From ae5f1d2fd7a9aee38f02e5c809e1f8771a7358bc Mon Sep 17 00:00:00 2001 From: Akilan Selvacoumar <31743758+Akilan1999@users.noreply.github.com> Date: Wed, 28 Jun 2023 00:38:17 +0100 Subject: [PATCH] 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 --- Blockchain Cache Global.go | 2 +- Blockchain User.go | 2 +- Bootstrap.go | 2 +- Command Traverse.go | 2 +- Commands.go | 2 +- Config.go | 2 +- Connection.go | 4 +- DHT Store.go | 2 +- Exit.go | 2 +- File Formats.go | 45 ++++++------ Filter.go | 2 +- Kademlia.go | 2 +- Message Send.go | 2 +- Network Detection.go | 2 +- Network IPv4 Broadcast.go | 2 +- Network IPv6 Multicast.go | 4 +- Network Init.go | 2 +- Network UPnP.go | 2 +- Network.go | 2 +- Networks.go | 2 +- Peer ID.go | 2 +- Peernet.go | 4 +- Ping.go | 2 +- Transfer Block.go | 2 +- Transfer UDT.go | 2 +- Transfer Virtual Connection.go | 2 +- Warehouse.go | 2 +- blockchain/Block Record File.go | 3 +- blockchain/Block Record Profile.go | 6 +- blockchain/Block Record.go | 4 +- blockchain/Block.go | 2 +- blockchain/Blockchain.go | 2 +- blockchain/File Tag.go | 4 +- blockchain/File.go | 2 +- blockchain/Multi.go | 9 ++- blockchain/Profile Data.go | 2 +- blockchain/Profile.go | 8 +-- blockchain/Test_test.go | 2 +- dht/DHT Lite.go | 2 +- dht/Hash Table.go | 2 +- dht/Information Request.go | 2 +- dht/Node.go | 2 +- dht/Search Client.go | 2 +- merkle/Fragment.go | 2 +- merkle/Merkle Tree.go | 2 +- protocol/Command.go | 2 +- protocol/File Transfer.go | 2 +- protocol/Hash.go | 2 +- protocol/Message Encoding Announcement.go | 2 +- protocol/Message Encoding Get Block.go | 2 +- protocol/Message Encoding Response.go | 2 +- protocol/Message Encoding Transfer.go | 2 +- protocol/Message Encoding Traverse.go | 2 +- protocol/Message Encoding.go | 2 +- protocol/Packet Encoding.go | 2 +- protocol/Packet Lite.go | 2 +- protocol/Sequence.go | 2 +- sanitize/Sanitize.go | 2 +- search/Normalize.go | 2 +- search/Search Index.go | 2 +- search/Search Term.go | 2 +- search/Text 2 Hash.go | 2 +- store/Memory.go | 2 +- store/Pebble.go | 2 +- store/Pogreb.go | 2 +- store/Store.go | 2 +- system/Execute.go | 2 +- system/Read Package.go | 2 +- upnp/UPnP.go | 2 +- warehouse/Merkle.go | 2 +- warehouse/Store.go | 16 +++-- warehouse/Warehouse.go | 6 +- webapi/API.go | 18 ++++- webapi/Blockchain.go | 5 +- webapi/Download Transfer.go | 2 +- webapi/Download.go | 8 ++- webapi/File Detection.go | 5 +- webapi/File IO.go | 2 +- webapi/File.go | 36 ++++++++-- webapi/GeoIP.go | 2 +- webapi/HTTP Range.go | 2 +- webapi/Merge directory.go | 28 +++----- webapi/Profile.go | 69 +++++++++++++++--- webapi/Search Dispatch.go | 9 ++- webapi/Search Job.go | 5 +- webapi/Search.go | 27 +++++-- webapi/Shared Recent.go | 25 ++++++- webapi/Status.go | 2 +- webapi/Upload.go | 86 +++++++++++++++++++++++ webapi/Warehouse.go | 54 ++++++++++++-- webapi/readme.md | 61 +++++++++------- 91 files changed, 483 insertions(+), 196 deletions(-) create mode 100644 webapi/Upload.go diff --git a/Blockchain Cache Global.go b/Blockchain Cache Global.go index 2b8926a..8eb5acc 100644 --- a/Blockchain Cache Global.go +++ b/Blockchain Cache Global.go @@ -1,5 +1,5 @@ /* -File Name: Blockchain Cache Global.go +File Username: Blockchain Cache Global.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Blockchain User.go b/Blockchain User.go index 81af81b..ae56f13 100644 --- a/Blockchain User.go +++ b/Blockchain User.go @@ -1,5 +1,5 @@ /* -File Name: Blockchain User.go +File Username: Blockchain User.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Bootstrap.go b/Bootstrap.go index 7adebd6..8e13a84 100644 --- a/Bootstrap.go +++ b/Bootstrap.go @@ -1,5 +1,5 @@ /* -File Name: Bootstrap.go +File Username: Bootstrap.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/Command Traverse.go b/Command Traverse.go index afc68d7..699f055 100644 --- a/Command Traverse.go +++ b/Command Traverse.go @@ -1,5 +1,5 @@ /* -File Name: Command Traverse.go +File Username: Command Traverse.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Commands.go b/Commands.go index 6edb990..b362a73 100644 --- a/Commands.go +++ b/Commands.go @@ -1,5 +1,5 @@ /* -File Name: Commands.go +File Username: Commands.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Config.go b/Config.go index 0562196..7f7a4bb 100644 --- a/Config.go +++ b/Config.go @@ -1,5 +1,5 @@ /* -File Name: Settings.go +File Username: Settings.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Connection.go b/Connection.go index a7a41da..309a282 100644 --- a/Connection.go +++ b/Connection.go @@ -1,5 +1,5 @@ /* -File Name: Connection.go +File Username: Connection.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ @@ -357,7 +357,7 @@ func (c *Connection) send(packet *protocol.PacketRaw, receiverPublicKey *btcec.P // Send Traverse message if the peer is behind a NAT or firewall and this is the first message. Only for Announcement. if err == nil && isFirstPacket && (c.IsBehindNAT() || c.Firewall) && c.traversePeer != nil && packet.Command == protocol.CommandAnnouncement { - c.traversePeer.sendTraverse(packet, receiverPublicKey) + err = c.traversePeer.sendTraverse(packet, receiverPublicKey) } return err diff --git a/DHT Store.go b/DHT Store.go index d420772..c2c20c6 100644 --- a/DHT Store.go +++ b/DHT Store.go @@ -1,5 +1,5 @@ /* -File Name: DHT Store.go +File Username: DHT Store.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Exit.go b/Exit.go index ae59168..bd0846a 100644 --- a/Exit.go +++ b/Exit.go @@ -1,5 +1,5 @@ /* -File Name: Exit.go +File Username: Exit.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/File Formats.go b/File Formats.go index 3d717dd..2e5ba52 100644 --- a/File Formats.go +++ b/File Formats.go @@ -1,5 +1,5 @@ /* -File Name: File Formats.go +File Username: File Formats.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner @@ -25,25 +25,26 @@ const ( // File formats. New ones may be added to the list as required. const ( - FormatBinary = iota // Binary/unspecified - FormatPDF // PDF document - FormatWord // Word document - FormatExcel // Excel - FormatPowerpoint // Powerpoint - FormatPicture // Pictures (including GIF, excluding icons) - FormatAudio // Audio files - FormatVideo // Video files - FormatContainer // Compressed files including ZIP, RAR, TAR and others - FormatHTML // HTML file - FormatText // Text file - FormatEbook // Ebook file - FormatCompressed // Compressed file - FormatDatabase // Database file - FormatEmail // Single email - FormatCSV // CSV file - FormatFolder // Virtual folder - FormatExecutable // Executable file - FormatInstaller // Installer - FormatAPK // APK - FormatISO // ISO + FormatBinary = iota // Binary/unspecified + FormatPDF // PDF document + FormatWord // Word document + FormatExcel // Excel + FormatPowerpoint // Powerpoint + FormatPicture // Pictures (including GIF, excluding icons) + FormatAudio // Audio files + FormatVideo // Video files + FormatContainer // Compressed files including ZIP, RAR, TAR and others + FormatHTML // HTML file + FormatText // Text file + FormatEbook // Ebook file + FormatCompressed // Compressed file + FormatDatabase // Database file + FormatEmail // Single email + FormatCSV // CSV file + FormatFolder // Virtual folder + FormatExecutable // Executable file + FormatInstaller // Installer + FormatAPK // APK + FormatISO // ISO + FormatPeernetSearch // Peernet Search ) diff --git a/Filter.go b/Filter.go index 5a4cf57..93f5819 100644 --- a/Filter.go +++ b/Filter.go @@ -1,5 +1,5 @@ /* -File Name: Filter.go +File Username: Filter.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/Kademlia.go b/Kademlia.go index e8a377b..e9f5b25 100644 --- a/Kademlia.go +++ b/Kademlia.go @@ -1,5 +1,5 @@ /* -File Name: Kademlia.go +File Username: Kademlia.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Message Send.go b/Message Send.go index f2e4e19..687c724 100644 --- a/Message Send.go +++ b/Message Send.go @@ -1,5 +1,5 @@ /* -File Name: Message Send.go +File Username: Message Send.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Network Detection.go b/Network Detection.go index 29f52b9..16677d8 100644 --- a/Network Detection.go +++ b/Network Detection.go @@ -1,5 +1,5 @@ /* -File Name: Network Detection.go +File Username: Network Detection.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Network IPv4 Broadcast.go b/Network IPv4 Broadcast.go index cbda142..0e7914e 100644 --- a/Network IPv4 Broadcast.go +++ b/Network IPv4 Broadcast.go @@ -1,5 +1,5 @@ /* -File Name: Network IPv4 Broadcast.go +File Username: Network IPv4 Broadcast.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/Network IPv6 Multicast.go b/Network IPv6 Multicast.go index f8f4594..2f7b20e 100644 --- a/Network IPv6 Multicast.go +++ b/Network IPv6 Multicast.go @@ -1,5 +1,5 @@ /* -File Name: Network IPv6 Multicast.go +File Username: Network IPv6 Multicast.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner @@ -63,7 +63,7 @@ func (network *Network) MulticastIPv6Join() (err error) { joinMulticastGroup := func(iface *net.Interface) (err error) { pc := ipv6.NewPacketConn(network.multicastSocket) if err := pc.JoinGroup(iface, &net.UDPAddr{IP: network.multicastIP}); err != nil { - //LogError("MulticastIPv6Join", "join multicast group iface '%s' multicast IP '%s' listen on IP '%s' port '%d': %v\n", iface.Name, network.multicastIP.String(), network.address.IP.String(), ipv6MulticastPort, err) + //LogError("MulticastIPv6Join", "join multicast group iface '%s' multicast IP '%s' listen on IP '%s' port '%d': %v\n", iface.Username, network.multicastIP.String(), network.address.IP.String(), ipv6MulticastPort, err) return err } diff --git a/Network Init.go b/Network Init.go index 739fb42..155f548 100644 --- a/Network Init.go +++ b/Network Init.go @@ -1,5 +1,5 @@ /* -File Name: Network Init.go +File Username: Network Init.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/Network UPnP.go b/Network UPnP.go index 5106f41..c2bfa5c 100644 --- a/Network UPnP.go +++ b/Network UPnP.go @@ -1,5 +1,5 @@ /* -File Name: Network UPnP.go +File Username: Network UPnP.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/Network.go b/Network.go index a7f078c..c2d7798 100644 --- a/Network.go +++ b/Network.go @@ -1,5 +1,5 @@ /* -File Name: Network.go +File Username: Network.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Networks.go b/Networks.go index 97bff74..8cfd234 100644 --- a/Networks.go +++ b/Networks.go @@ -1,5 +1,5 @@ /* -File Name: Networks.go +File Username: Networks.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Peer ID.go b/Peer ID.go index 680d8c2..8dd8969 100644 --- a/Peer ID.go +++ b/Peer ID.go @@ -1,5 +1,5 @@ /* -File Name: Peer ID.go +File Username: Peer ID.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Peernet.go b/Peernet.go index 796887c..b4b8ed0 100644 --- a/Peernet.go +++ b/Peernet.go @@ -1,5 +1,5 @@ /* -File Name: Peernet.go +File Username: Peernet.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ @@ -19,7 +19,7 @@ import ( ) // Init initializes the client. If the config file does not exist or is empty, a default one will be created. -// The User Agent must be provided in the form "Application Name/1.0". +// The User Agent must be provided in the form "Application Username/1.0". // The returned status is of type ExitX. Anything other than ExitSuccess indicates a fatal failure. func Init(UserAgent string, ConfigFilename string, Filters *Filters, ConfigOut interface{}) (backend *Backend, status int, err error) { if UserAgent == "" { diff --git a/Ping.go b/Ping.go index eb04ded..ac36cec 100644 --- a/Ping.go +++ b/Ping.go @@ -1,5 +1,5 @@ /* -File Name: Ping.go +File Username: Ping.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Transfer Block.go b/Transfer Block.go index 2c05a60..680aa56 100644 --- a/Transfer Block.go +++ b/Transfer Block.go @@ -1,5 +1,5 @@ /* -File Name: Transfer Block.go +File Username: Transfer Block.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/Transfer UDT.go b/Transfer UDT.go index 1d8635d..4cb370f 100644 --- a/Transfer UDT.go +++ b/Transfer UDT.go @@ -1,5 +1,5 @@ /* -File Name: Transfer UDT.go +File Username: Transfer UDT.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/Transfer Virtual Connection.go b/Transfer Virtual Connection.go index 766989d..a6a36ff 100644 --- a/Transfer Virtual Connection.go +++ b/Transfer Virtual Connection.go @@ -1,5 +1,5 @@ /* -File Name: Transfer Virtual Connection.go +File Username: Transfer Virtual Connection.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/Warehouse.go b/Warehouse.go index b6b176e..2513d27 100644 --- a/Warehouse.go +++ b/Warehouse.go @@ -1,5 +1,5 @@ /* -File Name: Warehouse.go +File Username: Warehouse.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/blockchain/Block Record File.go b/blockchain/Block Record File.go index 69de041..80633ff 100644 --- a/blockchain/Block Record File.go +++ b/blockchain/Block Record File.go @@ -1,5 +1,5 @@ /* -File Name: Block Record File.go +File Username: Block Record File.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner @@ -48,6 +48,7 @@ type BlockRecordFile struct { Size uint64 // Size of the file data NodeID []byte // Node ID, owner of the file Tags []BlockRecordFileTag // Tags provide additional metadata + Username string // Username of the User who uploaded the file } // BlockRecordFileTag provides metadata about the file. diff --git a/blockchain/Block Record Profile.go b/blockchain/Block Record Profile.go index 535bcc8..8b93720 100644 --- a/blockchain/Block Record Profile.go +++ b/blockchain/Block Record Profile.go @@ -1,5 +1,5 @@ /* -File Name: Block Record Profile.go +File Username: Block Record Profile.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner @@ -24,8 +24,8 @@ type BlockRecordProfile struct { Data []byte // Data } -// decodeBlockRecordProfile decodes only profile records. Other records are ignored. -func decodeBlockRecordProfile(recordsRaw []BlockRecordRaw) (fields []BlockRecordProfile, err error) { +// DecodeBlockRecordProfile decodes only profile records. Other records are ignored. +func DecodeBlockRecordProfile(recordsRaw []BlockRecordRaw) (fields []BlockRecordProfile, err error) { fieldMap := make(map[uint16][]byte) for _, record := range recordsRaw { diff --git a/blockchain/Block Record.go b/blockchain/Block Record.go index 5a411e6..606d177 100644 --- a/blockchain/Block Record.go +++ b/blockchain/Block Record.go @@ -1,5 +1,5 @@ /* -File Name: Block Record.go +File Username: Block Record.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner @@ -45,7 +45,7 @@ func decodeBlockRecords(block *Block) (decoded *BlockDecoded, err error) { decoded.RecordsDecoded = append(decoded.RecordsDecoded, file) } - if profileFields, err := decodeBlockRecordProfile(block.RecordsRaw); err != nil { + if profileFields, err := DecodeBlockRecordProfile(block.RecordsRaw); err != nil { return nil, err } else if len(profileFields) > 0 { decoded.RecordsDecoded = append(decoded.RecordsDecoded, profileFields) diff --git a/blockchain/Block.go b/blockchain/Block.go index 9b546f6..7f4ee29 100644 --- a/blockchain/Block.go +++ b/blockchain/Block.go @@ -1,5 +1,5 @@ /* -File Name: Block.go +File Username: Block.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/blockchain/Blockchain.go b/blockchain/Blockchain.go index f2a7e99..d3052a6 100644 --- a/blockchain/Blockchain.go +++ b/blockchain/Blockchain.go @@ -1,5 +1,5 @@ /* -File Name: Blockchain.go +File Username: Blockchain.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/blockchain/File Tag.go b/blockchain/File Tag.go index 8be13c3..ee414a3 100644 --- a/blockchain/File Tag.go +++ b/blockchain/File Tag.go @@ -1,5 +1,5 @@ /* -File Name: File Tag.go +File Username: File Tag.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner @@ -16,7 +16,7 @@ import ( // List of defined file tags. Virtual tags are generated at runtime and are read-only. They cannot be stored on the blockchain. const ( - TagName = 0 // Name of file. + TagName = 0 // Username of file. TagFolder = 1 // Folder name. TagDescription = 2 // Arbitrary description of the file. May contain hashtags. TagDateShared = 3 // When the file was published on the blockchain. Virtual. diff --git a/blockchain/File.go b/blockchain/File.go index 7e82908..7b95af0 100644 --- a/blockchain/File.go +++ b/blockchain/File.go @@ -1,5 +1,5 @@ /* -File Name: File.go +File Username: File.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/blockchain/Multi.go b/blockchain/Multi.go index 032b3e6..778c23c 100644 --- a/blockchain/Multi.go +++ b/blockchain/Multi.go @@ -1,5 +1,5 @@ /* -File Name: Multi.go +File Username: Multi.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner @@ -16,6 +16,7 @@ package blockchain import ( "encoding/binary" "errors" + "fmt" "time" "github.com/PeernetOfficial/core/btcec" @@ -277,7 +278,11 @@ func (multi *MultiStore) IngestBlock(header *MultiBlockchainHeader, blockNumber } // store the transferred block in the cache - multi.WriteBlock(header.PublicKey, header.Version, blockNumber, raw) + err = multi.WriteBlock(header.PublicKey, header.Version, blockNumber, raw) + if err != nil { + fmt.Println(err) + } + header.ListBlocks = append(header.ListBlocks, blockNumber) // update blockchain header stats if records were decoded diff --git a/blockchain/Profile Data.go b/blockchain/Profile Data.go index 0999824..8d1f5be 100644 --- a/blockchain/Profile Data.go +++ b/blockchain/Profile Data.go @@ -1,5 +1,5 @@ /* -File Name: Profile Data.go +File Username: Profile Data.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/blockchain/Profile.go b/blockchain/Profile.go index 2929434..75d36e3 100644 --- a/blockchain/Profile.go +++ b/blockchain/Profile.go @@ -1,5 +1,5 @@ /* -File Name: Profile.go +File Username: Profile.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ @@ -11,7 +11,7 @@ func (blockchain *Blockchain) ProfileReadField(index uint16) (data []byte, statu found := false status = blockchain.Iterate(func(block *Block) (statusI int) { - fields, err := decodeBlockRecordProfile(block.RecordsRaw) + fields, err := DecodeBlockRecordProfile(block.RecordsRaw) if err != nil { return StatusCorruptBlockRecord } else if len(fields) == 0 { @@ -43,7 +43,7 @@ func (blockchain *Blockchain) ProfileList() (fields []BlockRecordProfile, status uniqueFields := make(map[uint16][]byte) status = blockchain.Iterate(func(block *Block) (statusI int) { - fields, err := decodeBlockRecordProfile(block.RecordsRaw) + fields, err := DecodeBlockRecordProfile(block.RecordsRaw) if err != nil { return StatusCorruptBlockRecord } @@ -103,7 +103,7 @@ func (blockchain *Blockchain) ProfileDelete(fields []uint16) (newHeight, newVers return 0 // no action } - existingFields, err := decodeBlockRecordProfile([]BlockRecordRaw{*record}) + existingFields, err := DecodeBlockRecordProfile([]BlockRecordRaw{*record}) if err != nil || len(existingFields) != 1 { return 3 // error blockchain corrupt } diff --git a/blockchain/Test_test.go b/blockchain/Test_test.go index 4798c58..78c6faa 100644 --- a/blockchain/Test_test.go +++ b/blockchain/Test_test.go @@ -167,7 +167,7 @@ func printFile(file BlockRecordFile) { for _, tag := range file.Tags { switch tag.Type { case TagName: - fmt.Printf(" Name %s\n", tag.Text()) + fmt.Printf(" Username %s\n", tag.Text()) case TagFolder: fmt.Printf(" Folder %s\n", tag.Text()) case TagDescription: diff --git a/dht/DHT Lite.go b/dht/DHT Lite.go index 55b0b32..f46faa8 100644 --- a/dht/DHT Lite.go +++ b/dht/DHT Lite.go @@ -1,5 +1,5 @@ /* -File Name: DHT Lite.go +File Username: DHT Lite.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/dht/Hash Table.go b/dht/Hash Table.go index 67e2564..9fa0b3d 100644 --- a/dht/Hash Table.go +++ b/dht/Hash Table.go @@ -1,5 +1,5 @@ /* -File Name: Hash Table.go +File Username: Hash Table.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/dht/Information Request.go b/dht/Information Request.go index 0e88036..d38a812 100644 --- a/dht/Information Request.go +++ b/dht/Information Request.go @@ -1,5 +1,5 @@ /* -File Name: Information Request.go +File Username: Information Request.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/dht/Node.go b/dht/Node.go index 0510071..67b7d34 100644 --- a/dht/Node.go +++ b/dht/Node.go @@ -1,5 +1,5 @@ /* -File Name: Node.go +File Username: Node.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/dht/Search Client.go b/dht/Search Client.go index 8ebf588..0dec1f8 100644 --- a/dht/Search Client.go +++ b/dht/Search Client.go @@ -1,5 +1,5 @@ /* -File Name: Search Client.go +File Username: Search Client.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/merkle/Fragment.go b/merkle/Fragment.go index ca57b96..daae8df 100644 --- a/merkle/Fragment.go +++ b/merkle/Fragment.go @@ -1,5 +1,5 @@ /* -File Name: Fragment.go +File Username: Fragment.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/merkle/Merkle Tree.go b/merkle/Merkle Tree.go index b657e9c..6be5989 100644 --- a/merkle/Merkle Tree.go +++ b/merkle/Merkle Tree.go @@ -1,5 +1,5 @@ /* -File Name: Merkle Tree.go +File Username: Merkle Tree.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/protocol/Command.go b/protocol/Command.go index a721386..15aa4c8 100644 --- a/protocol/Command.go +++ b/protocol/Command.go @@ -1,5 +1,5 @@ /* -File Name: Command.go +File Username: Command.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/protocol/File Transfer.go b/protocol/File Transfer.go index 6e9aed7..c21f542 100644 --- a/protocol/File Transfer.go +++ b/protocol/File Transfer.go @@ -1,5 +1,5 @@ /* -File Name: File Transfer.go +File Username: File Transfer.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/protocol/Hash.go b/protocol/Hash.go index 4360c81..a2b34d2 100644 --- a/protocol/Hash.go +++ b/protocol/Hash.go @@ -1,5 +1,5 @@ /* -File Name: Hash.go +File Username: Hash.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/protocol/Message Encoding Announcement.go b/protocol/Message Encoding Announcement.go index 70a3daf..7e7b48d 100644 --- a/protocol/Message Encoding Announcement.go +++ b/protocol/Message Encoding Announcement.go @@ -1,5 +1,5 @@ /* -File Name: Message Encoding Announcement.go +File Username: Message Encoding Announcement.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/protocol/Message Encoding Get Block.go b/protocol/Message Encoding Get Block.go index 0d91553..895f891 100644 --- a/protocol/Message Encoding Get Block.go +++ b/protocol/Message Encoding Get Block.go @@ -1,5 +1,5 @@ /* -File Name: Message Encoding Get Block.go +File Username: Message Encoding Get Block.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/protocol/Message Encoding Response.go b/protocol/Message Encoding Response.go index b4211dc..2ead7e6 100644 --- a/protocol/Message Encoding Response.go +++ b/protocol/Message Encoding Response.go @@ -1,5 +1,5 @@ /* -File Name: Message Encoding Response.go +File Username: Message Encoding Response.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/protocol/Message Encoding Transfer.go b/protocol/Message Encoding Transfer.go index 4e6f8c0..1c8e664 100644 --- a/protocol/Message Encoding Transfer.go +++ b/protocol/Message Encoding Transfer.go @@ -1,5 +1,5 @@ /* -File Name: Message Encoding Transfer.go +File Username: Message Encoding Transfer.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/protocol/Message Encoding Traverse.go b/protocol/Message Encoding Traverse.go index 513c917..2ead025 100644 --- a/protocol/Message Encoding Traverse.go +++ b/protocol/Message Encoding Traverse.go @@ -1,5 +1,5 @@ /* -File Name: Message Encoding Traverse.go +File Username: Message Encoding Traverse.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/protocol/Message Encoding.go b/protocol/Message Encoding.go index 8e306ee..ad617ab 100644 --- a/protocol/Message Encoding.go +++ b/protocol/Message Encoding.go @@ -1,5 +1,5 @@ /* -File Name: Message Encoding.go +File Username: Message Encoding.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/protocol/Packet Encoding.go b/protocol/Packet Encoding.go index 5e3214c..8a77b76 100644 --- a/protocol/Packet Encoding.go +++ b/protocol/Packet Encoding.go @@ -1,5 +1,5 @@ /* -File Name: Packet Encoding.go +File Username: Packet Encoding.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/protocol/Packet Lite.go b/protocol/Packet Lite.go index 31eb1a5..bc1a168 100644 --- a/protocol/Packet Lite.go +++ b/protocol/Packet Lite.go @@ -1,5 +1,5 @@ /* -File Name: Packet Lite.go +File Username: Packet Lite.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/protocol/Sequence.go b/protocol/Sequence.go index fe6c557..3a39f85 100644 --- a/protocol/Sequence.go +++ b/protocol/Sequence.go @@ -1,5 +1,5 @@ /* -File Name: Sequence.go +File Username: Sequence.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/sanitize/Sanitize.go b/sanitize/Sanitize.go index 6c8899c..3f1c7ff 100644 --- a/sanitize/Sanitize.go +++ b/sanitize/Sanitize.go @@ -1,5 +1,5 @@ /* -File Name: Sanitize.go +File Username: Sanitize.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/search/Normalize.go b/search/Normalize.go index 3fb1cd2..a5aa2d4 100644 --- a/search/Normalize.go +++ b/search/Normalize.go @@ -1,5 +1,5 @@ /* -File Name: Normalizing.go +File name: Normalizing.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/search/Search Index.go b/search/Search Index.go index 107e4fa..0c340f9 100644 --- a/search/Search Index.go +++ b/search/Search Index.go @@ -1,5 +1,5 @@ /* -File Name: Search Index.go +File name: Search Index.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/search/Search Term.go b/search/Search Term.go index a0f6885..158d2f5 100644 --- a/search/Search Term.go +++ b/search/Search Term.go @@ -1,5 +1,5 @@ /* -File Name: Search Term.go +File name: Search Term.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/search/Text 2 Hash.go b/search/Text 2 Hash.go index 5343b3e..b9a7ead 100644 --- a/search/Text 2 Hash.go +++ b/search/Text 2 Hash.go @@ -1,5 +1,5 @@ /* -File Name: Text 2 Hash.go +File name: Text 2 Hash.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/store/Memory.go b/store/Memory.go index 5e987f9..0c06003 100644 --- a/store/Memory.go +++ b/store/Memory.go @@ -1,5 +1,5 @@ /* -File Name: Memory.go +File name: Memory.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/store/Pebble.go b/store/Pebble.go index dd2c088..284bf88 100644 --- a/store/Pebble.go +++ b/store/Pebble.go @@ -1,5 +1,5 @@ /* -File Name: Pebble.go +File name: Pebble.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/store/Pogreb.go b/store/Pogreb.go index 5d10ea1..940b32c 100644 --- a/store/Pogreb.go +++ b/store/Pogreb.go @@ -1,5 +1,5 @@ /* -File Name: Pogreb.go +File Username: Pogreb.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/store/Store.go b/store/Store.go index 4e9a47d..63bea7e 100644 --- a/store/Store.go +++ b/store/Store.go @@ -1,5 +1,5 @@ /* -File Name: Store.go +File Username: Store.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner diff --git a/system/Execute.go b/system/Execute.go index 03c4f8a..a8d5277 100644 --- a/system/Execute.go +++ b/system/Execute.go @@ -1,5 +1,5 @@ /* -File Name: Execute.go +File Username: Execute.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/system/Read Package.go b/system/Read Package.go index f430adb..44be12a 100644 --- a/system/Read Package.go +++ b/system/Read Package.go @@ -1,5 +1,5 @@ /* -File Name: Read Package.go +File Username: Read Package.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/upnp/UPnP.go b/upnp/UPnP.go index dbcd0d5..9a5b49b 100644 --- a/upnp/UPnP.go +++ b/upnp/UPnP.go @@ -1,5 +1,5 @@ /* -File Name: UPnP.go +File Username: UPnP.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner */ diff --git a/warehouse/Merkle.go b/warehouse/Merkle.go index ac552dd..8dc7be3 100644 --- a/warehouse/Merkle.go +++ b/warehouse/Merkle.go @@ -1,5 +1,5 @@ /* -File Name: Merkle.go +File Username: Merkle.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ diff --git a/warehouse/Store.go b/warehouse/Store.go index 73cd83e..9cbfd26 100644 --- a/warehouse/Store.go +++ b/warehouse/Store.go @@ -1,5 +1,5 @@ /* -File Name: Store.go +File Username: Store.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -38,7 +38,7 @@ const ( // CreateFile creates a new file in the warehouse // If fileSize is provided, creating the merkle tree is significantly faster as it will be created on the fly. If the file size is unknown, set the size to 0. -func (wh *Warehouse) CreateFile(data io.Reader, fileSize uint64) (hash []byte, status int, err error) { +func (wh *Warehouse) CreateFile(data io.Reader, fileSize uint64, uploadStatus io.Writer) (hash []byte, status int, err error) { // create a temporary file to hold the body content tmpFile, err := wh.tempFile() if err != nil { @@ -55,8 +55,14 @@ func (wh *Warehouse) CreateFile(data io.Reader, fileSize uint64) (hash []byte, s // create the hash-writer hashWriter := blake3.New(hashSize, nil) - // the multi-writer writes to the temp-file and the hash simultaneously - mw := io.MultiWriter(tmpFile, hashWriter) + var mw io.Writer + + if uploadStatus != nil { + // the multi-writer writes to the temp-file and the hash simultaneously + mw = io.MultiWriter(tmpFile, hashWriter, uploadStatus) + } else { + mw = io.MultiWriter(tmpFile, hashWriter) + } // copy into the multiwriter if _, err = io.Copy(mw, data); err != nil { @@ -132,7 +138,7 @@ func (wh *Warehouse) CreateFileFromPath(file string) (hash []byte, status int, e } // create the file using the opened file - return wh.CreateFile(fileHandle, fileSize) + return wh.CreateFile(fileHandle, fileSize, nil) } // ReadFile reads a file from the warehouse and outputs it to the writer diff --git a/warehouse/Warehouse.go b/warehouse/Warehouse.go index a0479a6..f2ae65b 100644 --- a/warehouse/Warehouse.go +++ b/warehouse/Warehouse.go @@ -1,5 +1,5 @@ /* -File Name: Warehouse.go +File Username: Warehouse.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -93,7 +93,7 @@ func (wh *Warehouse) IterateFiles(Callback func(Hash []byte, Size int64) (Contin name1 := file.Name() _, err = hex.DecodeString(name1) - // we are only looking for directories. Name has to be "XXXX" hex chars only. + // we are only looking for directories. Username has to be "XXXX" hex chars only. if !file.IsDir() || len(name1) != 4 || err != nil { continue } @@ -108,7 +108,7 @@ func (wh *Warehouse) IterateFiles(Callback func(Hash []byte, Size int64) (Contin name2 := file2.Name() _, err = hex.DecodeString(name2) - // we are only looking for directories. Name has to be "XXXX" hex chars only. + // we are only looking for directories. Username has to be "XXXX" hex chars only. if !file2.IsDir() || len(name2) != 4 || err != nil { continue } diff --git a/webapi/API.go b/webapi/API.go index 319dbbb..1e553d9 100644 --- a/webapi/API.go +++ b/webapi/API.go @@ -1,5 +1,5 @@ /* -File Name: API.go +File Username: API.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -36,6 +36,17 @@ type WebapiInstance struct { // download info downloads map[uuid.UUID]*downloadInfo downloadsMutex sync.RWMutex + + // upload info + uploads map[uuid.UUID]*UploadStatus + uploadsMutex sync.RWMutex +} + +// API error +// This follows the same format as the logger +type errorResponse struct { + function string + error string } // WSUpgrader is used for websocket functionality. It allows all requests. @@ -62,6 +73,7 @@ func Start(Backend *core.Backend, ListenAddresses []string, UseSSL bool, Certifi AllowKeyInParam: []string{"/file/read", "/file/view"}, allJobs: make(map[uuid.UUID]*SearchJob), downloads: make(map[uuid.UUID]*downloadInfo), + uploads: make(map[uuid.UUID]*UploadStatus), } if APIKey != uuid.Nil { @@ -96,7 +108,9 @@ func Start(Backend *core.Backend, ListenAddresses []string, UseSSL bool, Certifi api.Router.HandleFunc("/download/start", api.apiDownloadStart).Methods("GET") api.Router.HandleFunc("/download/status", api.apiDownloadStatus).Methods("GET") api.Router.HandleFunc("/download/action", api.apiDownloadAction).Methods("GET") - api.Router.HandleFunc("/warehouse/create", api.apiWarehouseCreateFile).Methods("POST") + api.Router.HandleFunc("/warehouse/create", api.ApiWarehouseCreateFile).Methods("POST") + api.Router.HandleFunc("/warehouse/create/uploadID", api.apiUploadID).Methods("GET") + api.Router.HandleFunc("/warehouse/create/track/uploadID", api.apiUploadInfo).Methods("GET") api.Router.HandleFunc("/warehouse/create/path", api.apiWarehouseCreateFilePath).Methods("GET") api.Router.HandleFunc("/warehouse/read", api.apiWarehouseReadFile).Methods("GET") api.Router.HandleFunc("/warehouse/read/path", api.apiWarehouseReadFilePath).Methods("GET") diff --git a/webapi/Blockchain.go b/webapi/Blockchain.go index ac7db19..7e3c6dd 100644 --- a/webapi/Blockchain.go +++ b/webapi/Blockchain.go @@ -1,5 +1,5 @@ /* -File Name: Blockchain.go +File Username: Blockchain.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -8,10 +8,9 @@ package webapi import ( "encoding/hex" + "github.com/PeernetOfficial/core/blockchain" "net/http" "strconv" - - "github.com/PeernetOfficial/core/blockchain" ) type apiBlockchainHeader struct { diff --git a/webapi/Download Transfer.go b/webapi/Download Transfer.go index be41124..7ab7c58 100644 --- a/webapi/Download Transfer.go +++ b/webapi/Download Transfer.go @@ -1,5 +1,5 @@ /* -File Name: Download Transfer.go +File Username: Download Transfer.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner diff --git a/webapi/Download.go b/webapi/Download.go index 9e90209..a4cf890 100644 --- a/webapi/Download.go +++ b/webapi/Download.go @@ -1,5 +1,5 @@ /* -File Name: Download.go +File Username: Download.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -78,6 +78,8 @@ func (api *WebapiInstance) apiDownloadStart(w http.ResponseWriter, r *http.Reque info := &downloadInfo{backend: api.Backend, api: api, id: uuid.New(), created: time.Now(), hash: hash, nodeID: nodeID} + api.Backend.LogError("Download.DownloadStart", "output %v", downloadInfo{backend: api.Backend, api: api, id: uuid.New(), created: time.Now(), hash: hash, nodeID: nodeID}) + // create the file immediately if info.initDiskFile(filePath) != nil { EncodeJSON(api.Backend, w, r, apiResponseDownloadStatus{APIStatus: DownloadResponseFileInvalid}) @@ -90,6 +92,8 @@ func (api *WebapiInstance) apiDownloadStart(w http.ResponseWriter, r *http.Reque // start the download! go info.Start() + api.Backend.LogError("Download.DownloadStart", "output %v", apiResponseDownloadStatus{APIStatus: DownloadResponseSuccess, ID: info.id, DownloadStatus: DownloadWaitMetadata}) + EncodeJSON(api.Backend, w, r, apiResponseDownloadStatus{APIStatus: DownloadResponseSuccess, ID: info.id, DownloadStatus: DownloadWaitMetadata}) } @@ -132,6 +136,8 @@ func (api *WebapiInstance) apiDownloadStatus(w http.ResponseWriter, r *http.Requ info.RUnlock() + api.Backend.LogError("Download.DownloadStatus", "output %v", response) + EncodeJSON(api.Backend, w, r, response) } diff --git a/webapi/File Detection.go b/webapi/File Detection.go index b20fc2f..640164f 100644 --- a/webapi/File Detection.go +++ b/webapi/File Detection.go @@ -1,5 +1,5 @@ /* -File Name: File Detection.go +File: File Detection.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -94,6 +94,9 @@ func FileTranslateExtension(extension string) (fileType, fileFormat uint16) { case "iso": return core.TypeContainer, core.FormatISO + case "pnsearch": + return core.TypeText, core.FormatPeernetSearch + default: return core.TypeBinary, core.FormatBinary } diff --git a/webapi/File IO.go b/webapi/File IO.go index 48e4763..15657d0 100644 --- a/webapi/File IO.go +++ b/webapi/File IO.go @@ -1,5 +1,5 @@ /* -File Name: File IO.go +File Username: File IO.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ diff --git a/webapi/File.go b/webapi/File.go index c6f6b0d..7d8201a 100644 --- a/webapi/File.go +++ b/webapi/File.go @@ -1,5 +1,5 @@ /* -File Name: File.go +File Username: File.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -8,6 +8,7 @@ package webapi import ( "net/http" + "strconv" "time" "github.com/PeernetOfficial/core" @@ -42,14 +43,18 @@ type apiFile struct { Date time.Time `json:"date"` // Date shared NodeID []byte `json:"nodeid"` // Node ID, owner of the file. Read only. Metadata []apiFileMetadata `json:"metadata"` // Additional metadata. + Username string `json:"username"` // Username of the user who uploaded the file } // --- conversion from core to API data --- func blockRecordFileToAPI(input blockchain.BlockRecordFile) (output apiFile) { - output = apiFile{ID: input.ID, Hash: input.Hash, NodeID: input.NodeID, Type: input.Type, Format: input.Format, Size: input.Size, Metadata: []apiFileMetadata{}} + output = apiFile{ID: input.ID, Hash: input.Hash, NodeID: input.NodeID, Type: input.Type, Format: input.Format, Size: input.Size, Username: input.Username, Metadata: []apiFileMetadata{}} for _, tag := range input.Tags { + if tag.Type == blockchain.TagSharedByCount && tag.Number() == 0 { + return apiFile{} + } switch tag.Type { case blockchain.TagName: output.Name = tag.Text() @@ -69,6 +74,10 @@ func blockRecordFileToAPI(input blockchain.BlockRecordFile) (output apiFile) { case blockchain.TagSharedByCount: output.Metadata = append(output.Metadata, apiFileMetadata{Type: tag.Type, Name: "Shared By Count", Number: tag.Number()}) + // if a file has 0 peers sharing then do not add it to the list. + if tag.Number() == 0 { + return apiFile{} + } case blockchain.TagSharedByGeoIP: output.Metadata = append(output.Metadata, apiFileMetadata{Type: tag.Type, Name: "Shared By GeoIP", Text: tag.Text()}) @@ -136,6 +145,7 @@ Response: 200 with JSON structure apiBlockchainBlockStatus func (api *WebapiInstance) apiBlockchainFileAdd(w http.ResponseWriter, r *http.Request) { var input apiBlockAddFiles if err := DecodeJSON(w, r, &input); err != nil { + api.Backend.LogError("blockchain.AddFile", "error: %v", "error decoding JSON") return } @@ -143,6 +153,8 @@ func (api *WebapiInstance) apiBlockchainFileAdd(w http.ResponseWriter, r *http.R for _, file := range input.Files { if len(file.Hash) != protocol.HashSize { + api.Backend.LogError("blockchain.AddFile", "error: %v", "file length is not the same length as "+ + "the protocol hash size.") http.Error(w, "", http.StatusBadRequest) return } @@ -153,6 +165,7 @@ func (api *WebapiInstance) apiBlockchainFileAdd(w http.ResponseWriter, r *http.R // Verify that the file exists in the warehouse. Folders are exempt from this check as they are only virtual. if !file.IsVirtualFolder() { if _, err := warehouse.ValidateHash(file.Hash); err != nil { + api.Backend.LogError("blockchain.AddFile", "error: %v", err) http.Error(w, "", http.StatusBadRequest) return } else if _, fileSize, status, _ := api.Backend.UserWarehouse.FileExists(file.Hash); status != warehouse.StatusOK { @@ -179,22 +192,37 @@ func (api *WebapiInstance) apiBlockchainFileAdd(w http.ResponseWriter, r *http.R newHeight, newVersion, status := api.Backend.UserBlockchain.AddFiles(filesAdd) + // Temporary log to check the output for warehouse API + api.Backend.LogError("blockchain.AddFile", "output %v", apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion}) + EncodeJSON(api.Backend, w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion}) } /* apiBlockchainFileList lists all files stored on the blockchain. -Request: GET /blockchain/file/list +Request: GET /blockchain/file/list?fileFormat= Response: 200 with JSON structure apiBlockAddFiles */ func (api *WebapiInstance) apiBlockchainFileList(w http.ResponseWriter, r *http.Request) { files, status := api.Backend.UserBlockchain.ListFiles() + r.ParseForm() + // filter based on file type + fileType, err := strconv.Atoi(r.Form.Get("fileFormat")) + var result apiBlockAddFiles for _, file := range files { - result.Files = append(result.Files, blockRecordFileToAPI(file)) + ApiFile := blockRecordFileToAPI(file) + if ApiFile.NodeID == nil { + continue + } + if ApiFile.Format == uint16(fileType) { + result.Files = append(result.Files, ApiFile) + } else if err != nil { + result.Files = append(result.Files, ApiFile) + } } result.Status = status diff --git a/webapi/GeoIP.go b/webapi/GeoIP.go index 3e19b94..03be9b3 100644 --- a/webapi/GeoIP.go +++ b/webapi/GeoIP.go @@ -1,5 +1,5 @@ /* -File Name: GeoIP.go +File Username: GeoIP.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner diff --git a/webapi/HTTP Range.go b/webapi/HTTP Range.go index cb8985f..bb5b1a2 100644 --- a/webapi/HTTP Range.go +++ b/webapi/HTTP Range.go @@ -1,5 +1,5 @@ /* -File Name: HTTP Range.go +File Username: HTTP Range.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ diff --git a/webapi/Merge directory.go b/webapi/Merge directory.go index 92df57e..59ee093 100644 --- a/webapi/Merge directory.go +++ b/webapi/Merge directory.go @@ -69,7 +69,11 @@ func (api *WebapiInstance) ExploreFileSharedByNodeThatSharedSimilarFile(fileType // loop over results for n := range resultFiles { - result.Files = append(result.Files, blockRecordFileToAPI(resultFiles[n])) + ApiFile := blockRecordFileToAPI(resultFiles[n]) + if ApiFile.NodeID == nil { + continue + } + result.Files = append(result.Files, ApiFile) } } @@ -86,8 +90,6 @@ func (api *WebapiInstance) GreedySearchMergeDirection(nodeID *[][]byte, fileType // get all NodeIDs peerList := api.Backend.PeerlistGet() - //var tags []blockchain.BlockRecordFileTag - // search with AllNodes which have a match of the NodeID. for _, peer := range peerList { if peer.BlockchainHeight == 0 { @@ -112,28 +114,18 @@ func (api *WebapiInstance) GreedySearchMergeDirection(nodeID *[][]byte, fileType file.Tags = append(file.Tags, blockchain.TagFromText(blockchain.TagSharedByGeoIP, sharedByGeoIP)) } - // found a new file! append. - filesFromPeer++ + //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) } - - //for _, tag := range file.Tags { - // // checks if any of tags from - // // the NodeID provided matches - // // Requires better search parameters - // // So that it's more narrow - // for i := range tags { - // if tag.Text() == tags[i].Text() { - // *nodeID = append(*nodeID, file.NodeID) - // break - // } - // } - //} } } diff --git a/webapi/Profile.go b/webapi/Profile.go index 683b696..ec36551 100644 --- a/webapi/Profile.go +++ b/webapi/Profile.go @@ -1,5 +1,5 @@ /* -File Name: Profile.go +File Username: Profile.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -7,8 +7,10 @@ Author: Peter Kleissner package webapi import ( + "bytes" "net/http" "strconv" + "time" "github.com/PeernetOfficial/core/blockchain" ) @@ -31,15 +33,50 @@ type apiBlockRecordProfile struct { /* apiProfileList lists all users profile fields. -Request: GET /profile/list +Request: GET /profile/list?node=[nodeid] Response: 200 with JSON structure apiProfileData */ func (api *WebapiInstance) apiProfileList(w http.ResponseWriter, r *http.Request) { - fields, status := api.Backend.UserBlockchain.ProfileList() + + NodeID, valid := DecodeBlake3Hash(r.URL.Query().Get("node")) + + var fields []blockchain.BlockRecordProfile + var status int result := apiProfileData{Status: status} - for n := range fields { - result.Fields = append(result.Fields, blockRecordProfileToAPI(fields[n])) + + if valid && !bytes.Equal(NodeID, api.Backend.SelfNodeID()) { + //_, node, _ := api.Backend.FindNode(NodeID, 100) + + _, peers, _ := api.Backend.FindNode(NodeID, time.Second*5) + // First iteration of the entire blockchain to search for the profile + // image and Username of the user + + for blockN1 := peers.BlockchainHeight; blockN1 > 0; blockN1-- { + blockDecoded, _, found, _ := api.Backend.ReadBlock(peers.PublicKey, peers.BlockchainVersion, blockN1) + if !found { + continue + } + + profile, _ := blockchain.DecodeBlockRecordProfile(blockDecoded.Block.RecordsRaw) + // Adding profile image and Username to the output + for raw, _ := range profile { + + if profile[raw].Type == blockchain.ProfileName { + result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: profile[raw].Type, Data: profile[raw].Data[:]})) + } + if profile[raw].Type == blockchain.ProfilePicture { + result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: profile[raw].Type, Data: profile[raw].Data[:]})) + } + } + } + + } else { + fields, status = api.Backend.UserBlockchain.ProfileList() + result.Status = status + for n := range fields { + result.Fields = append(result.Fields, blockRecordProfileToAPI(fields[n])) + } } EncodeJSON(api.Backend, w, r, result) @@ -48,12 +85,13 @@ func (api *WebapiInstance) apiProfileList(w http.ResponseWriter, r *http.Request /* apiProfileRead reads a specific users profile field. See core.ProfileX for recognized fields. -Request: GET /profile/read?field=[index] +Request: GET /profile/read?field=[index]&node=[nodeid] Response: 200 with JSON structure apiProfileData */ func (api *WebapiInstance) apiProfileRead(w http.ResponseWriter, r *http.Request) { r.ParseForm() - fieldN, err1 := strconv.Atoi(r.Form.Get("field")) + fieldN, err1 := strconv.Atoi(r.URL.Query().Get("field")) + NodeID, valid := DecodeBlake3Hash(r.URL.Query().Get("node")) if err1 != nil || fieldN < 0 { http.Error(w, "", http.StatusBadRequest) @@ -61,10 +99,19 @@ func (api *WebapiInstance) apiProfileRead(w http.ResponseWriter, r *http.Request } var result apiProfileData - var data []byte - if data, result.Status = api.Backend.UserBlockchain.ProfileReadField(uint16(fieldN)); result.Status == blockchain.StatusOK { - result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: uint16(fieldN), Data: data})) + + if !valid { + _, node, _ := api.Backend.FindNode(NodeID, 100) + if data, result.Status = node.Backend.UserBlockchain.ProfileReadField(uint16(fieldN)); result.Status == blockchain.StatusOK { + result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: uint16(fieldN), Data: data})) + } + } else { + if api.Backend.NodelistLookup(NodeID) != nil { + if data, result.Status = api.Backend.NodelistLookup(NodeID).Backend.UserBlockchain.ProfileReadField(uint16(fieldN)); result.Status == blockchain.StatusOK { + result.Fields = append(result.Fields, blockRecordProfileToAPI(blockchain.BlockRecordProfile{Type: uint16(fieldN), Data: data})) + } + } } EncodeJSON(api.Backend, w, r, result) @@ -90,6 +137,8 @@ func (api *WebapiInstance) apiProfileWrite(w http.ResponseWriter, r *http.Reques newHeight, newVersion, status := api.Backend.UserBlockchain.ProfileWrite(fields) + api.Backend.LogError("apiProfileWrite", "Height: %v, Version %v", newHeight, newVersion) + EncodeJSON(api.Backend, w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion}) } diff --git a/webapi/Search Dispatch.go b/webapi/Search Dispatch.go index a971446..a7787a9 100644 --- a/webapi/Search Dispatch.go +++ b/webapi/Search Dispatch.go @@ -1,5 +1,5 @@ /* -File Name: Search Dispatch.go +File Username: Search Dispatch.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -9,6 +9,7 @@ package webapi import ( "bytes" "fmt" + "github.com/PeernetOfficial/core/protocol" "time" "github.com/PeernetOfficial/core/blockchain" @@ -43,6 +44,12 @@ func (job *SearchJob) localSearch(api *WebapiInstance, term string) { resultLoop: for _, result := range results { + + // check if the NodeID filter is provided + if job.filtersStart.NodeID != nil && !(bytes.Equal(job.filtersStart.NodeID, protocol.PublicKey2NodeID(result.PublicKey))) { + continue + } + file, _, found, err := api.Backend.ReadFile(result.PublicKey, result.BlockchainVersion, result.BlockNumber, result.FileID) if err != nil || !found { continue diff --git a/webapi/Search Job.go b/webapi/Search Job.go index 1f24435..3d65c1c 100644 --- a/webapi/Search Job.go +++ b/webapi/Search Job.go @@ -1,5 +1,5 @@ /* -File Name: Search Job.go +File Username: Search Job.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -25,6 +25,7 @@ type SearchFilter struct { Sort int // Sort order. See SortX. SizeMin int // Min file size in bytes. -1 = not used. SizeMax int // Max file size in bytes. -1 = not used. + NodeID []byte // Filter based on a NodeID provided } // SearchJob is a collection of search jobs @@ -257,7 +258,7 @@ func (job *SearchJob) isFileFiltered(file *apiFile) bool { return true } -// SortFiles sorts a list of files. It returns a sorted list. 0 = no sorting, 1 = Relevance ASC, 2 = Relevance DESC, 3 = Date ASC, 4 = Date DESC, 5 = Name ASC, 6 = Name DESC +// SortFiles sorts a list of files. It returns a sorted list. 0 = no sorting, 1 = Relevance ASC, 2 = Relevance DESC, 3 = Date ASC, 4 = Date DESC, 5 = Username ASC, 6 = Username DESC func SortFiles(files []*apiFile, Sort int) (sorted []*apiFile) { switch Sort { case SortRelevanceAsc: diff --git a/webapi/Search.go b/webapi/Search.go index d25f2b2..209f71e 100644 --- a/webapi/Search.go +++ b/webapi/Search.go @@ -1,5 +1,5 @@ /* -File Name: Search.go +File Username: Search.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner @@ -156,6 +156,7 @@ 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")) filter := inputToSearchFilter(sort, fileType, fileFormat, dateFrom, dateTo, sizeMin, sizeMax) @@ -353,23 +354,30 @@ func (api *WebapiInstance) apiSearchStatistic(w http.ResponseWriter, r *http.Req apiExplore returns recently shared files 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 /explore?limit=[max records]&type=[file type]&offset=[offset] +Request: GET /explore?limit=[max records]&type=[file type]&offset=[offset]&node=[nodeID] Result: 200 with JSON structure SearchResult. Check the field status. */ func (api *WebapiInstance) apiExplore(w http.ResponseWriter, r *http.Request) { r.ParseForm() - offset, _ := strconv.Atoi(r.Form.Get("offset")) - limit, err := strconv.Atoi(r.Form.Get("limit")) + offset, _ := strconv.Atoi(r.URL.Query().Get("offset")) + limit, err := strconv.Atoi(r.URL.Query().Get("limit")) if err != nil { limit = 100 } - fileType, err := strconv.Atoi(r.Form.Get("type")) + fileType, err := strconv.Atoi(r.URL.Query().Get("type")) if err != nil { fileType = -1 } - result := api.ExploreHelper(fileType, limit, offset, []byte{}, false) + var result *SearchResult + + NodeId, valid := DecodeBlake3Hash(r.URL.Query().Get("node")) + if valid { + result = api.ExploreHelper(fileType, limit, offset, NodeId, true) + } else { + result = api.ExploreHelper(fileType, limit, offset, []byte{}, false) + } EncodeJSON(api.Backend, w, r, result) } @@ -383,7 +391,11 @@ func (api *WebapiInstance) ExploreHelper(fileType int, limit, offset int, nodeID // loop over results for n := range resultFiles { - result.Files = append(result.Files, blockRecordFileToAPI(resultFiles[n])) + ApiFile := blockRecordFileToAPI(resultFiles[n]) + if ApiFile.NodeID == nil { + continue + } + result.Files = append(result.Files, ApiFile) } if len(result.Files) == 0 { @@ -407,6 +419,7 @@ 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) } diff --git a/webapi/Shared Recent.go b/webapi/Shared Recent.go index d7d6eb5..6e35a56 100644 --- a/webapi/Shared Recent.go +++ b/webapi/Shared Recent.go @@ -1,5 +1,5 @@ /* -File Name: Shared Recent.go +File Username: Shared Recent.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -18,7 +18,6 @@ func (api *WebapiInstance) queryRecentShared(backend *core.Backend, fileType int if limitPeer == 0 { limitPeer = 1 } - // Assign peer list as an empty array var peerList []*core.PeerInfo @@ -44,11 +43,31 @@ func (api *WebapiInstance) queryRecentShared(backend *core.Backend, fileType int } var filesFromPeer uint64 + var Name string + + ProfileNameFound := false + + // First iteration of the entire blockchain to search for the profile + // image and Username of the user + for blockN1 := peer.BlockchainHeight - 1; blockN1 > 0; blockN1-- { + blockDecoded, _, found, _ := backend.ReadBlock(peer.PublicKey, peer.BlockchainVersion, blockN1) + if !found { + continue + } + // Adding profile image and Username to the output + for raw := range blockDecoded.Block.RecordsRaw { + if blockDecoded.Block.RecordsRaw[raw].Type == blockchain.ProfileName && !ProfileNameFound { + Name = string(blockDecoded.Block.RecordsRaw[raw].Data[:]) + ProfileNameFound = true + } + } + } // decode blocks from top down blockLoop: for blockN := peer.BlockchainHeight - 1; blockN > 0; blockN-- { blockDecoded, _, found, _ := backend.ReadBlock(peer.PublicKey, peer.BlockchainVersion, blockN) + if !found { continue } @@ -62,6 +81,8 @@ func (api *WebapiInstance) queryRecentShared(backend *core.Backend, fileType int file.Tags = append(file.Tags, blockchain.TagFromText(blockchain.TagSharedByGeoIP, sharedByGeoIP)) } + file.Username = Name + // found a new file! append. if filesFromPeer < limitPeer { filesFromPeer++ diff --git a/webapi/Status.go b/webapi/Status.go index e63735a..37cbdc5 100644 --- a/webapi/Status.go +++ b/webapi/Status.go @@ -1,5 +1,5 @@ /* -File Name: Status.go +File Username: Status.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ diff --git a/webapi/Upload.go b/webapi/Upload.go new file mode 100644 index 0000000..c50cb00 --- /dev/null +++ b/webapi/Upload.go @@ -0,0 +1,86 @@ +package webapi + +import ( + "github.com/google/uuid" + "math" + "net/http" + "sync" +) + +type UploadStatus struct { + APIStatus int `json:"apistatus"` // Status of the API call. See DownloadResponseX. + ID uuid.UUID `json:"id"` // Download ID. This can be used to query the latest status and take actions. + sync.RWMutex // Mutext for changing the status + + UploadStatus int `json:"uploadstatus"` // Status of the download. See DownloadX. + Progress struct { + TotalSize uint64 `json:"totalsize"` // Total size in bytes. + UploadedSize uint64 `json:"uploadedsize"` // Count of bytes download so far. + Percentage float64 `json:"percentage"` // Percentage downloaded. Rounded to 2 decimal points. Between 0.00 and 100.00. + } `json:"progress"` // Progress of the download. Only valid for status >= DownloadWaitSwarm. +} + +func (api *WebapiInstance) uploadAdd(info *UploadStatus) { + api.uploadsMutex.Lock() + api.uploads[info.ID] = info + api.uploadsMutex.Unlock() +} + +func (api *WebapiInstance) uploadDelete(id uuid.UUID) { + api.uploadsMutex.Lock() + delete(api.uploads, id) + api.uploadsMutex.Unlock() +} + +func (api *WebapiInstance) uploadLookup(id uuid.UUID) (info *UploadStatus) { + api.uploadsMutex.Lock() + info = api.uploads[id] + api.uploadsMutex.Unlock() + return info +} + +// UploadID API to set a Status ID to track the upload +func (api *WebapiInstance) apiUploadID(w http.ResponseWriter, r *http.Request) { + var info UploadStatus + info.ID = uuid.New() + + // Create a upload ID for adding the upload + // metadata later one + api.uploadAdd(&info) + + EncodeJSON(api.Backend, w, r, info) +} + +// Write is used to satisfy the io.Writer interface. +// Instead of writing somewhere, it simply aggregates +// the total bytes on each read +func (uploadStatus *UploadStatus) Write(p []byte) (n int, err error) { + n = len(p) + uploadStatus.Progress.UploadedSize += uint64(n) + uploadStatus.Progress.Percentage = math.Round(float64(uploadStatus.Progress.UploadedSize)/float64(uploadStatus.Progress.TotalSize)*100*100) / 100 + return +} + +// Get information about upload file status +func (api *WebapiInstance) apiUploadInfo(w http.ResponseWriter, r *http.Request) { + ID := r.URL.Query().Get("id") + if ID == "" { + api.Backend.LogError("upload.UploadInformation", "error: %v", "ID parameter not passed") + http.Error(w, "", http.StatusBadRequest) + return + } + + IDUUID, err := uuid.Parse(ID) + if err != nil { + api.Backend.LogError("upload.UploadInformation", "error: %v", err) + return + } + + info := api.uploadLookup(IDUUID) + if info == nil { + EncodeJSON(api.Backend, w, r, UploadStatus{APIStatus: DownloadResponseIDNotFound}) + return + } + + EncodeJSON(api.Backend, w, r, info) +} diff --git a/webapi/Warehouse.go b/webapi/Warehouse.go index 95c5c2b..42e7f8c 100644 --- a/webapi/Warehouse.go +++ b/webapi/Warehouse.go @@ -1,5 +1,5 @@ /* -File Name: Warehouse.go +File Username: Warehouse.go Copyright: 2021 Peernet Foundation s.r.o. Author: Peter Kleissner */ @@ -7,6 +7,7 @@ Author: Peter Kleissner package webapi import ( + "github.com/google/uuid" "net/http" "strconv" @@ -20,18 +21,63 @@ type WarehouseResult struct { } /* -apiWarehouseCreateFile creates a file in the warehouse. +ApiWarehouseCreateFile creates a file in the warehouse. Request: POST /warehouse/create with raw data to create as new file Response: 200 with JSON structure WarehouseResult */ -func (api *WebapiInstance) apiWarehouseCreateFile(w http.ResponseWriter, r *http.Request) { - hash, status, err := api.Backend.UserWarehouse.CreateFile(r.Body, 0) +func (api *WebapiInstance) ApiWarehouseCreateFile(w http.ResponseWriter, r *http.Request) { + // changing parameter to take ID as a parameter for upload and file itself + ID := r.FormValue("id") + file, handler, err := r.FormFile("File") + if err != nil { + api.Backend.LogError("warehouse.CreateFile", "error: %v", err) + EncodeJSON(api.Backend, w, r, errorResponse{function: "warehouse.CreateFile", error: err.Error()}) + return + } + + var hash []byte + var status int + + // checks if there is a new upload and then + if ID != "" { + IDUUID, err := uuid.Parse(ID) + if err != nil { + api.Backend.LogError("warehouse.CreateFile", "error: %v", err) + EncodeJSON(api.Backend, w, r, errorResponse{function: "warehouse.CreateFile", error: err.Error()}) + return + } + + info := api.uploadLookup(IDUUID) + if info == nil { + var newInfo UploadStatus + newInfo.ID = IDUUID + newInfo.Progress.TotalSize = uint64(handler.Size) + api.Backend.LogError("warehouse.CreateFile", "%v", newInfo) + api.uploadAdd(&newInfo) + hash, status, err = api.Backend.UserWarehouse.CreateFile(file, uint64(handler.Size), &newInfo) + } else { + info.Progress.TotalSize = uint64(handler.Size) + api.Backend.LogError("warehouse.CreateFile", "%v", info) + hash, status, err = api.Backend.UserWarehouse.CreateFile(file, uint64(handler.Size), info) + } + + api.Backend.LogError("warehouse.CreateFile", "outside Create file: %v", info) + + } else { + // File := r. + hash, status, err = api.Backend.UserWarehouse.CreateFile(file, uint64(handler.Size), nil) + } if err != nil { api.Backend.LogError("warehouse.CreateFile", "status %d error: %v", status, err) + EncodeJSON(api.Backend, w, r, errorResponse{function: "warehouse.CreateFile", error: err.Error()}) + return } + // Temporary log to check the output for warehouse API + api.Backend.LogError("warehouse.CreateFile", "output %v", WarehouseResult{Status: status, Hash: hash}) + EncodeJSON(api.Backend, w, r, WarehouseResult{Status: status, Hash: hash}) } diff --git a/webapi/readme.md b/webapi/readme.md index d591cba..a77d89a 100644 --- a/webapi/readme.md +++ b/webapi/readme.md @@ -75,6 +75,11 @@ These are the functions provided by the API: /merge/directory List all recent files shared by peers based on the similar file shared +/warehouse/create/uploadID Generates a UUID to track upload status +/warehouse/create/track/uploadID Tracks upload status when a upload is + ongoing to the warehaouse (Triggers after + the route "/warehouse/create" is called). + ``` # API Documentation @@ -277,29 +282,30 @@ The file type is an indication what type of content the file's data is: The file format is a more granular indicator about the content of a file: -| Type | Constant | Info | -| ---- | ---------------- | --------------------------------------------------- | -| 0 | FormatBinary | Binary/unspecified | -| 1 | FormatPDF | PDF document | -| 2 | FormatWord | Word document | -| 3 | FormatExcel | Excel | -| 4 | FormatPowerpoint | Powerpoint | -| 5 | FormatPicture | Pictures (including GIF, excluding icons) | -| 6 | FormatAudio | Audio files | -| 7 | FormatVideo | Video files | +| Type | Constant | Info | +|------| ---------------- |----------------------------------------------------| +| 0 | FormatBinary | Binary/unspecified | +| 1 | FormatPDF | PDF document | +| 2 | FormatWord | Word document | +| 3 | FormatExcel | Excel | +| 4 | FormatPowerpoint | Powerpoint | +| 5 | FormatPicture | Pictures (including GIF, excluding icons) | +| 6 | FormatAudio | Audio files | +| 7 | FormatVideo | Video files | | 8 | FormatContainer | Compressed files including ZIP, RAR, TAR and others | -| 9 | FormatHTML | HTML file | -| 10 | FormatText | Text file | -| 11 | FormatEbook | Ebook file | -| 12 | FormatCompressed | Compressed file | -| 13 | FormatDatabase | Database file | -| 14 | FormatEmail | Single email | -| 15 | FormatCSV | CSV file | -| 16 | FormatFolder | Virtual folder | -| 17 | FormatExecutable | Executable file | -| 18 | FormatInstaller | Installer | -| 19 | FormatAPK | APK | -| 20 | FormatISO | ISO | +| 9 | FormatHTML | HTML file | +| 10 | FormatText | Text file | +| 11 | FormatEbook | Ebook file | +| 12 | FormatCompressed | Compressed file | +| 13 | FormatDatabase | Database file | +| 14 | FormatEmail | Single email | +| 15 | FormatCSV | CSV file | +| 16 | FormatFolder | Virtual folder | +| 17 | FormatExecutable | Executable file | +| 18 | FormatInstaller | Installer | +| 19 | FormatAPK | APK | +| 20 | FormatISO | ISO | +| 21 | FormatPeernetSearch | File type to store peernet search history | ### Add File @@ -496,7 +502,7 @@ Below is the list of well known profile information. Clients may define addition This lists all profile fields. ``` -Request: GET /profile/list +Request: GET /profile/list&node=[node id] Response: 200 with JSON structure apiProfileData ``` @@ -538,7 +544,7 @@ Example response: This reads a specific profile field. See ProfileX for recognized fields. ``` -Request: GET /profile/read?field=[index] +Request: GET /profile/read?field=[index]&node=[node id] Response: 200 with JSON structure apiProfileData ``` @@ -617,7 +623,7 @@ Filters and sort order may be applied when starting the search at `/search`, or These are the available sort options: | Sort | Constant | Info | -| ---- | --------------------- | ----------------------------------------------------------------------------------- | +|------|-----------------------|-------------------------------------------------------------------------------------| | 0 | SortNone | No sorting. Results are returned as they come in. | | 1 | SortRelevanceAsc | Least relevant results first. | | 2 | SortRelevanceDec | Most relevant results first. | @@ -630,6 +636,7 @@ These are the available sort options: | 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. | + The following filters are supported: * Filter by date from and to. Both dates are required. The inclusion check for the 'from date' is >= and 'to date' <. @@ -658,6 +665,7 @@ type SearchRequest struct { FileFormat int `json:"fileformat"` // File format such as PDF, Word, Ebook, etc. See core.FormatX. -1 = not used. SizeMin int `json:"sizemin"` // Min file size in bytes. -1 = not used. SizeMax int `json:"sizemax"` // Max file size in bytes. -1 = not used. + NodeID string `json:"node"` // Filter based on the NodeID provided } type SearchRequestResponse struct { @@ -1028,7 +1036,8 @@ type WarehouseResult struct { Example POST request to `http://127.0.0.1:112/warehouse/create`: ``` -Test file. +--form 'id=""' \ +--form 'File=@""' ``` Example response: