2020-06-30 20:56:12 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2020-07-04 13:07:32 +00:00
|
|
|
"fmt"
|
|
|
|
"log"
|
2020-06-30 20:56:12 +00:00
|
|
|
"net/http"
|
2020-07-01 14:40:10 +00:00
|
|
|
"strings"
|
2020-06-30 20:56:12 +00:00
|
|
|
|
|
|
|
"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
|
|
|
|
}
|
|
|
|
|
2020-07-01 14:40:10 +00:00
|
|
|
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"`
|
|
|
|
}
|
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
func NewSearchHandler(searchIndex bleve.Index) (http.Handler, error) {
|
|
|
|
return &searchHandler{
|
2020-07-01 14:40:10 +00:00
|
|
|
searchIndex: searchIndex,
|
2020-06-30 20:56:12 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *searchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
2020-07-04 13:07:32 +00:00
|
|
|
defer r.Body.Close()
|
|
|
|
|
|
|
|
sess, err := NewSession(w, r)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(w, err.Error(), 500)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
if err := sess.Flush(); err != nil {
|
|
|
|
log.Println(err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
if !sess.LoggedIn {
|
|
|
|
fmt.Fprint(w, "{}")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-30 20:56:12 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
2020-07-01 14:40:10 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|