summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Shyba <victor1984@riseup.net>2017-07-07 02:32:36 -0300
committerdrebs <drebs@leap.se>2017-07-18 15:30:30 -0300
commit679e1bb7990fc1fc9c4971db6383a75ae6acab80 (patch)
tree22e48ea737a95f0433ac217915d31e2ec5ffa00d
parent463073b3147f9ba4e784e92cc8bec1d74ab0b7f4 (diff)
[feature] remote list sorting by date
Listing by date is useful for listing newest/oldest documents on blobs storage and should be used for listing new IncomingMessages as described on specification. -- Resolves: #8879
-rw-r--r--src/leap/soledad/client/_db/blobs.py4
-rw-r--r--src/leap/soledad/server/_blobs.py14
-rw-r--r--testing/tests/blobs/test_fs_backend.py4
-rw-r--r--testing/tests/server/test_blobs_server.py21
4 files changed, 35 insertions, 8 deletions
diff --git a/src/leap/soledad/client/_db/blobs.py b/src/leap/soledad/client/_db/blobs.py
index 10b90c71..8f9f4769 100644
--- a/src/leap/soledad/client/_db/blobs.py
+++ b/src/leap/soledad/client/_db/blobs.py
@@ -167,9 +167,9 @@ class BlobManager(object):
return self.local.close()
@defer.inlineCallbacks
- def remote_list(self):
+ def remote_list(self, **params):
uri = urljoin(self.remote, self.user + '/')
- data = yield self._client.get(uri)
+ data = yield self._client.get(uri, params=params)
defer.returnValue((yield data.json()))
def local_list(self):
diff --git a/src/leap/soledad/server/_blobs.py b/src/leap/soledad/server/_blobs.py
index f6a8cbc6..793149cd 100644
--- a/src/leap/soledad/server/_blobs.py
+++ b/src/leap/soledad/server/_blobs.py
@@ -102,11 +102,16 @@ class FilesystemBlobsBackend(object):
def get_blob_size(user, blob_id, namespace=''):
raise NotImplementedError
- def list_blobs(self, user, request, namespace=''):
+ def list_blobs(self, user, request, namespace='', order_by=None):
blob_ids = []
base_path = self._get_path(user, custom_preffix=namespace)
- for _, _, filenames in os.walk(base_path):
- blob_ids += filenames
+ for root, dirs, filenames in os.walk(base_path):
+ blob_ids += [os.path.join(root, name) for name in filenames]
+ if order_by in ['date', '+date']:
+ blob_ids.sort(key=lambda x: os.path.getmtime(x))
+ elif order_by == '-date':
+ blob_ids.sort(key=lambda x: os.path.getmtime(x), reverse=True)
+ blob_ids = [os.path.basename(path) for path in blob_ids]
return json.dumps(blob_ids)
def get_total_storage(self, user):
@@ -181,7 +186,8 @@ class BlobsResource(resource.Resource):
logger.info("http get: %s" % request.path)
user, blob_id = self._validate(request)
if not blob_id:
- return self._handler.list_blobs(user, request)
+ order = request.args.get('order_by', [None])[0]
+ return self._handler.list_blobs(user, request, order_by=order)
self._handler.add_tag_header(user, blob_id, request)
return self._handler.read_blob(user, blob_id, request)
diff --git a/testing/tests/blobs/test_fs_backend.py b/testing/tests/blobs/test_fs_backend.py
index 7fce4cfe..a6d7272d 100644
--- a/testing/tests/blobs/test_fs_backend.py
+++ b/testing/tests/blobs/test_fs_backend.py
@@ -106,7 +106,7 @@ class FilesystemBackendTestCase(unittest.TestCase):
@mock.patch('leap.soledad.server._blobs.os.walk')
def test_list_blobs(self, walk_mock):
backend, _ = _blobs.FilesystemBlobsBackend(self.tempdir), None
- walk_mock.return_value = [(_, _, ['blob_0']), (_, _, ['blob_1'])]
+ walk_mock.return_value = [('', _, ['blob_0']), ('', _, ['blob_1'])]
result = json.loads(backend.list_blobs('user', DummyRequest([''])))
self.assertEquals(result, ['blob_0', 'blob_1'])
@@ -114,7 +114,7 @@ class FilesystemBackendTestCase(unittest.TestCase):
@mock.patch('leap.soledad.server._blobs.os.walk')
def test_list_blobs_limited_by_namespace(self, walk_mock):
backend, _ = _blobs.FilesystemBlobsBackend(self.tempdir), None
- walk_mock.return_value = [(_, _, ['blob_0']), (_, _, ['blob_1'])]
+ walk_mock.return_value = [('', _, ['blob_0']), ('', _, ['blob_1'])]
result = json.loads(backend.list_blobs('user', DummyRequest(['']),
namespace='incoming'))
self.assertEquals(result, ['blob_0', 'blob_1'])
diff --git a/testing/tests/server/test_blobs_server.py b/testing/tests/server/test_blobs_server.py
index 36bd3f0a..bbb1b6d5 100644
--- a/testing/tests/server/test_blobs_server.py
+++ b/testing/tests/server/test_blobs_server.py
@@ -17,6 +17,7 @@
"""
Integration tests for blobs server
"""
+import os
import pytest
from io import BytesIO
from twisted.trial import unittest
@@ -66,6 +67,26 @@ class BlobServerTestCase(unittest.TestCase):
@defer.inlineCallbacks
@pytest.mark.usefixtures("method_tmpdir")
+ def test_list_orders_by_date(self):
+ manager = BlobManager('', self.uri, self.secret,
+ self.secret, 'user')
+ yield manager._encrypt_and_upload('blob_id1', BytesIO("1"))
+ yield manager._encrypt_and_upload('blob_id2', BytesIO("2"))
+ blobs_list = yield manager.remote_list(order_by='date')
+ self.assertEquals(['blob_id1', 'blob_id2'], blobs_list)
+ self.__touch(self.tempdir, 'user', 'b', 'blo', 'blob_i', 'blob_id1')
+ blobs_list = yield manager.remote_list(order_by='+date')
+ self.assertEquals(['blob_id2', 'blob_id1'], blobs_list)
+ blobs_list = yield manager.remote_list(order_by='-date')
+ self.assertEquals(['blob_id1', 'blob_id2'], blobs_list)
+
+ def __touch(self, *args):
+ path = os.path.join(*args)
+ with open(path, 'a'):
+ os.utime(path, None)
+
+ @defer.inlineCallbacks
+ @pytest.mark.usefixtures("method_tmpdir")
def test_upload_deny_duplicates(self):
manager = BlobManager('', self.uri, self.secret,
self.secret, 'user')