Files
core/webapi/Merge directory.go
Akilan Selvacoumar ae5f1d2fd7 New features (#110)
* added upload status

* added changes for progress bar with more logs and bug fixes, Documentation yet to be added

* huge changes that need more doucmenting

* added possibility to get profile using NodeID

* added fix profile listing user profile information

* removed profile image from the explore reult struct

* saving current changes

* added filter to search based on NodeID

* Monday bug fixing

* updates to the profile

* changes for tracing the blockchain profile image not shown

* added condition to ensure TAG is not sent and removed debug prints

* updated webapi docs
2023-06-28 00:38:17 +01:00

136 lines
4.5 KiB
Go

package webapi
import (
"bytes"
"fmt"
"github.com/PeernetOfficial/core/blockchain"
"net/http"
"strconv"
)
// SearchResultMergedDirectory contains results for the merged directory.
type SearchResultMergedDirectory 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 []apiFile `json:"files"` // List of files found
Statistic interface{} `json:"statistic"` // Statistics of all results (independent from applied filters), if requested. Only set if files are returned (= if statistics changed). See SearchStatisticData.
}
/*
apiMergeDirectory Shows the recent files of peers that shared
the same file as the one provided in the GET request.
Currently searches through Memory for Nodes currently
identified in the network and then checks if the files
they shared match with the hash that is provided
in the search parameter and the queries the recent
file that node shared and then returns that result
back.
Request: GET /merge/directory with JSON structure apiMergeDirectory
Response: 200 with JSON structure SearchResultMergedDirectory
400 if invalid input
*/
func (api *WebapiInstance) apiMergeDirectory(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
offset, _ := strconv.Atoi(r.Form.Get("offset"))
limit, err := strconv.Atoi(r.Form.Get("limit"))
if err != nil {
limit = 100
}
// ID fields for results for a specific node ID.
//NodeId, _ := DecodeBlake3Hash(r.Form.Get("node"))
hash, _ := DecodeBlake3Hash(r.Form.Get("hash"))
fileType, err := strconv.Atoi(r.Form.Get("type"))
if err != nil {
fileType = -1
}
result := api.ExploreFileSharedByNodeThatSharedSimilarFile(fileType, limit, offset, hash, true)
EncodeJSON(api.Backend, w, r, result)
}
// ExploreFileSharedByNodeThatSharedSimilarFile lists files shared by a nodes which share the same file as a common point
// Currently this is a greedy search and requires work for optimization
func (api *WebapiInstance) ExploreFileSharedByNodeThatSharedSimilarFile(fileType int, limit, offset int, hash []byte, nodeIDState bool) *SearchResultMergedDirectory {
// lookup all NodeID blockchains which have the similar hash
// do a search to get all the node IDs sharing the particular file
var NodeIDs [][]byte
NodeIDs, _ = api.Backend.SearchIndex.SearchNodeIDBasedOnHash(hash)
// Does a greedy search to find node serving similar files
api.GreedySearchMergeDirection(&NodeIDs, fileType, hash)
var result SearchResultMergedDirectory
for i := range NodeIDs {
resultFiles := api.queryRecentShared(api.Backend, fileType, uint64(limit*20/100), uint64(offset), uint64(limit), NodeIDs[i], nodeIDState)
// loop over results
for n := range resultFiles {
ApiFile := blockRecordFileToAPI(resultFiles[n])
if ApiFile.NodeID == nil {
continue
}
result.Files = append(result.Files, ApiFile)
}
}
result.Status = 1 // No more results to expect
return &result
}
// GreedySearchMergeDirection This function is implemented since the local index tables do not
// always consist of the required hashes of the NodeIDs.
func (api *WebapiInstance) GreedySearchMergeDirection(nodeID *[][]byte, fileType int, hash []byte) {
// get all NodeIDs
peerList := api.Backend.PeerlistGet()
// search with AllNodes which have a match of the NodeID.
for _, peer := range peerList {
if peer.BlockchainHeight == 0 {
continue
}
var filesFromPeer uint64
// decode blocks from top down
for blockN := peer.BlockchainHeight - 1; blockN > 0; blockN-- {
blockDecoded, _, found, _ := api.Backend.ReadBlock(peer.PublicKey, peer.BlockchainVersion, blockN)
if !found {
continue
}
for _, record := range blockDecoded.RecordsDecoded {
if file, ok := record.(blockchain.BlockRecordFile); ok && isFileTypeMatchBlock(&file, fileType) {
// 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))
}
//file.Username = Name
// if both the hashes match
if bytes.Equal(file.Hash, hash) {
// set the Tags needed for the filter parameter
//tags = file.Tags
// found a new file! append.
filesFromPeer++
*nodeID = append(*nodeID, file.NodeID)
}
}
}
}
}
}