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  }