added support to filter files in the search result based on the NodeID provided

This commit is contained in:
2023-07-01 13:02:49 +01:00
parent 187621a29e
commit 9dcfcb6b55
4 changed files with 78 additions and 65 deletions

View File

@@ -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()
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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: