wiki/search.go
2020-07-01 16:40:10 +02:00

89 lines
1.9 KiB
Go

package main
import (
"encoding/json"
"net/http"
"strings"
"github.com/blevesearch/bleve"
"github.com/blevesearch/bleve/mapping"
)
// TODO: http handler
// TODO: index all pages on start
// TODO: reindex all command
// TODO: search(query) command
type searchHandler struct {
documents PagesRepository
indexMapping mapping.IndexMapping
searchIndex bleve.Index
}
type nameLine struct {
Name string `json:"name"`
Line string `json:"line"`
}
type searchObject struct {
Title string `json:"title"`
Blocks []string `json:"blocks"`
Refs []nameLine `json:"refs"`
Meta map[string]string `json:"meta"`
}
func NewSearchHandler(searchIndex bleve.Index) (http.Handler, error) {
return &searchHandler{
searchIndex: searchIndex,
}, nil
}
func (s *searchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
q := bleve.NewQueryStringQuery(r.URL.Query().Get("q"))
sr := bleve.NewSearchRequest(q)
results, err := s.searchIndex.Search(sr)
if err != nil {
http.Error(w, err.Error(), 500)
}
enc := json.NewEncoder(w)
enc.SetIndent("", " ")
err = enc.Encode(&results)
if err != nil {
http.Error(w, err.Error(), 500)
}
}
func createSearchObject(page Page) (searchObject, error) {
so := searchObject{}
so.Title = page.Title
so.Meta = make(map[string]string)
type simpleListItem struct {
Text string
}
var listItems []simpleListItem
if err := json.NewDecoder(strings.NewReader(page.Content)).Decode(&listItems); err != nil {
so.Blocks = append(so.Blocks, page.Content)
} else {
for _, li := range listItems {
meta := strings.SplitN(li.Text, "::", 2)
if len(meta) == 2 {
so.Meta[strings.ToLower(strings.TrimSpace(meta[0]))] = strings.ToLower(strings.TrimSpace(meta[1]))
}
so.Blocks = append(so.Blocks, li.Text)
}
}
for k, refs := range page.Refs {
for _, ref := range refs {
so.Refs = append(so.Refs, nameLine{
k,
ref.Line,
})
}
}
return so, nil
}