diff --git a/HISTORY.rst b/HISTORY.rst index c60dcfa746..dc473e2b00 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,6 +2,7 @@ ================== * Add support for disabling the random primary key test mixin. +* Add a reusable task to upload documents. 3.2.2 (2019-06-19) ================== diff --git a/mayan/apps/documents/literals.py b/mayan/apps/documents/literals.py index c56f92d39b..0ae213fac4 100644 --- a/mayan/apps/documents/literals.py +++ b/mayan/apps/documents/literals.py @@ -32,6 +32,7 @@ DEFAULT_DOCUMENT_TYPE_LABEL = _('Default') DOCUMENT_IMAGE_TASK_TIMEOUT = 120 STUB_EXPIRATION_INTERVAL = 60 * 60 * 24 # 24 hours UPDATE_PAGE_COUNT_RETRY_DELAY = 10 +UPLOAD_NEW_DOCUMENT_RETRY_DELAY = 10 UPLOAD_NEW_VERSION_RETRY_DELAY = 10 PAGE_RANGE_ALL = 'all' diff --git a/mayan/apps/documents/queues.py b/mayan/apps/documents/queues.py index 57f4c4b32a..50840203c5 100644 --- a/mayan/apps/documents/queues.py +++ b/mayan/apps/documents/queues.py @@ -82,3 +82,7 @@ queue_uploads.add_task_type( dotted_path='mayan.apps.documents.tasks.task_scan_duplicates_for', label=_('Scan document duplicates') ) +queue_uploads.add_task_type( + dotted_path='mayan.apps.documents.tasks.task_upload_new_document', + label=_('Upload new document') +) diff --git a/mayan/apps/documents/tasks.py b/mayan/apps/documents/tasks.py index 857eb38e66..f161fc7973 100644 --- a/mayan/apps/documents/tasks.py +++ b/mayan/apps/documents/tasks.py @@ -9,7 +9,8 @@ from django.db import OperationalError from mayan.celery import app from .literals import ( - UPDATE_PAGE_COUNT_RETRY_DELAY, UPLOAD_NEW_VERSION_RETRY_DELAY + UPDATE_PAGE_COUNT_RETRY_DELAY, UPLOAD_NEW_DOCUMENT_RETRY_DELAY, + UPLOAD_NEW_VERSION_RETRY_DELAY ) logger = logging.getLogger(__name__) @@ -127,6 +128,60 @@ def task_update_page_count(self, version_id): raise self.retry(exc=exception) +@app.task(bind=True, default_retry_delay=UPLOAD_NEW_DOCUMENT_RETRY_DELAY, ignore_result=True) +def task_upload_new_document(self, document_type_id, shared_uploaded_file_id): + DocumentType = apps.get_model( + app_label='documents', model_name='DocumentType' + ) + + SharedUploadedFile = apps.get_model( + app_label='common', model_name='SharedUploadedFile' + ) + + try: + document_type = DocumentType.objects.get(pk=document_type_id) + shared_file = SharedUploadedFile.objects.get( + pk=shared_uploaded_file_id + ) + except OperationalError as exception: + logger.warning( + 'Operational error during attempt to retrieve shared data for ' + 'new document of type: %s; %s. Retrying.', document_type, exception + ) + raise self.retry(exc=exception) + + try: + with shared_file.open() as file_object: + document_type.new_document(file_object=file_object) + except OperationalError as exception: + logger.warning( + 'Operational error during attempt to create new document ' + 'of type: %s; %s. Retrying.', document_type, exception + ) + raise self.retry(exc=exception) + except Exception as exception: + # This except and else block emulate a finally: + logger.error( + 'Unexpected error during attempt to create new document ' + 'of type: %s; %s', document_type, exception + ) + try: + shared_file.delete() + except OperationalError as exception: + logger.warning( + 'Operational error during attempt to delete shared ' + 'file: %s; %s.', shared_file, exception + ) + else: + try: + shared_file.delete() + except OperationalError as exception: + logger.warning( + 'Operational error during attempt to delete shared ' + 'file: %s; %s.', shared_file, exception + ) + + @app.task(bind=True, default_retry_delay=UPLOAD_NEW_VERSION_RETRY_DELAY, ignore_result=True) def task_upload_new_version(self, document_id, shared_uploaded_file_id, user_id, comment=None): SharedUploadedFile = apps.get_model(