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:
@@ -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)
|
||||
==================
|
||||
|
||||
@@ -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
|
||||
--------
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
21
mayan/apps/tags/handlers.py
Normal file
21
mayan/apps/tags/handlers.py
Normal 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)
|
||||
@@ -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', '')
|
||||
|
||||
73
mayan/apps/tags/tests/test_indexing.py
Normal file
73
mayan/apps/tags/tests/test_indexing.py
Normal 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()
|
||||
)
|
||||
Reference in New Issue
Block a user