package main import ( "encoding/json" "fmt" "log" "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) { 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 } 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 }