Add hashmap-based download in lib and store utility.
authorAntony Chazapis <chazapis@gmail.com>
Wed, 28 Sep 2011 21:05:12 +0000 (00:05 +0300)
committerAntony Chazapis <chazapis@gmail.com>
Wed, 28 Sep 2011 21:05:12 +0000 (00:05 +0300)
tools/lib/transfer.py
tools/store

index a07240d..cd3548b 100644 (file)
@@ -65,9 +65,35 @@ def upload(client, file, container, prefix):
     
     with open(file) as fp:
         for hash in missing:
-            offset = hashes.index(unhexlify(hash)) * BLOCK_SIZE
+            offset = hashes.index(unhexlify(hash)) * blocksize
             fp.seek(offset)
-            block = fp.read(BLOCK_SIZE)
+            block = fp.read(blocksize)
             client.create_object(container, '.upload', StringIO(block))
     
     client.create_object_by_hashmap(container, object, map)
+
+def download(client, container, object, file):
+    
+    meta = client.retrieve_container_metadata(container)
+    blocksize = int(meta['x-container-block-size'])
+    blockhash = meta['x-container-block-hash']
+    
+    if os.path.isfile(file):
+        size = os.path.getsize(file)
+        hashes = HashMap(blocksize, blockhash)
+        hashes.load(file)
+    else:
+        size = 0
+        hashes = []
+    
+    map = client.retrieve_object_hashmap(container, object)
+    
+    with open(file, 'a') as fp:
+        for i, h in enumerate(map):
+            if i < len(hashes) and h == hashes[i]:
+                continue
+            start = i * blocksize
+            end = '' if i == len(map) - 1 else (i + 1) * blocksize
+            data = client.retrieve_object(container, object, range='bytes=%s-%s' % (start, end))
+            fp.seek(start)
+            fp.write(data)
index e3dd03a..9e3ab27 100755 (executable)
@@ -40,7 +40,7 @@ from sys import argv, exit, stdin, stdout
 from datetime import datetime
 from lib.client import Pithos_Client, Fault
 from lib.util import get_user, get_auth, get_server, get_api
-from lib.transfer import upload
+from lib.transfer import upload, download
 
 import json
 import logging
@@ -204,7 +204,7 @@ class Meta(Command):
     
     def execute(self, path=''):
         container, sep, object = path.partition('/')
-        args = {'restricted':self.restricted}
+        args = {'restricted': self.restricted}
         if getattr(self, 'until'):
             t = _time.strptime(self.until, self.format)
             args['until'] = int(_time.mktime(t))
@@ -299,7 +299,7 @@ class GetObject(Command):
         args = self._build_args(attrs)
         args['format'] = 'json' if self.detail else 'text'
         if self.range:
-            args['range'] = 'bytes=%s' %self.range
+            args['range'] = 'bytes=%s' % self.range
         if getattr(self, 'if_range'):
             args['if-range'] = 'If-Range:%s' % getattr(self, 'if_range')
         
@@ -690,11 +690,20 @@ class SharingObject(Command):
 class Send(Command):
     syntax = '<file> <container>[/<prefix>]'
     description = 'upload file to container (using prefix)'
-        
-    def execute(self, file, prefix):
-        container, sep, prefix = prefix.partition('/')
+    
+    def execute(self, file, path):
+        container, sep, prefix = path.partition('/')
         upload(self.client, file, container, prefix)
 
+@cli_command('receive')
+class Receive(Command):
+    syntax = '<container>/<object> <file>'
+    description = 'download object to file'
+    
+    def execute(self, path, file):
+        container, sep, object = path.partition('/')
+        download(self.client, container, object, file)
+
 def print_usage():
     cmd = Command('', [])
     parser = cmd.parser