diff options
author | Kali Kaneko <kali@leap.se> | 2017-05-08 14:13:02 +0200 |
---|---|---|
committer | Kali Kaneko <kali@leap.se> | 2017-05-09 15:18:48 +0200 |
commit | 09c9683cd6888fe7e54cfdd71ada9ace5fdf4fcc (patch) | |
tree | 89aca674958b102e7c2b5b5c5a54bc708a4d4725 /server/src/leap/soledad/server/_blobs.py | |
parent | 3ff522b687dcccd1ada5da5aba526057befec007 (diff) |
[refactor] move interfaces out
- rename add_tag method
- reorder blob interface methods for clarity
- use mkdir_p from leap.common
Diffstat (limited to 'server/src/leap/soledad/server/_blobs.py')
-rw-r--r-- | server/src/leap/soledad/server/_blobs.py | 98 |
1 files changed, 26 insertions, 72 deletions
diff --git a/server/src/leap/soledad/server/_blobs.py b/server/src/leap/soledad/server/_blobs.py index 44abeb44..74707111 100644 --- a/server/src/leap/soledad/server/_blobs.py +++ b/server/src/leap/soledad/server/_blobs.py @@ -36,74 +36,28 @@ from twisted.web.client import FileBodyProducer from twisted.web.server import NOT_DONE_YET from twisted.internet import utils, defer -from zope.interface import Interface, implementer +from zope.interface import implementer + +from leap.common.files import mkdir_p +from leap.soledad.server import interfaces __all__ = ['BlobsResource'] logger = Logger() + # Used for sanitizers, we accept only letters, numbers, '-' and '_' VALID_STRINGS = re.compile('^[a-zA-Z0-9_-]+$') -# TODO some error handling needed -# [ ] sanitize path - # for the future: # [ ] isolate user avatar in a safer way # [ ] catch timeout in the server (and delete incomplete upload) # [ ] chunking (should we do it on the client or on the server?) -class IBlobsBackend(Interface): - - """ - An interface for a BlobsBackend. - """ - - def read_blob(user, blob_id, request): - """ - Read blob with a given blob_id, and write it to the passed request. - - :returns: a deferred that fires upon finishing. - """ - - def list_blobs(user, request): - """ - Returns a json-encoded list of ids from user's blob. - - :returns: a deferred that fires upon finishing. - """ - - def tag_header(user, blob_id, request): - """ - Adds a header 'Tag' with the last 16 bytes of the encoded file, - which contains the tag. - - :returns: a deferred that fires upon finishing. - """ - - def write_blob(user, blob_id, request): - """ - Write blob to the storage, reading it from the passed request. - - :returns: a deferred that fires upon finishing. - """ - - # other stuff for the API - - def delete_blob(user, blob_id): - pass - - def get_blob_size(user, blob_id): - pass - - def get_total_storage(user): - pass - - -@implementer(IBlobsBackend) +@implementer(interfaces.IBlobsBackend) class FilesystemBlobsBackend(object): def __init__(self, blobs_path='/tmp/blobs/', quota=200 * 1024): @@ -112,19 +66,6 @@ class FilesystemBlobsBackend(object): os.makedirs(blobs_path) self.path = blobs_path - def list_blobs(self, user, request): - blob_ids = [] - base_path = self._get_path(user) - for _, _, filenames in os.walk(base_path): - blob_ids += filenames - return json.dumps(blob_ids) - - def tag_header(self, user, blob_id, request): - with open(self._get_path(user, blob_id)) as doc_file: - doc_file.seek(-16, 2) - tag = base64.urlsafe_b64encode(doc_file.read()) - request.responseHeaders.setRawHeaders('Tag', [tag]) - def read_blob(self, user, blob_id, request): logger.info('reading blob: %s - %s' % (user, blob_id)) path = self._get_path(user, blob_id) @@ -136,8 +77,8 @@ class FilesystemBlobsBackend(object): def write_blob(self, user, blob_id, request): path = self._get_path(user, blob_id) try: - os.makedirs(os.path.split(path)[0]) - except: + mkdir_p(os.path.split(path)[0]) + except OSError: pass if os.path.isfile(path): # 409 - Conflict @@ -154,9 +95,6 @@ class FilesystemBlobsBackend(object): fbp = FileBodyProducer(request.content) yield fbp.startProducing(open(path, 'wb')) - def get_total_storage(self, user): - return self._get_disk_usage(self._get_path(user)) - def delete_blob(self, user, blob_id): blob_path = self._get_path(user, blob_id) os.unlink(blob_path) @@ -164,6 +102,22 @@ class FilesystemBlobsBackend(object): def get_blob_size(user, blob_id): raise NotImplementedError + def list_blobs(self, user, request): + blob_ids = [] + base_path = self._get_path(user) + for _, _, filenames in os.walk(base_path): + blob_ids += filenames + return json.dumps(blob_ids) + + def get_total_storage(self, user): + return self._get_disk_usage(self._get_path(user)) + + def add_tag_header(self, user, blob_id, request): + with open(self._get_path(user, blob_id)) as doc_file: + doc_file.seek(-16, 2) + tag = base64.urlsafe_b64encode(doc_file.read()) + request.responseHeaders.setRawHeaders('Tag', [tag]) + @defer.inlineCallbacks def _get_disk_usage(self, start_path): if not os.path.isdir(start_path): @@ -207,7 +161,7 @@ class BlobsResource(resource.Resource): resource.Resource.__init__(self) self._blobs_path = blobs_path self._handler = self.blobsFactoryClass(blobs_path) - assert IBlobsBackend.providedBy(self._handler) + assert interfaces.IBlobsBackend.providedBy(self._handler) # TODO double check credentials, we can have then # under request. @@ -217,7 +171,7 @@ class BlobsResource(resource.Resource): user, blob_id = self._validate(request) if not blob_id: return self._handler.list_blobs(user, request) - self._handler.tag_header(user, blob_id, request) + self._handler.add_tag_header(user, blob_id, request) return self._handler.read_blob(user, blob_id, request) def render_DELETE(self, request): |