✨(backend) refactor indexation signals and fix circular import issues
Signed-off-by: Fabre Florian <ffabre@hybird.org>
This commit is contained in:
committed by
Quentin BEY
parent
24460ffc3a
commit
bf978b5376
@@ -9,6 +9,9 @@ and this project adheres to
|
||||
### Added
|
||||
|
||||
- ✨(backend) allow to create a new user in a marketing system
|
||||
- ✨(backend) add async indexation of documents on save (or access save) #1276
|
||||
- ✨(backend) add debounce mechanism to limit indexation jobs #1276
|
||||
- ✨(api) add API route to search for indexed documents in Find #1276
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
"""Impress Core application"""
|
||||
# from django.apps import AppConfig
|
||||
# from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django.apps import AppConfig
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
# class CoreConfig(AppConfig):
|
||||
# """Configuration class for the impress core app."""
|
||||
class CoreConfig(AppConfig):
|
||||
"""Configuration class for the impress core app."""
|
||||
|
||||
# name = "core"
|
||||
# app_label = "core"
|
||||
# verbose_name = _("impress core application")
|
||||
name = "core"
|
||||
app_label = "core"
|
||||
verbose_name = _("Impress core application")
|
||||
|
||||
def ready(self):
|
||||
"""
|
||||
Import signals when the app is ready.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel, unused-import
|
||||
from . import signals # noqa: PLC0415
|
||||
|
||||
@@ -20,9 +20,7 @@ from django.core.files.base import ContentFile
|
||||
from django.core.files.storage import default_storage
|
||||
from django.core.mail import send_mail
|
||||
from django.db import models, transaction
|
||||
from django.db.models import signals
|
||||
from django.db.models.functions import Left, Length
|
||||
from django.dispatch import receiver
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils import timezone
|
||||
from django.utils.functional import cached_property
|
||||
@@ -41,7 +39,6 @@ from .choices import (
|
||||
RoleChoices,
|
||||
get_equivalent_link_definition,
|
||||
)
|
||||
from .tasks.find import trigger_document_indexer
|
||||
from .validators import sub_validator
|
||||
|
||||
logger = getLogger(__name__)
|
||||
@@ -955,16 +952,6 @@ class Document(MP_Node, BaseModel):
|
||||
)
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=Document)
|
||||
def document_post_save(sender, instance, **kwargs): # pylint: disable=unused-argument
|
||||
"""
|
||||
Asynchronous call to the document indexer at the end of the transaction.
|
||||
Note : Within the transaction we can have an empty content and a serialization
|
||||
error.
|
||||
"""
|
||||
trigger_document_indexer(instance, on_commit=True)
|
||||
|
||||
|
||||
class LinkTrace(BaseModel):
|
||||
"""
|
||||
Relation model to trace accesses to a document via a link by a logged-in user.
|
||||
@@ -1195,15 +1182,6 @@ class DocumentAccess(BaseAccess):
|
||||
}
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=DocumentAccess)
|
||||
def document_access_post_save(sender, instance, created, **kwargs): # pylint: disable=unused-argument
|
||||
"""
|
||||
Asynchronous call to the document indexer at the end of the transaction.
|
||||
"""
|
||||
if not created:
|
||||
trigger_document_indexer(instance.document, on_commit=True)
|
||||
|
||||
|
||||
class DocumentAskForAccess(BaseModel):
|
||||
"""Relation model to ask for access to a document."""
|
||||
|
||||
|
||||
28
src/backend/core/signals.py
Normal file
28
src/backend/core/signals.py
Normal file
@@ -0,0 +1,28 @@
|
||||
"""
|
||||
Declare and configure the signals for the impress core application
|
||||
"""
|
||||
|
||||
from django.db.models import signals
|
||||
from django.dispatch import receiver
|
||||
|
||||
from . import models
|
||||
from .tasks.find import trigger_document_indexer
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=models.Document)
|
||||
def document_post_save(sender, instance, **kwargs): # pylint: disable=unused-argument
|
||||
"""
|
||||
Asynchronous call to the document indexer at the end of the transaction.
|
||||
Note : Within the transaction we can have an empty content and a serialization
|
||||
error.
|
||||
"""
|
||||
trigger_document_indexer(instance, on_commit=True)
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=models.DocumentAccess)
|
||||
def document_access_post_save(sender, instance, created, **kwargs): # pylint: disable=unused-argument
|
||||
"""
|
||||
Asynchronous call to the document indexer at the end of the transaction.
|
||||
"""
|
||||
if not created:
|
||||
trigger_document_indexer(instance.document, on_commit=True)
|
||||
@@ -7,12 +7,6 @@ from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.db import transaction
|
||||
|
||||
from core import models
|
||||
from core.services.search_indexers import (
|
||||
get_batch_accesses_by_users_and_teams,
|
||||
get_document_indexer_class,
|
||||
)
|
||||
|
||||
from impress.celery_app import app
|
||||
|
||||
logger = getLogger(__file__)
|
||||
@@ -52,6 +46,13 @@ def document_indexer_task(document_id):
|
||||
logger.info("Skip document %s indexation", document_id)
|
||||
return
|
||||
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from core import models # noqa: PLC0415
|
||||
from core.services.search_indexers import ( # noqa: PLC0415
|
||||
get_batch_accesses_by_users_and_teams,
|
||||
get_document_indexer_class,
|
||||
)
|
||||
|
||||
doc = models.Document.objects.get(pk=document_id)
|
||||
indexer = get_document_indexer_class()()
|
||||
accesses = get_batch_accesses_by_users_and_teams((doc.path,))
|
||||
|
||||
@@ -3,11 +3,11 @@ Unit tests for the Document model
|
||||
"""
|
||||
# pylint: disable=too-many-lines
|
||||
|
||||
from operator import itemgetter
|
||||
import random
|
||||
import smtplib
|
||||
import time
|
||||
from logging import Logger
|
||||
from operator import itemgetter
|
||||
from unittest import mock
|
||||
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
@@ -1651,13 +1651,13 @@ def test_models_documents_post_save_indexer(mock_push, settings):
|
||||
|
||||
indexer = FindDocumentIndexer()
|
||||
|
||||
assert sorted(data, key=itemgetter('id')) == sorted(
|
||||
assert sorted(data, key=itemgetter("id")) == sorted(
|
||||
[
|
||||
indexer.serialize_document(doc1, accesses),
|
||||
indexer.serialize_document(doc2, accesses),
|
||||
indexer.serialize_document(doc3, accesses),
|
||||
],
|
||||
key=itemgetter('id'),
|
||||
key=itemgetter("id"),
|
||||
)
|
||||
|
||||
# The debounce counters should be reset
|
||||
|
||||
@@ -36,7 +36,6 @@ class FakeDocumentIndexer(BaseDocumentIndexer):
|
||||
return {}
|
||||
|
||||
|
||||
|
||||
@pytest.fixture(name="fake_indexer_settings")
|
||||
def fake_indexer_settings_fixture(settings):
|
||||
"""Fixture to switch the indexer to the FakeDocumentIndexer."""
|
||||
@@ -103,6 +102,7 @@ def test_services_search_indexer_class(fake_indexer_settings):
|
||||
"core.tests.test_services_search_indexers.FakeDocumentIndexer"
|
||||
)
|
||||
|
||||
|
||||
def test_services_search_indexer_url_is_none(settings):
|
||||
"""
|
||||
Indexer should raise RuntimeError if SEARCH_INDEXER_URL is None or empty.
|
||||
|
||||
Reference in New Issue
Block a user