diff --git a/mayan/apps/documents/models/document_version_models.py b/mayan/apps/documents/models/document_version_models.py index 873ec1ad07..a982bfd45d 100644 --- a/mayan/apps/documents/models/document_version_models.py +++ b/mayan/apps/documents/models/document_version_models.py @@ -47,8 +47,9 @@ class DocumentVersion(models.Model): document is modified after upload it's checksum will not match, used for detecting file tampering among other things. """ - _pre_open_hooks = {} - _post_save_hooks = {} + _pre_open_hooks = [] + _pre_save_hooks = [] + _post_save_hooks = [] document = models.ForeignKey( on_delete=models.CASCADE, related_name='versions', to=Document, @@ -103,12 +104,38 @@ class DocumentVersion(models.Model): return self.get_rendered_string() @classmethod - def register_pre_open_hook(cls, order, func): - cls._pre_open_hooks[order] = func + def _execute_hooks(cls, hook_list, instance, **kwargs): + result = None + + for hook in hook_list: + result = hook(document_version=instance, **kwargs) + if result: + kwargs.update(result) + + return result @classmethod - def register_post_save_hook(cls, order, func): - cls._post_save_hooks[order] = func + def _insert_hook_entry(cls, hook_list, func, order=None): + order = order or len(hook_list) + hook_list.insert(order, func) + + @classmethod + def register_pre_open_hook(cls, func, order=None): + cls._insert_hook_entry( + hook_list=cls._pre_open_hooks, func=func, order=order + ) + + @classmethod + def register_post_save_hook(cls, func, order=None): + cls._insert_hook_entry( + hook_list=cls._post_save_hooks, func=func, order=order + ) + + @classmethod + def register_pre_save_hook(cls, func, order=None): + cls._insert_hook_entry( + hook_list=cls._pre_save_hooks, func=func, order=order + ) @cached_property def cache(self): @@ -130,6 +157,11 @@ class DocumentVersion(models.Model): return super(DocumentVersion, self).delete(*args, **kwargs) + def execute_pre_save_hooks(self): + DocumentVersion._execute_hooks( + hook_list=DocumentVersion._pre_save_hooks, instance=self + ) + def exists(self): """ Returns a boolean value that indicates if the document's file @@ -231,13 +263,14 @@ class DocumentVersion(models.Model): if raw: return self.file.storage.open(self.file.name) else: - result = self.file.storage.open(self.file.name) - for key in sorted(DocumentVersion._pre_open_hooks): - result = DocumentVersion._pre_open_hooks[key]( - file_object=result, document_version=self - ) + file_object = self.file.storage.open(self.file.name) - return result + result = DocumentVersion._execute_hooks( + hook_list=DocumentVersion._pre_open_hooks, + instance=self, file_object=file_object + ) + + return result['file_object'] @property def page_count(self): @@ -282,12 +315,14 @@ class DocumentVersion(models.Model): try: with transaction.atomic(): + self.execute_pre_save_hooks() + super(DocumentVersion, self).save(*args, **kwargs) - for key in sorted(DocumentVersion._post_save_hooks): - DocumentVersion._post_save_hooks[key]( - document_version=self - ) + DocumentVersion._execute_hooks( + hook_list=DocumentVersion._post_save_hooks, + instance=self + ) if new_document_version: # Only do this for new documents