From 9dcfcb6b55c494911e4b6534e0a0178849258be4 Mon Sep 17 00:00:00 2001 From: Akilan Date: Sat, 1 Jul 2023 13:02:49 +0100 Subject: [PATCH] added support to filter files in the search result based on the NodeID provided --- webapi/Search Dispatch.go | 117 +++++++++++++++++++------------------- webapi/Search Job.go | 5 ++ webapi/Search.go | 20 +++++-- webapi/readme.md | 1 + 4 files changed, 78 insertions(+), 65 deletions(-) diff --git a/webapi/Search Dispatch.go b/webapi/Search Dispatch.go index 65bc26e..90126e2 100644 --- a/webapi/Search Dispatch.go +++ b/webapi/Search Dispatch.go @@ -7,86 +7,83 @@ Author: Peter Kleissner package webapi import ( - "bytes" - "fmt" - "time" + "bytes" + "fmt" + "time" - "github.com/PeernetOfficial/core/blockchain" + "github.com/PeernetOfficial/core/blockchain" ) func (api *WebapiInstance) dispatchSearch(input SearchRequest, NodeID []byte) (job *SearchJob) { - Timeout := input.Parse() - Filter := input.ToSearchFilter() + Timeout := input.Parse() + Filter := input.ToSearchFilter() - // create the search job - job = api.CreateSearchJob(Timeout, input.MaxResults, Filter) + // create the search job + job = api.CreateSearchJob(Timeout, input.MaxResults, Filter) - // todo: create actual search clients! - job.Status = SearchStatusLive + // todo: create actual search clients! + job.Status = SearchStatusLive - go job.localSearch(api, input.Term, NodeID) + go job.localSearch(api, input.Term) - api.RemoveJobDefer(job, job.timeout+time.Minute*10) + api.RemoveJobDefer(job, job.timeout+time.Minute*10) - return job + return job } -func (job *SearchJob) localSearch(api *WebapiInstance, term string, NodeID []byte) { - if api.Backend.SearchIndex == nil { - job.Status = SearchStatusNoIndex - return - } +func (job *SearchJob) localSearch(api *WebapiInstance, term string) { + if api.Backend.SearchIndex == nil { + job.Status = SearchStatusNoIndex + return + } - results := api.Backend.SearchIndex.Search(term) + results := api.Backend.SearchIndex.Search(term) - job.ResultSync.Lock() + job.ResultSync.Lock() resultLoop: - for _, result := range results { + for _, result := range results { - file, _, found, err := api.Backend.ReadFile(result.PublicKey, result.BlockchainVersion, result.BlockNumber, result.FileID) - if err != nil || !found { - continue - } + file, _, found, err := api.Backend.ReadFile(result.PublicKey, result.BlockchainVersion, result.BlockNumber, result.FileID) + if err != nil || !found { + continue + } - // Deduplicate based on file hash from the same peer. - for n := range job.AllFiles { - if bytes.Equal(job.AllFiles[n].Hash, file.Hash) && bytes.Equal(job.AllFiles[n].NodeID, file.NodeID) { - continue resultLoop - } - } + // Deduplicate based on file hash from the same peer. + for n := range job.AllFiles { + if bytes.Equal(job.AllFiles[n].Hash, file.Hash) && bytes.Equal(job.AllFiles[n].NodeID, file.NodeID) { + continue resultLoop + } + } - // if the NodeID filter is provided - if bytes.Equal(file.NodeID, NodeID) || bytes.Equal(NodeID, nil) { - if bytes.Equal(file.NodeID, api.Backend.SelfNodeID()) { - // Indicates data from the current user. - file.Tags = append(file.Tags, blockchain.TagFromNumber(blockchain.TagSharedByCount, 1)) - } else if peer := api.Backend.NodelistLookup(file.NodeID); peer != nil { - // Get current active connections - if len(peer.GetConnections(true)) > 0 { - // add the tags 'Shared By Count' and 'Shared By GeoIP' - file.Tags = append(file.Tags, blockchain.TagFromNumber(blockchain.TagSharedByCount, 1)) - if latitude, longitude, valid := api.Peer2GeoIP(peer); valid { - sharedByGeoIP := fmt.Sprintf("%.4f", latitude) + "," + fmt.Sprintf("%.4f", longitude) - file.Tags = append(file.Tags, blockchain.TagFromText(blockchain.TagSharedByGeoIP, sharedByGeoIP)) - } - } - } - } + if bytes.Equal(file.NodeID, api.Backend.SelfNodeID()) { + // Indicates data from the current user. + file.Tags = append(file.Tags, blockchain.TagFromNumber(blockchain.TagSharedByCount, 1)) + } else if peer := api.Backend.NodelistLookup(file.NodeID); peer != nil { + // Get current active connections + if len(peer.GetConnections(true)) > 0 { + // add the tags 'Shared By Count' and 'Shared By GeoIP' + file.Tags = append(file.Tags, blockchain.TagFromNumber(blockchain.TagSharedByCount, 1)) + if latitude, longitude, valid := api.Peer2GeoIP(peer); valid { + sharedByGeoIP := fmt.Sprintf("%.4f", latitude) + "," + fmt.Sprintf("%.4f", longitude) + file.Tags = append(file.Tags, blockchain.TagFromText(blockchain.TagSharedByGeoIP, sharedByGeoIP)) + } + } + } - // new result - newFile := blockRecordFileToAPI(file, false) + // new result + newFile := blockRecordFileToAPI(file, false) - if newFile.NodeID != nil { - job.Files = append(job.Files, &newFile) - job.AllFiles = append(job.AllFiles, &newFile) - job.requireSort = true - job.statsAdd(&newFile) - } - } + if newFile.NodeID != nil { + job.Files = append(job.Files, &newFile) + job.AllFiles = append(job.AllFiles, &newFile) + job.requireSort = true + job.statsAdd(&newFile) + } + } - job.Status = SearchStatusTerminated + job.Status = SearchStatusTerminated - job.ResultSync.Unlock() - job.Terminate() + job.ResultSync.Unlock() + job.Terminate() } diff --git a/webapi/Search Job.go b/webapi/Search Job.go index 3d65c1c..4725271 100644 --- a/webapi/Search Job.go +++ b/webapi/Search Job.go @@ -7,6 +7,7 @@ Author: Peter Kleissner package webapi import ( + "bytes" "sort" "sync" "time" @@ -255,6 +256,10 @@ func (job *SearchJob) isFileFiltered(file *apiFile) bool { return false } + if job.filtersRuntime.NodeID != nil && !bytes.Equal(job.filtersRuntime.NodeID, file.NodeID) { + return false + } + return true } diff --git a/webapi/Search.go b/webapi/Search.go index 66ef662..aed20d4 100644 --- a/webapi/Search.go +++ b/webapi/Search.go @@ -160,9 +160,12 @@ func (api *WebapiInstance) apiSearchResult(w http.ResponseWriter, r *http.Reques sort, _ := strconv.Atoi(r.Form.Get("sort")) sizeMin, _ := strconv.Atoi(r.Form.Get("sizemin")) sizeMax, _ := strconv.Atoi(r.Form.Get("sizemax")) - //nodeID, _ := DecodeBlake3Hash(r.Form.Get("node")) + nodeID, valid := DecodeBlake3Hash(r.Form.Get("node")) + if !valid { + nodeID = nil + } - filter := inputToSearchFilter(sort, fileType, fileFormat, dateFrom, dateTo, sizeMin, sizeMax) + filter := inputToSearchFilter(sort, fileType, fileFormat, dateFrom, dateTo, sizeMin, sizeMax, nodeID) job.RuntimeFilter(filter) } @@ -433,11 +436,14 @@ func (input *SearchRequest) Parse() (Timeout time.Duration) { // ToSearchFilter converts the user input to a valid search filter func (input *SearchRequest) ToSearchFilter() (output SearchFilter) { - //hash, _ := DecodeBlake3Hash(input.NodeID) - return inputToSearchFilter(input.Sort, input.FileType, input.FileFormat, input.DateFrom, input.DateTo, input.SizeMin, input.SizeMax) + hash, valid := DecodeBlake3Hash(input.NodeID) + if !valid { + hash = nil + } + return inputToSearchFilter(input.Sort, input.FileType, input.FileFormat, input.DateFrom, input.DateTo, input.SizeMin, input.SizeMax, hash) } -func inputToSearchFilter(Sort, FileType, FileFormat int, DateFrom, DateTo string, SizeMin, SizeMax int) (output SearchFilter) { +func inputToSearchFilter(Sort, FileType, FileFormat int, DateFrom, DateTo string, SizeMin, SizeMax int, NodeID []byte) (output SearchFilter) { output.Sort = Sort output.FileType = FileType output.FileFormat = FileFormat @@ -452,5 +458,9 @@ func inputToSearchFilter(Sort, FileType, FileFormat int, DateFrom, DateTo string output.IsDates = true } + if NodeID != nil { + output.NodeID = NodeID + } + return } diff --git a/webapi/readme.md b/webapi/readme.md index a77d89a..6725174 100644 --- a/webapi/readme.md +++ b/webapi/readme.md @@ -635,6 +635,7 @@ These are the available sort options: | 8 | SortSizeDesc | File size descending. Largest files first. | | 9 | SortSharedByCountAsc | Shared by count ascending. Files that are shared by the least count of peers first. | | 10 | SortSharedByCountDesc | Shared by count descending. Files that are shared by the most count of peers first. | +| 11 | Node | Filter files based on the NodeID provided | The following filters are supported: