mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-23 05:07:51 +01:00
New Search Job code. Supports filtering and sorting. Renaming apiBlockRecordFile -> apiFile. Added filters and sort parameters to /search/result.
Improved API documentation. Added documentation about search filters and sort parameter.
This commit is contained in:
@@ -18,24 +18,35 @@ package webapi
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// SearchRequest is the information from the end-user for the search.
|
||||
// SearchRequest is the information from the end-user for the search. Filters and sort order may be applied when starting the search, or at runtime when getting the results.
|
||||
type SearchRequest struct {
|
||||
Term string `json:"term"` // Search term.
|
||||
Timeout int `json:"timeout"` // Timeout in seconds. 0 means default. This is the entire time the search may take. Found results are still available after this timeout.
|
||||
MaxResults int `json:"maxresults"` // Total number of max results. 0 means default.
|
||||
DateFrom string `json:"datefrom"` // Date from, both from/to are required if set.
|
||||
DateTo string `json:"dateto"` // Date to, both from/to are required if set.
|
||||
Sort int `json:"sort"` // Sort order: 0 = No sorting, 1 = Relevance ASC, 2 = Relevance DESC (this should be default), 3 = Date ASC, 4 = Date DESC
|
||||
DateFrom string `json:"datefrom"` // Date from, both from/to are required if set. Format "2006-01-02 15:04:05".
|
||||
DateTo string `json:"dateto"` // Date to, both from/to are required if set. Format "2006-01-02 15:04:05".
|
||||
Sort int `json:"sort"` // See SortX.
|
||||
TerminateID []uuid.UUID `json:"terminate"` // Optional: Previous search IDs to terminate. This is if the user makes a new search from the same tab. Same as first calling /search/terminate.
|
||||
TypeFilter int `json:"typefilter"` // 0 = No filters used, 1 = Use file type filter, 2 = Use file format filter.
|
||||
FileType int `json:"filetype"` // File type such as binary, text document etc. See core.TypeX.
|
||||
FileFormat int `json:"fileformat"` // File format such as PDF, Word, Ebook, etc. See core.FormatX.
|
||||
FileType int `json:"filetype"` // File type such as binary, text document etc. See core.TypeX. -1 = not used.
|
||||
FileFormat int `json:"fileformat"` // File format such as PDF, Word, Ebook, etc. See core.FormatX. -1 = not used.
|
||||
}
|
||||
|
||||
// Sort orders
|
||||
const (
|
||||
SortNone = 0 // No sorting. Results are returned as they come in.
|
||||
SortRelevanceAsc = 1 // Least relevant results first.
|
||||
SortRelevanceDec = 2 // Most relevant results first.
|
||||
SortDateAsc = 3 // Oldest first.
|
||||
SortDateDesc = 4 // Newest first.
|
||||
SortNameAsc = 5 // File name ascending. The folder name is not used for sorting.
|
||||
SortNameDesc = 6 // File name descending. The folder name is not used for sorting.
|
||||
)
|
||||
|
||||
// SearchRequestResponse is the result to the initial search request
|
||||
type SearchRequestResponse struct {
|
||||
ID uuid.UUID `json:"id"` // ID of the search job. This is used to get the results.
|
||||
@@ -44,12 +55,15 @@ type SearchRequestResponse struct {
|
||||
|
||||
// SearchResult contains the search results.
|
||||
type SearchResult struct {
|
||||
Status int `json:"status"` // Status: 0 = Success with results, 1 = No more results available, 2 = Search ID not found, 3 = No results yet available keep trying
|
||||
Files []apiBlockRecordFile `json:"files"` // List of files found
|
||||
Status int `json:"status"` // Status: 0 = Success with results, 1 = No more results available, 2 = Search ID not found, 3 = No results yet available keep trying
|
||||
Files []apiFile `json:"files"` // List of files found
|
||||
}
|
||||
|
||||
const apiDateFormat = "2006-01-02 15:04:05"
|
||||
|
||||
/*
|
||||
apiSearch submits a search request
|
||||
|
||||
Request: POST /search with JSON SearchRequest
|
||||
Result: 200 on success with JSON SearchRequestResponse
|
||||
400 on invalid JSON
|
||||
@@ -83,7 +97,15 @@ func apiSearch(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
/*
|
||||
apiSearchResult returns results. The default limit is 100.
|
||||
If reset is set, all results will be filtered and sorted according to the settings. This means that the new first result will be returned again and internal result offset is set to 0.
|
||||
|
||||
Request: GET /search/result?id=[UUID]&limit=[max records]
|
||||
Optional parameters:
|
||||
&reset=[0|1] to reset the filters or sort orders with any of the below parameters (all required):
|
||||
&filetype=[File Type]
|
||||
&fileformat=[File Format]
|
||||
&from=[Date From]&to=[Date To]
|
||||
&sort=[sort order]
|
||||
Result: 200 with JSON structure SearchResult. Check the field status.
|
||||
*/
|
||||
func apiSearchResult(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -98,6 +120,14 @@ func apiSearchResult(w http.ResponseWriter, r *http.Request) {
|
||||
limit = 100
|
||||
}
|
||||
|
||||
// filters and sort parameter
|
||||
filterReset, _ := strconv.ParseBool(r.Form.Get("reset"))
|
||||
fileType, _ := strconv.Atoi(r.Form.Get("filetype"))
|
||||
fileFormat, _ := strconv.Atoi(r.Form.Get("fileformat"))
|
||||
dateFrom, _ := time.Parse(apiDateFormat, r.Form.Get("from"))
|
||||
dateTo, _ := time.Parse(apiDateFormat, r.Form.Get("to"))
|
||||
sort, _ := strconv.Atoi(r.Form.Get("sort"))
|
||||
|
||||
// find the job ID
|
||||
job := JobLookup(jobID)
|
||||
if job == nil {
|
||||
@@ -105,21 +135,27 @@ func apiSearchResult(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// apply runtime filters, if any
|
||||
if filterReset {
|
||||
job.RuntimeFilter(sort, fileType, fileFormat, dateFrom, dateTo)
|
||||
}
|
||||
|
||||
// query all results
|
||||
resultFiles := job.ReturnNext(limit)
|
||||
|
||||
var result SearchResult
|
||||
result.Files = []apiBlockRecordFile{}
|
||||
result.Files = []apiFile{}
|
||||
|
||||
// loop over results
|
||||
for n := range resultFiles {
|
||||
result.Files = append(result.Files, blockRecordFileToAPI(*resultFiles[n]))
|
||||
result.Files = append(result.Files, *resultFiles[n])
|
||||
}
|
||||
|
||||
if len(result.Files) == 0 {
|
||||
result.Status = 3 // No results yet available keep trying
|
||||
}
|
||||
|
||||
//if !job.IsSearchResults() { // if no fresh results to be expected
|
||||
result.Status = 1 // No more results to expect
|
||||
|
||||
EncodeJSON(w, r, result)
|
||||
@@ -127,6 +163,7 @@ func apiSearchResult(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
/*
|
||||
apiSearchResultStream runs a websocket to return results
|
||||
|
||||
Request: GET /search/result/ws?id=[UUID]&limit=[optional max records]
|
||||
Result: If successful, upgrades to a web-socket and sends JSON structure SearchResult messages
|
||||
Limit is optional. Not used if ommitted or 0.
|
||||
@@ -161,7 +198,7 @@ func apiSearchResultStream(w http.ResponseWriter, r *http.Request) {
|
||||
// query all results
|
||||
|
||||
var result SearchResult
|
||||
result.Files = []apiBlockRecordFile{}
|
||||
result.Files = []apiFile{}
|
||||
|
||||
// loop over the results
|
||||
|
||||
@@ -186,6 +223,7 @@ func apiSearchResultStream(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
/*
|
||||
apiSearchTerminate terminates a search
|
||||
|
||||
Request: GET /search/terminate?id=[UUID]
|
||||
Response: 204 Empty
|
||||
400 Invalid input
|
||||
@@ -235,7 +273,7 @@ func apiExplore(w http.ResponseWriter, r *http.Request) {
|
||||
resultFiles := queryRecentShared(fileType, limit)
|
||||
|
||||
var result SearchResult
|
||||
result.Files = []apiBlockRecordFile{}
|
||||
result.Files = []apiFile{}
|
||||
|
||||
// loop over results
|
||||
for n := range resultFiles {
|
||||
@@ -250,3 +288,19 @@ func apiExplore(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
EncodeJSON(w, r, result)
|
||||
}
|
||||
|
||||
func (input *SearchRequest) Parse() (Timeout time.Duration, FileType, FileFormat int, DateFrom, DateTo time.Time) {
|
||||
if input.Timeout == 0 {
|
||||
Timeout = time.Second * 20 // default timeout: 20 seconds
|
||||
} else {
|
||||
Timeout = time.Duration(input.Timeout) * time.Second
|
||||
}
|
||||
|
||||
FileType = input.FileType
|
||||
FileFormat = input.FileFormat
|
||||
|
||||
DateFrom, _ = time.Parse(apiDateFormat, input.DateFrom)
|
||||
DateTo, _ = time.Parse(apiDateFormat, input.DateTo)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user