SciPost Code Repository

Skip to content
Snippets Groups Projects
signalprocessors.py 2.84 KiB
Newer Older
__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"


from haystack import signals
from haystack.exceptions import NotHandled

from submissions.models import Submission


class AutoSearchIndexingProcessor(signals.RealtimeSignalProcessor):

    @app.task(bind=True, name='signalprocessors.remove_object_indexes',
              serializer='yaml')
    def remove_objects_indexes(self, sender, objects):
        Given a set of `objects` model instances, remove them from the index as preparation
        for the new index.
Jorran de Wit's avatar
Jorran de Wit committed
            using_backends = self.connection_router.for_write(instance=objects[0])
        except IndexError:
            # No submissions given, stop processing here
            return None

        for instance in objects:
            for using in using_backends:
                try:
                    index = self.connections[using].get_unified_index().get_index(sender)
                    index.remove_object(instance, using=using)
                except NotHandled:
                    # TODO: Maybe log it or let the exception bubble?
                    pass

    @app.task(bind=True, name='signalprocessors.update_instance_indexes',
              serializer='yaml')
    def update_instance_indexes(self, sender, instance):
        """
        Given an individual model instance, update its entire indexes.
        """
        try:
            using_backends = self.connection_router.for_write(instance=instance)
        except IndexError:
            # No valid instance given, stop processing here
            return None

        for using in using_backends:
            try:
                index = self.connections[using].get_unified_index().get_index(sender)
                index.update(using=using)
            except NotHandled:
                # TODO: Maybe log it or let the exception bubble?
                pass

    def handle_save(self, sender, instance, **kwargs):
        if isinstance(instance, Submission):
            # Submission have complex status handling, so a status change should lead to
            # more drastic reindexing.
            chain = (
                self.remove_objects_indexes.s(sender, instance.thread.public())
                |
                self.update_instance_indexes.s(sender, instance)
            )
            chain()

            # Objects such as Reports, Comments, Commentaries, etc. may get rejected. This
            # does not remove them from the index. Therefore, do a complete rebuild_index
            # action on that specific instance every time the index signal is triggered.
            chain = (
                self.remove_objects_indexes.s(sender, [instance])
                |
                self.update_instance_indexes.s(sender, instance)
            )
            chain()