github.com/bosssauce/ponzu@v0.11.1-0.20200102001432-9bc41b703131/system/api/search.go (about) 1 package api 2 3 import ( 4 "encoding/json" 5 "log" 6 "net/http" 7 "net/url" 8 "strconv" 9 10 "github.com/ponzu-cms/ponzu/system/db" 11 "github.com/ponzu-cms/ponzu/system/item" 12 "github.com/ponzu-cms/ponzu/system/search" 13 ) 14 15 func searchContentHandler(res http.ResponseWriter, req *http.Request) { 16 qs := req.URL.Query() 17 t := qs.Get("type") 18 // type must be set, future version may compile multi-type result set 19 if t == "" { 20 res.WriteHeader(http.StatusBadRequest) 21 return 22 } 23 24 it, ok := item.Types[t] 25 if !ok { 26 res.WriteHeader(http.StatusBadRequest) 27 return 28 } 29 30 if hide(res, req, it()) { 31 return 32 } 33 34 q, err := url.QueryUnescape(qs.Get("q")) 35 if err != nil { 36 res.WriteHeader(http.StatusInternalServerError) 37 return 38 } 39 40 // q must be set 41 if q == "" { 42 res.WriteHeader(http.StatusBadRequest) 43 return 44 } 45 46 count, err := strconv.Atoi(qs.Get("count")) // int: determines number of posts to return (10 default, -1 is all) 47 if err != nil { 48 if qs.Get("count") == "" { 49 count = 10 50 } else { 51 res.WriteHeader(http.StatusInternalServerError) 52 return 53 } 54 } 55 56 offset, err := strconv.Atoi(qs.Get("offset")) // int: multiplier of count for pagination (0 default) 57 if err != nil { 58 if qs.Get("offset") == "" { 59 offset = 0 60 } else { 61 res.WriteHeader(http.StatusInternalServerError) 62 return 63 } 64 } 65 66 // execute search for query provided, if no index for type send 404 67 matches, err := search.TypeQuery(t, q, count, offset) 68 if err == search.ErrNoIndex { 69 res.WriteHeader(http.StatusNotFound) 70 return 71 } 72 if err != nil { 73 log.Println("[search] Error:", err) 74 res.WriteHeader(http.StatusInternalServerError) 75 return 76 } 77 78 // respond with json formatted results 79 bb, err := db.ContentMulti(matches) 80 if err != nil { 81 log.Println("[search] Error:", err) 82 res.WriteHeader(http.StatusInternalServerError) 83 return 84 } 85 86 // if we have matches, push the first as its matched by relevance 87 if len(bb) > 0 { 88 push(res, req, it(), bb[0]) 89 } 90 91 var result = []json.RawMessage{} 92 for i := range bb { 93 result = append(result, bb[i]) 94 } 95 96 j, err := fmtJSON(result...) 97 if err != nil { 98 res.WriteHeader(http.StatusInternalServerError) 99 return 100 } 101 102 j, err = omit(res, req, it(), j) 103 if err != nil { 104 res.WriteHeader(http.StatusInternalServerError) 105 return 106 } 107 108 sendData(res, req, j) 109 }