Skip to content
Snippets Groups Projects
Commit 7d214247 authored by ale's avatar ale
Browse files

add a limit parameter to the search API

parent 24ac7c3e
Branches
No related tags found
No related merge requests found
......@@ -10,6 +10,7 @@ import (
"log"
"net/http"
"net/url"
"strconv"
"strings"
"sync"
......@@ -23,6 +24,7 @@ import (
var (
configFile = flag.String("djrandom-config", util.ExpandTilde("~/.djrandom.conf"), "Config file location")
maxResults = flag.Int("max-search-results", 200, "maximum number of search results to return")
serverUrl = config.String("djrandom-server", "https://djrandom.incal.net", "Server URL")
authKeyId = config.String("auth_key", "", "API authentication key")
......@@ -182,6 +184,7 @@ func (d *DJRandomDatabase) doQuery(query string) ([]mpd.Song, error) {
values := url.Values{}
values.Add("q", query)
values.Add("limit", strconv.Itoa(*maxResults))
req, err := d.client.NewRequest("POST", "/api/search", strings.NewReader(values.Encode()))
if err != nil {
return nil, err
......
......@@ -2,6 +2,7 @@ package frontend
import (
"encoding/json"
"errors"
// "fmt"
"io"
"io/ioutil"
......@@ -182,49 +183,67 @@ func CheckFingerprints(w http.ResponseWriter, r *djRequest) {
sendJsonResponse(w, &fpResp)
}
// SearchIds runs a search query and returns only song IDs.
func SearchIds(w http.ResponseWriter, r *djRequest) {
// Assemble the search query.
func doSearch(r *djRequest) ([]api.SongID, error) {
// Extract query parameters from the request.
query := r.Request.FormValue("q")
if query == "" {
http.Error(w, "Empty search query", http.StatusBadRequest)
return
return nil, errors.New("empty search query")
}
var limit int
limitstr := r.Request.FormValue("limit")
if limitstr != "" {
var err error
limit, err = strconv.Atoi(limitstr)
if err != nil {
return nil, err
}
}
// Run search.
var resp api.SearchIdsResponse
for item, _ := range r.Ctx.Index.Search(query) {
resp.Results = append(resp.Results, item)
// Run search, only return 'limit' results (if 0, return all
// of them). Try to use the least memory possible.
results := r.Ctx.Index.Search(query)
if limit == 0 {
limit = len(results)
}
sendJsonResponse(w, &resp)
songIds := make([]api.SongID, 0, limit)
i := 0
for id := range results {
songIds = append(songIds, id)
i++
if i > limit {
break
}
}
return songIds, nil
}
// Search returns full search results.
func Search(w http.ResponseWriter, r *djRequest) {
// Assemble the search query.
query := r.Request.FormValue("q")
if query == "" {
http.Error(w, "Empty search query", http.StatusBadRequest)
// SearchIds runs a search query and returns only song IDs.
func SearchIds(w http.ResponseWriter, r *djRequest) {
ids, err := doSearch(r)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
sendJsonResponse(w, &api.SearchIdsResponse{Results: ids})
}
// Run search (and create a list).
results := r.Ctx.Index.Search(query)
songIds := make([]api.SongID, 0, len(results))
for id, _ := range results {
songIds = append(songIds, id)
// Search returns full search results.
func Search(w http.ResponseWriter, r *djRequest) {
ids, err := doSearch(r)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
songs, err := db_client.ParallelFetchSongs(r.Ctx.Db, songIds)
songs, err := db_client.ParallelFetchSongs(r.Ctx.Db, ids)
if err != nil {
log.Printf("Search(): %s", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
resp := api.SearchResponse{
Results: songs,
}
sendJsonResponse(w, &resp)
sendJsonResponse(w, &api.SearchResponse{Results: songs})
}
// ArtistAutocomplete returns artist autocompletion results.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment