implemented Api.Download

This commit is contained in:
zsfelfoldi 2015-06-02 19:21:29 +02:00
parent 2f404edffc
commit 26cefefbfd
3 changed files with 96 additions and 6 deletions

View file

@ -1,6 +1,7 @@
package bzz
import (
"bufio"
"bytes"
"fmt"
"io"
@ -179,8 +180,62 @@ func (self *Api) Modify(rootHash, path, contentHash, contentType string) (newRoo
// Download replicates the manifest path structure on the local filesystem
// under localpath
func (self *Api) Download(bzzpath, localpath string) (string, error) {
return "", nil
func (self *Api) Download(bzzpath, localpath string) (err error) {
lpath, err := filepath.Abs(filepath.Clean(localpath))
if err != nil {
return
}
err = os.MkdirAll(lpath, os.ModePerm)
if err != nil {
return
}
parts := slashes.Split(bzzpath, 3)
if len(parts) < 2 {
return fmt.Errorf("Invalid bzz path")
}
hostPort := parts[1]
var path string
if len(parts) > 2 {
path = regularSlashes(parts[2]) + "/"
}
dpaLogger.Debugf("Swarm: host: '%s', path '%s' requested.", hostPort, path)
//resolving host and port
var key Key
key, err = self.Resolve(hostPort)
if err != nil {
err = errResolve(err)
dpaLogger.Debugf("Swarm: error : %v", err)
return
}
trie, err := loadManifest(self.dpa, key)
if err != nil {
dpaLogger.Debugf("Swarm: loadManifestTrie error: %v", err)
return
}
prevPath := lpath
trie.listWithPrefix(path, func(entry *manifestTrieEntry, suffix string) { // TODO: paralellize
key := common.Hex2Bytes(entry.Hash)
reader := self.dpa.Retrieve(key)
path := lpath + "/" + suffix
dir := filepath.Dir(path)
if dir != prevPath {
os.MkdirAll(dir, os.ModePerm) // TODO: handle errors
prevPath = dir
}
f, _ := os.Create(path) // TODO: handle errors, ??path separators
writer := bufio.NewWriter(f)
//io.Copy(writer, reader) // TODO: handle errors
io.CopyN(writer, reader, reader.Size()) // TODO: handle errors
writer.Flush()
f.Close()
})
return
}
const maxParallelFiles = 5

View file

@ -159,7 +159,7 @@ func (self *JSApi) download(call otto.FunctionCall) otto.Value {
}
var err error
var bzzpath, localpath, res string
var bzzpath, localpath string
bzzpath, err = call.Argument(0).ToString()
if err != nil {
fmt.Println(err)
@ -171,14 +171,13 @@ func (self *JSApi) download(call otto.FunctionCall) otto.Value {
return otto.UndefinedValue()
}
res, err = self.api.Download(bzzpath, localpath)
err = self.api.Download(bzzpath, localpath)
if err != nil {
fmt.Println(err)
return otto.UndefinedValue()
}
v, _ := call.Otto.ToValue(res)
return v
return otto.UndefinedValue()
}
func (self *JSApi) upload(call otto.FunctionCall) otto.Value {

View file

@ -209,6 +209,42 @@ func (self *manifestTrie) loadSubTrie(entry *manifestTrieEntry) (err error) {
return
}
func (self *manifestTrie) listWithPrefixInt(prefix, rp string, cb func(entry *manifestTrieEntry, suffix string)) {
plen := len(prefix)
var start, stop int
if plen == 0 {
start = 0
stop = 256
} else {
start = int(prefix[0])
stop = start
}
for i := start; i <= stop; i++ {
entry := self.entries[i]
if entry != nil {
epl := len(entry.Path)
if entry.ContentType == manifestType {
l := plen
if epl < l {
l = epl
}
if (prefix[:l] == entry.Path[:l]) && (self.loadSubTrie(entry) == nil) { // TODO: handle errors
entry.subtrie.listWithPrefixInt(prefix[l:], rp+entry.Path[l:], cb)
}
} else {
if (epl >= plen) && (prefix == entry.Path[:plen]) {
cb(entry, rp+entry.Path[plen:])
}
}
}
}
}
func (self *manifestTrie) listWithPrefix(prefix string, cb func(entry *manifestTrieEntry, suffix string)) {
self.listWithPrefixInt(prefix, "", cb)
}
func (self *manifestTrie) findPrefixOf(path string) (entry *manifestTrieEntry, pos int) {
dpaLogger.Debugf("findPrefixOf(%s)", path)