package models import ( "encoding/json" "fmt" "io" "log" "net/http" "strings" "github.com/google/uuid" "github.com/tidwall/gjson" ) var ( Store SearchStorage ) type SearchStorage struct { RedisUrl string `json:"redis_url,omitempty"` RedisPassword string `json:"redis_password,omitempty"` ZincUrl string `json:"zinc_url,omitempty"` ZincLogin string `json:"zinc_login,omitempty"` ZincPassword string `json:"zinc_password,omitempty"` } type SearchTarget struct { PeerId string ApiUrl string } func init() { } func StartSearch(query string) (searchId string, err error) { searchId = uuid.New().String() doSearch(query, searchId) return searchId, nil } func GetProgress(searchId string) (err error) { return nil } func GetResults(searchId string) { } func doSearch(query string, searchId string) error { // select peers ids, err := getPeersIds(query) if err != nil { return nil } // loop and search through peers for _, id := range ids { doSinglePeerSearch(id, query, searchId) } return nil } func getPeersIds(query string) ([]SearchTarget, error) { var ws HttpQuery var ids []SearchTarget ws.Init(GetConfig().DiscoveryUrl) body, err := ws.Get("peer/find/" + query) if err != nil { return nil, err } result := gjson.Parse(string(body)) result.ForEach(func(key, value gjson.Result) bool { st := SearchTarget{value.Get("peer_id").Str, value.Get("api_url").Str} ids = append(ids, st) return true // keep iterating }) return ids, nil } func doSinglePeerSearch(peerId SearchTarget, query string, searchId string) error { // start search var ws HttpQuery ws.Init(peerId.ApiUrl) body, err := ws.Get("/search/byWord?word=" + query) if err != nil { return err } println(string(body)) // get results // split types // update percent in Redis // feed results to Zinc bulk := map[string]interface{}{"index": "search_" + searchId, "records": indexedPeers} raw, err := json.Marshal(bulk) if err != nil { return err } req, err := http.NewRequest("POST", GetConfig().ZincUrl+"/api/_bulkv2", strings.NewReader(string(raw))) if err != nil { return err } req.SetBasicAuth(GetConfig().ZincLogin, GetConfig().ZincPassword) req.Header.Set("Content-Type", "application/json") req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36") resp, err := http.DefaultClient.Do(req) if err != nil { return err } defer resp.Body.Close() log.Println(resp.StatusCode) body, err := io.ReadAll(resp.Body) if err != nil { return err } fmt.Println(string(body)) // query Zinc // remerge results in types // provide intermediary results // store result in Redis return nil }