summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Shyba <victor1984@riseup.net>2017-03-27 23:54:34 -0300
committerdrebs <drebs@leap.se>2017-04-19 11:37:06 +0200
commit7acbef762be976ab484889f411382e7bd2b8551d (patch)
treeeb25ee0268b6eefee4d342c3a26977f250b19b74
parent3cf6c48549ffb1c713a7b12bbd0cb0e16f49e5e9 (diff)
[feature] fetch new blobs from server
Check what server has, what we have, compare, fetch missing. - Related: #8808
-rw-r--r--client/src/leap/soledad/client/_blobs.py25
-rw-r--r--testing/tests/server/test_blobs_server.py13
2 files changed, 38 insertions, 0 deletions
diff --git a/client/src/leap/soledad/client/_blobs.py b/client/src/leap/soledad/client/_blobs.py
index 14c9ffaa..99ed1678 100644
--- a/client/src/leap/soledad/client/_blobs.py
+++ b/client/src/leap/soledad/client/_blobs.py
@@ -180,6 +180,18 @@ class BlobManager(object):
yield self._encrypt_and_upload(blob_id, fd)
@defer.inlineCallbacks
+ def fetch_missing(self):
+ # TODO: Use something to prioritize user requests over general new docs
+ our_blobs = yield self.local_list()
+ server_blobs = yield self.remote_list()
+ docs_we_want = [b_id for b_id in server_blobs if b_id not in our_blobs]
+ logger.info("Fetching new docs from server: %s" % len(docs_we_want))
+ # TODO: Fetch concurrently when we are able to stream directly into db
+ for blob_id in docs_we_want:
+ logger.info("Fetching new doc: %s" % blob_id)
+ yield self.get(blob_id)
+
+ @defer.inlineCallbacks
def put(self, doc, size):
fd = doc.blob_fd
# TODO this is a tee really, but ok... could do db and upload
@@ -398,6 +410,10 @@ def testit(reactor):
parser_get = subparsers.add_parser(
'send_missing', help='send all pending upload blobs')
+ # parse send_missing command
+ parser_get = subparsers.add_parser(
+ 'fetch_missing', help='fetch all new server blobs')
+
# parse arguments
args = parser.parse_args()
@@ -470,6 +486,13 @@ def testit(reactor):
yield manager.send_missing()
logger.info(":: Finished sending missing docs")
+ @defer.inlineCallbacks
+ def _fetch_missing():
+ logger.info(":: Fetching remote new docs")
+ manager = _manager()
+ yield manager.fetch_missing()
+ logger.info(":: Finished fetching new docs")
+
if args.action == 'upload':
yield _upload(args.blob_id, args.payload)
elif args.action == 'download':
@@ -482,6 +505,8 @@ def testit(reactor):
yield _list()
elif args.action == 'send_missing':
yield _send_missing()
+ elif args.action == 'fetch_missing':
+ yield _fetch_missing()
if __name__ == '__main__':
diff --git a/testing/tests/server/test_blobs_server.py b/testing/tests/server/test_blobs_server.py
index 7aa41956..cf06631b 100644
--- a/testing/tests/server/test_blobs_server.py
+++ b/testing/tests/server/test_blobs_server.py
@@ -83,3 +83,16 @@ class BlobServerTestCase(unittest.TestCase):
result = yield manager._download_and_decrypt(blob_id)
self.assertIsNotNone(result)
self.assertEquals(result[0].getvalue(), "X")
+
+ @defer.inlineCallbacks
+ @pytest.mark.usefixtures("method_tmpdir")
+ def test_fetch_missing(self):
+ manager = BlobManager(self.tempdir, self.uri, self.secret,
+ self.secret, 'user')
+ self.addCleanup(manager.close)
+ blob_id = 'remote_only_blob_id'
+ yield manager._encrypt_and_upload(blob_id, BytesIO("X"))
+ yield manager.fetch_missing()
+ result = yield manager.local.get(blob_id)
+ assert result is not None
+ assert result.getvalue() == "X"