Recalculate a document's indexes when attaching or removing a tag from or to it. Recalculate all of a tag's documents when a tag is about to be deleted.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
Roberto Rosario
2018-06-13 01:26:58 -04:00
parent 66e53bac22
commit 9dfe187202
6 changed files with 131 additions and 0 deletions

View File

@@ -176,6 +176,8 @@
- Don't provide a default for the scanner source adf_mode. Some scanners throw an error even when the selection
if supported.
- Add a "Quick Download" action to reduce the number of steps to download a single document. GitLab issue #338.
- Recalculate a document's indexes when attaching or removing a tag from or to it.
- Recalculate all of a tag's documents when a tag is about to be deleted.
2.7.3 (2017-09-11)
==================

View File

@@ -522,6 +522,8 @@ Other changes worth mentioning
- Don't provide a default for the scanner source adf_mode. Some scanners throw an error even when the selection
if supported.
- Add a "Quick Download" action to reduce the number of steps to download a single document. GitLab issue #338.
- Recalculate a document's indexes when attaching or removing a tag from or to it.
- Recalculate all of a tag's documents when a tag is about to be deleted.
Removals
--------

View File

@@ -1,6 +1,7 @@
from __future__ import unicode_literals
from django.apps import apps
from django.db.models.signals import m2m_changed, pre_delete
from django.utils.translation import ugettext_lazy as _
from acls import ModelPermission
@@ -13,6 +14,7 @@ from common import (
from documents.search import document_page_search, document_search
from navigation import SourceColumn
from .handlers import handler_index_document, handler_tag_pre_delete
from .links import (
link_multiple_documents_attach_tag, link_multiple_documents_tag_remove,
link_single_document_multiple_tag_remove, link_tag_attach, link_tag_create,
@@ -149,3 +151,17 @@ class TagsApp(MayanAppConfig):
)
)
registry.register(Tag)
# Index update
m2m_changed.connect(
handler_index_document,
dispatch_uid='tags_handler_index_document',
sender=Tag.documents.through
)
pre_delete.connect(
handler_tag_pre_delete,
dispatch_uid='tags_handler_tag_pre_delete',
sender=Tag
)

View File

@@ -0,0 +1,21 @@
from __future__ import unicode_literals
import logging
from document_indexing.tasks import task_index_document
logger = logging.getLogger(__name__)
def handler_index_document(sender, **kwargs):
if kwargs['action'] in ('post_add', 'post_remove'):
for pk in kwargs['pk_set']:
task_index_document.apply_async(kwargs=dict(document_id=pk))
def handler_tag_pre_delete(sender, **kwargs):
for document in kwargs['instance'].documents.all():
# Remove each of the documents from the tag
# Trigger the m2m_changed signal for each document so they can be
# reindexed
kwargs['instance'].documents.remove(document)

View File

@@ -4,3 +4,20 @@ TEST_TAG_LABEL = 'test-tag'
TEST_TAG_LABEL_EDITED = 'test-tag-edited'
TEST_TAG_COLOR = '#001122'
TEST_TAG_COLOR_EDITED = '#221100'
TEST_TAG_INDEX_HAS_TAG = 'HAS_TAG'
TEST_TAG_INDEX_NO_TAG = 'NO_TAG'
TEST_TAG_INDEX_NODE_TEMPLATE = '''
{{% for tag in document.tags.all %}}
{{% if tag.label == "{}" %}}
{}
{{% else %}}
NO_TAG
{{% endif %}}
{{% empty %}}
NO_TAG
{{% endfor %}}
'''.format(
TEST_TAG_LABEL, TEST_TAG_INDEX_HAS_TAG, TEST_TAG_INDEX_NO_TAG,
TEST_TAG_INDEX_NO_TAG
).replace('\n', '')

View File

@@ -0,0 +1,73 @@
from __future__ import unicode_literals
from django.core.files.base import File
from django.test import override_settings
from common.tests import BaseTestCase
from documents.models import DocumentType
from documents.tests import TEST_DOCUMENT_TYPE_LABEL, TEST_SMALL_DOCUMENT_PATH
from document_indexing.models import Index, IndexInstanceNode
from document_indexing.tests.literals import TEST_INDEX_LABEL
from ..models import Tag
from .literals import (
TEST_TAG_COLOR, TEST_TAG_LABEL, TEST_TAG_INDEX_HAS_TAG,
TEST_TAG_INDEX_NO_TAG, TEST_TAG_INDEX_NODE_TEMPLATE
)
@override_settings(OCR_AUTO_OCR=False)
class TagSignalIndexingTestCase(BaseTestCase):
def setUp(self):
super(TagSignalIndexingTestCase, self).setUp()
self.document_type = DocumentType.objects.create(
label=TEST_DOCUMENT_TYPE_LABEL
)
def tearDown(self):
self.document.delete()
self.document_type.delete()
super(TagSignalIndexingTestCase, self).tearDown()
def _create_document(self):
with open(TEST_SMALL_DOCUMENT_PATH) as file_object:
self.document = self.document_type.new_document(
file_object=File(file_object)
)
def test_tag_indexing(self):
index = Index.objects.create(label=TEST_INDEX_LABEL)
index.document_types.add(self.document_type)
root = index.template_root
index.node_templates.create(
parent=root, expression=TEST_TAG_INDEX_NODE_TEMPLATE,
link_documents=True
)
tag = Tag.objects.create(color=TEST_TAG_COLOR, label=TEST_TAG_LABEL)
self._create_document()
self.assertTrue(
self.document in IndexInstanceNode.objects.get(
value=TEST_TAG_INDEX_NO_TAG
).documents.all()
)
tag.documents.add(self.document)
self.assertTrue(
self.document in IndexInstanceNode.objects.get(
value=TEST_TAG_INDEX_HAS_TAG
).documents.all()
)
tag.delete()
self.assertTrue(
self.document in IndexInstanceNode.objects.get(
value=TEST_TAG_INDEX_NO_TAG
).documents.all()
)