[infrae.fileupload][Sylvain Viollon] Make code less spaghetti.
[email protected] Wed, 25 Sep 2013 12:08:23 +0200
| Newsgroups | gmane.comp.web.zope.silva.cvs |
|---|---|
| Message-ID | <[email protected]> |
author: Sylvain Viollon
date: Wed Sep 25 12:08:18 2013 +0200
revision: 23:afc9b945459c in infrae.fileupload
branch:
details: https://hg.infrae.com/infrae.fileupload?cmd=changeset;node=afc9b945459c
modified: src/infrae/fileupload/middleware.py
added:
removed:
log: Make code less spaghetti.
diffstat:
src/infrae/fileupload/middleware.py | 50 ++++++++++++++++++++++--------------
1 files changed, 31 insertions(+), 19 deletions(-)
diffs (142 lines):
diff -r 91e201463abc -r afc9b945459c src/infrae/fileupload/middleware.py
--- a/src/infrae/fileupload/middleware.py Fri Aug 23 16:14:58 2013 +0200
+++ b/src/infrae/fileupload/middleware.py Wed Sep 25 12:08:18 2013 +0200
@@ -184,8 +184,10 @@
self._api = api
self._status = None
- def get_status(self):
- if self._status is not None:
+ def get_status(self, refresh=False):
+ """Return the status of the upload.
+ """
+ if not refresh and self._status is not None:
return self._status
status = None
with open(self._metadata, 'rb') as stream:
@@ -207,20 +209,23 @@
return status
def get_filename(self):
+ """Return the filename of the upload.
+ """
if self.is_complete():
return self._data
return None
- def clear(self):
+ def clear_upload(self):
# This is called by the middleware if the upload fails.
path = os.path.join(self._api._directory, self._identifier)
with self._api._get_lock():
if os.path.isdir(path):
shutil.rmtree(path)
-
def is_complete(self):
- status = self.get_status()
+ """Return true if the upload is done.
+ """
+ status = self.get_status(refresh=True)
if status is not None:
return status.get('state', 'unknown') == 'done'
return False
@@ -239,7 +244,7 @@
descriptor = open(filename, 'wb')
if payload:
descriptor.write(payload)
- descriptor.flush()
+ descriptor.flush() # Make sure the file is created on the FS
return descriptor
@@ -250,6 +255,7 @@
def __init__(self, api, identifier, directory,
filename, content_type, content_length):
super(UploadFileBucket, self).__init__(api, identifier, directory)
+ self._finished = False
self._length = content_length
self._metadata_descriptor = open_data(
self._metadata,
@@ -261,16 +267,21 @@
self._done_descriptor = open_data(self._done, '0')
self._data_descriptor = open_data(self._data)
- def metadata(self, finished=False, error=None):
- status = self.get_status()
- if finished:
- status['state'] = 'done'
+ def finish_upload(self, error=None):
+ if self._metadata_descriptor is None:
+ logger.error('Error while closing the upload (already closed).')
+ return
+ status = self.get_status(refresh=True)
if error:
status['state'] = 'error'
status['error'] = error
+ elif self._finished:
+ status['state'] = 'done'
self._metadata_descriptor.seek(0)
self._metadata_descriptor.write(json.dumps(status))
self._metadata_descriptor.flush()
+ self._metadata_descriptor.close()
+ self._metadata_descriptor = None
self._status = None
def progress(self):
@@ -280,12 +291,11 @@
read = yield
except GeneratorExit:
# Reload and save metadata.
- self.metadata(finished=(total == self._length))
- self._metadata_descriptor.close()
self._done_descriptor.close()
- self._status = None
+ self._done_descriptor = None
raise StopIteration
total += read
+ self._finished = total == self._length
self._done_descriptor.seek(0)
self._done_descriptor.write(str(total))
self._done_descriptor.flush()
@@ -296,6 +306,7 @@
block = yield
except GeneratorExit:
self._data_descriptor.close()
+ self._data_descriptor = None
raise StopIteration
if isinstance(block, str):
self._data_descriptor.write(block)
@@ -459,17 +470,18 @@
if upload is None:
upload = self.manager.create_upload_bucket(
identifier, '', 'n/a', '0')
- upload.metadata(error=error.msg)
+ upload.finish_upload(error=error.msg)
+ return exc.HTTPServerError(error.msg)
+ else:
+ upload.finish_upload()
+ finally:
if output_stream is not None:
output_stream.close()
if track_progress is not None:
track_progress.close()
- return exc.HTTPServerError(error.msg)
# We are done uploading
- output_stream.close()
- track_progress.close()
- logger.debug('%s: Upload done, file closed', identifier)
+ logger.debug('%s: Upload done, file closed.', identifier)
# Get the response from the application
info = json.dumps(upload.get_status())
@@ -486,7 +498,7 @@
try:
upload = self.manager.access_upload_bucket(identifier)
if upload is not None:
- upload.clear()
+ upload.clear_upload()
except UploadError:
result = '{"success": false, "error": "Upload server error"}'
else: