mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-16 18:37:51 +01:00
added base changes for the merge cirectory api
This commit is contained in:
24
search/Search NodeIDs Based on Hash.go
Normal file
24
search/Search NodeIDs Based on Hash.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/PeernetOfficial/core/protocol"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SearchNodeIDBasedOnHash Provides a list of NodeIDs
|
||||||
|
// based on the hash provided
|
||||||
|
// This is used to find out which nodes are hosting
|
||||||
|
// which files based on the hash provided
|
||||||
|
func (index *SearchIndexStore) SearchNodeIDBasedOnHash(hash []byte) (NodeIDs [][]byte, err error) {
|
||||||
|
var resultMap map[uuid.UUID]*SearchIndexRecord
|
||||||
|
err = index.LookupHash(SearchSelector{Hash: hash}, resultMap)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range resultMap {
|
||||||
|
NodeIDs = append(NodeIDs, protocol.PublicKey2NodeID(resultMap[i].PublicKey))
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -81,6 +81,7 @@ func Start(Backend *core.Backend, ListenAddresses []string, UseSSL bool, Certifi
|
|||||||
api.Router.HandleFunc("/blockchain/file/delete", api.apiBlockchainFileDelete).Methods("POST")
|
api.Router.HandleFunc("/blockchain/file/delete", api.apiBlockchainFileDelete).Methods("POST")
|
||||||
api.Router.HandleFunc("/blockchain/file/update", api.apiBlockchainFileUpdate).Methods("POST")
|
api.Router.HandleFunc("/blockchain/file/update", api.apiBlockchainFileUpdate).Methods("POST")
|
||||||
api.Router.HandleFunc("/blockchain/view", api.apiExploreNodeID).Methods("GET")
|
api.Router.HandleFunc("/blockchain/view", api.apiExploreNodeID).Methods("GET")
|
||||||
|
api.Router.HandleFunc("/merge/directory", api.apiMergeDirectory).Methods("GET")
|
||||||
api.Router.HandleFunc("/profile/list", api.apiProfileList).Methods("GET")
|
api.Router.HandleFunc("/profile/list", api.apiProfileList).Methods("GET")
|
||||||
api.Router.HandleFunc("/profile/read", api.apiProfileRead).Methods("GET")
|
api.Router.HandleFunc("/profile/read", api.apiProfileRead).Methods("GET")
|
||||||
api.Router.HandleFunc("/profile/write", api.apiProfileWrite).Methods("POST")
|
api.Router.HandleFunc("/profile/write", api.apiProfileWrite).Methods("POST")
|
||||||
|
|||||||
@@ -7,18 +7,17 @@ Author: Peter Kleissner
|
|||||||
package webapi
|
package webapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/PeernetOfficial/core/blockchain"
|
"github.com/PeernetOfficial/core/blockchain"
|
||||||
)
|
)
|
||||||
|
|
||||||
type apiBlockchainHeader struct {
|
type apiBlockchainHeader struct {
|
||||||
PeerID string `json:"peerid"` // Peer ID hex encoded.
|
PeerID string `json:"peerid"` // Peer ID hex encoded.
|
||||||
Version uint64 `json:"version"` // Current version number of the blockchain.
|
Version uint64 `json:"version"` // Current version number of the blockchain.
|
||||||
Height uint64 `json:"height"` // Height of the blockchain (number of blocks). If 0, no data exists.
|
Height uint64 `json:"height"` // Height of the blockchain (number of blocks). If 0, no data exists.
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -28,25 +27,25 @@ Request: GET /blockchain/header
|
|||||||
Result: 200 with JSON structure apiResponsePeerSelf
|
Result: 200 with JSON structure apiResponsePeerSelf
|
||||||
*/
|
*/
|
||||||
func (api *WebapiInstance) apiBlockchainHeaderFunc(w http.ResponseWriter, r *http.Request) {
|
func (api *WebapiInstance) apiBlockchainHeaderFunc(w http.ResponseWriter, r *http.Request) {
|
||||||
publicKey, height, version := api.Backend.UserBlockchain.Header()
|
publicKey, height, version := api.Backend.UserBlockchain.Header()
|
||||||
|
|
||||||
EncodeJSON(api.Backend, w, r, apiBlockchainHeader{Version: version, Height: height, PeerID: hex.EncodeToString(publicKey.SerializeCompressed())})
|
EncodeJSON(api.Backend, w, r, apiBlockchainHeader{Version: version, Height: height, PeerID: hex.EncodeToString(publicKey.SerializeCompressed())})
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiBlockRecordRaw struct {
|
type apiBlockRecordRaw struct {
|
||||||
Type uint8 `json:"type"` // Record Type. See core.RecordTypeX.
|
Type uint8 `json:"type"` // Record Type. See core.RecordTypeX.
|
||||||
Data []byte `json:"data"` // Data according to the type.
|
Data []byte `json:"data"` // Data according to the type.
|
||||||
}
|
}
|
||||||
|
|
||||||
// apiBlockchainBlockRaw contains a raw block of the blockchain via API
|
// apiBlockchainBlockRaw contains a raw block of the blockchain via API
|
||||||
type apiBlockchainBlockRaw struct {
|
type apiBlockchainBlockRaw struct {
|
||||||
Records []apiBlockRecordRaw `json:"records"` // Block records in encoded raw format.
|
Records []apiBlockRecordRaw `json:"records"` // Block records in encoded raw format.
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiBlockchainBlockStatus struct {
|
type apiBlockchainBlockStatus struct {
|
||||||
Status int `json:"status"` // See blockchain.StatusX.
|
Status int `json:"status"` // See blockchain.StatusX.
|
||||||
Height uint64 `json:"height"` // Height of the blockchain (number of blocks).
|
Height uint64 `json:"height"` // Height of the blockchain (number of blocks).
|
||||||
Version uint64 `json:"version"` // Version of the blockchain.
|
Version uint64 `json:"version"` // Version of the blockchain.
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -57,30 +56,30 @@ Request: POST /blockchain/append with JSON structure apiBlockchainBlockRaw
|
|||||||
Response: 200 with JSON structure apiBlockchainBlockStatus
|
Response: 200 with JSON structure apiBlockchainBlockStatus
|
||||||
*/
|
*/
|
||||||
func (api *WebapiInstance) apiBlockchainAppend(w http.ResponseWriter, r *http.Request) {
|
func (api *WebapiInstance) apiBlockchainAppend(w http.ResponseWriter, r *http.Request) {
|
||||||
var input apiBlockchainBlockRaw
|
var input apiBlockchainBlockRaw
|
||||||
if err := DecodeJSON(w, r, &input); err != nil {
|
if err := DecodeJSON(w, r, &input); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var records []blockchain.BlockRecordRaw
|
var records []blockchain.BlockRecordRaw
|
||||||
|
|
||||||
for _, record := range input.Records {
|
for _, record := range input.Records {
|
||||||
records = append(records, blockchain.BlockRecordRaw{Type: record.Type, Data: record.Data})
|
records = append(records, blockchain.BlockRecordRaw{Type: record.Type, Data: record.Data})
|
||||||
}
|
}
|
||||||
|
|
||||||
newHeight, newVersion, status := api.Backend.UserBlockchain.Append(records)
|
newHeight, newVersion, status := api.Backend.UserBlockchain.Append(records)
|
||||||
|
|
||||||
EncodeJSON(api.Backend, w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion})
|
EncodeJSON(api.Backend, w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion})
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiBlockchainBlock struct {
|
type apiBlockchainBlock struct {
|
||||||
Status int `json:"status"` // See blockchain.StatusX.
|
Status int `json:"status"` // See blockchain.StatusX.
|
||||||
PeerID string `json:"peerid"` // Peer ID hex encoded.
|
PeerID string `json:"peerid"` // Peer ID hex encoded.
|
||||||
LastBlockHash []byte `json:"lastblockhash"` // Hash of the last block. Blake3.
|
LastBlockHash []byte `json:"lastblockhash"` // Hash of the last block. Blake3.
|
||||||
BlockchainVersion uint64 `json:"blockchainversion"` // Blockchain version
|
BlockchainVersion uint64 `json:"blockchainversion"` // Blockchain version
|
||||||
Number uint64 `json:"blocknumber"` // Block number
|
Number uint64 `json:"blocknumber"` // Block number
|
||||||
RecordsRaw []apiBlockRecordRaw `json:"recordsraw"` // Records raw. Successfully decoded records are parsed into the below fields.
|
RecordsRaw []apiBlockRecordRaw `json:"recordsraw"` // Records raw. Successfully decoded records are parsed into the below fields.
|
||||||
RecordsDecoded []interface{} `json:"recordsdecoded"` // Records decoded. The encoding for each record depends on its type.
|
RecordsDecoded []interface{} `json:"recordsdecoded"` // Records decoded. The encoding for each record depends on its type.
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -90,63 +89,36 @@ Request: GET /blockchain/read?block=[number]
|
|||||||
Result: 200 with JSON structure apiBlockchainBlock
|
Result: 200 with JSON structure apiBlockchainBlock
|
||||||
*/
|
*/
|
||||||
func (api *WebapiInstance) apiBlockchainRead(w http.ResponseWriter, r *http.Request) {
|
func (api *WebapiInstance) apiBlockchainRead(w http.ResponseWriter, r *http.Request) {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
blockN, err := strconv.Atoi(r.Form.Get("block"))
|
blockN, err := strconv.Atoi(r.Form.Get("block"))
|
||||||
if err != nil || blockN < 0 {
|
if err != nil || blockN < 0 {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
http.Error(w, "", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
block, status, _ := api.Backend.UserBlockchain.Read(uint64(blockN))
|
block, status, _ := api.Backend.UserBlockchain.Read(uint64(blockN))
|
||||||
result := apiBlockchainBlock{Status: status}
|
result := apiBlockchainBlock{Status: status}
|
||||||
|
|
||||||
if status == 0 {
|
if status == 0 {
|
||||||
for _, record := range block.RecordsRaw {
|
for _, record := range block.RecordsRaw {
|
||||||
result.RecordsRaw = append(result.RecordsRaw, apiBlockRecordRaw{Type: record.Type, Data: record.Data})
|
result.RecordsRaw = append(result.RecordsRaw, apiBlockRecordRaw{Type: record.Type, Data: record.Data})
|
||||||
}
|
}
|
||||||
|
|
||||||
result.PeerID = hex.EncodeToString(block.OwnerPublicKey.SerializeCompressed())
|
result.PeerID = hex.EncodeToString(block.OwnerPublicKey.SerializeCompressed())
|
||||||
|
|
||||||
for _, record := range block.RecordsDecoded {
|
for _, record := range block.RecordsDecoded {
|
||||||
switch v := record.(type) {
|
switch v := record.(type) {
|
||||||
case blockchain.BlockRecordFile:
|
case blockchain.BlockRecordFile:
|
||||||
result.RecordsDecoded = append(result.RecordsDecoded, blockRecordFileToAPI(v))
|
result.RecordsDecoded = append(result.RecordsDecoded, blockRecordFileToAPI(v))
|
||||||
|
|
||||||
case blockchain.BlockRecordProfile:
|
case blockchain.BlockRecordProfile:
|
||||||
result.RecordsDecoded = append(result.RecordsDecoded, blockRecordProfileToAPI(v))
|
result.RecordsDecoded = append(result.RecordsDecoded, blockRecordProfileToAPI(v))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EncodeJSON(api.Backend, w, r, result)
|
EncodeJSON(api.Backend, w, r, result)
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
apiExploreNodeID returns the shared files of a particular node in Peernet. Results are returned in real-time. The file type is an optional filter. See TypeX.
|
|
||||||
Special type -2 = Binary, Compressed, Container, Executable. This special type includes everything except Documents, Video, Audio, Ebooks, Picture, Text.
|
|
||||||
|
|
||||||
Request: GET /blockchain/view?limit=[max records]&type=[file type]&offset=[offset]&node=[node id]
|
|
||||||
Result: 200 with JSON structure SearchResult. Check the field status.
|
|
||||||
*/
|
|
||||||
func (api *WebapiInstance) apiExploreNodeID(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"))
|
|
||||||
|
|
||||||
fileType, err := strconv.Atoi(r.Form.Get("type"))
|
|
||||||
if err != nil {
|
|
||||||
fileType = -1
|
|
||||||
}
|
|
||||||
|
|
||||||
result := api.ExploreHelper(fileType, limit, offset, NodeId, true)
|
|
||||||
|
|
||||||
EncodeJSON(api.Backend, w, r, result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -171,14 +143,6 @@ func (api *WebapiInstance) apiExploreNodeID(w http.ResponseWriter, r *http.Reque
|
|||||||
fileType = -1
|
fileType = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the node IDs are the same
|
|
||||||
if bytes.Compare(NodeId, api.Backend.SelfNodeID()) == 0 {
|
|
||||||
// setting the value of block to 0
|
|
||||||
r.Form.Add("block", "0")
|
|
||||||
api.apiBlockchainRead(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
result := api.ExploreHelper(fileType, limit, offset, NodeId, true)
|
result := api.ExploreHelper(fileType, limit, offset, NodeId, true)
|
||||||
|
|
||||||
EncodeJSON(api.Backend, w, r, result)
|
EncodeJSON(api.Backend, w, r, result)
|
||||||
|
|||||||
62
webapi/Merge directory.go
Normal file
62
webapi/Merge directory.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package webapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"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.
|
||||||
|
}
|
||||||
|
|
||||||
|
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, NodeId, 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, nodeID []byte, 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
|
||||||
|
NodeIDs, _ := api.Backend.SearchIndex.SearchNodeIDBasedOnHash(nodeID)
|
||||||
|
|
||||||
|
var result SearchResultMergedDirectory
|
||||||
|
|
||||||
|
for i := range NodeIDs {
|
||||||
|
resultFiles := api.queryRecentShared(api.Backend, fileType, uint64(limit*20/100), uint64(offset), uint64(limit), NodeIDs[i], nodeIDState)
|
||||||
|
|
||||||
|
var ApiFile []apiFile
|
||||||
|
|
||||||
|
// loop over results
|
||||||
|
for n := range resultFiles {
|
||||||
|
ApiFile = append(ApiFile, blockRecordFileToAPI(resultFiles[n]))
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Files = append(result.Files, ApiFile)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Status = 1 // No more results to expect
|
||||||
|
|
||||||
|
return &result
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user