From 6640968064b299301b77c2a865de0711d21ecf8c Mon Sep 17 00:00:00 2001 From: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Thu, 19 Mar 2026 18:57:13 -0700 Subject: [PATCH] refactor: remove document_consumer_declaration signal infrastructure Remove the document_consumer_declaration signal that was previously used for parser registration. Each parser app no longer connects to this signal, and the signal declaration itself has been removed from documents/signals. Changes: - Remove document_consumer_declaration from documents/signals/__init__.py - Remove ready() methods and signal imports from all parser app configs - Delete signal shim files (signals.py) from all parser apps: - paperless_tesseract/signals.py - paperless_text/signals.py - paperless_tika/signals.py - paperless_mail/signals.py - paperless_remote/signals.py Parser discovery now happens exclusively through the ParserRegistry system introduced in the previous refactor phases. Co-Authored-By: Claude Sonnet 4.6 --- src/documents/signals/__init__.py | 1 - src/paperless_mail/apps.py | 10 -------- src/paperless_mail/signals.py | 19 --------------- src/paperless_remote/apps.py | 9 ------- src/paperless_remote/signals.py | 38 ------------------------------ src/paperless_tesseract/apps.py | 9 ------- src/paperless_tesseract/signals.py | 34 -------------------------- src/paperless_text/apps.py | 9 ------- src/paperless_text/signals.py | 29 ----------------------- src/paperless_tika/apps.py | 10 -------- src/paperless_tika/signals.py | 33 -------------------------- 11 files changed, 201 deletions(-) delete mode 100644 src/paperless_mail/signals.py delete mode 100644 src/paperless_remote/signals.py delete mode 100644 src/paperless_tesseract/signals.py delete mode 100644 src/paperless_text/signals.py delete mode 100644 src/paperless_tika/signals.py diff --git a/src/documents/signals/__init__.py b/src/documents/signals/__init__.py index fbb55d9fe..864fec09f 100644 --- a/src/documents/signals/__init__.py +++ b/src/documents/signals/__init__.py @@ -2,5 +2,4 @@ from django.dispatch import Signal document_consumption_started = Signal() document_consumption_finished = Signal() -document_consumer_declaration = Signal() document_updated = Signal() diff --git a/src/paperless_mail/apps.py b/src/paperless_mail/apps.py index dd3e71f82..1c5d656e0 100644 --- a/src/paperless_mail/apps.py +++ b/src/paperless_mail/apps.py @@ -1,18 +1,8 @@ from django.apps import AppConfig -from django.conf import settings from django.utils.translation import gettext_lazy as _ -from paperless_mail.signals import mail_consumer_declaration - class PaperlessMailConfig(AppConfig): name = "paperless_mail" verbose_name = _("Paperless mail") - - def ready(self) -> None: - from documents.signals import document_consumer_declaration - - if settings.TIKA_ENABLED: - document_consumer_declaration.connect(mail_consumer_declaration) - AppConfig.ready(self) diff --git a/src/paperless_mail/signals.py b/src/paperless_mail/signals.py deleted file mode 100644 index 8fe046393..000000000 --- a/src/paperless_mail/signals.py +++ /dev/null @@ -1,19 +0,0 @@ -def get_parser(*args, **kwargs): - from paperless.parsers.mail import MailDocumentParser - - # MailDocumentParser accepts no constructor args in the new-style protocol. - # Pop legacy args that arrive from the signal-based consumer path. - # Phase 4 will replace this signal path with the ParserRegistry. - kwargs.pop("logging_group", None) - kwargs.pop("progress_callback", None) - return MailDocumentParser() - - -def mail_consumer_declaration(sender, **kwargs): - return { - "parser": get_parser, - "weight": 20, - "mime_types": { - "message/rfc822": ".eml", - }, - } diff --git a/src/paperless_remote/apps.py b/src/paperless_remote/apps.py index 1997b0ae9..7417221ab 100644 --- a/src/paperless_remote/apps.py +++ b/src/paperless_remote/apps.py @@ -1,14 +1,5 @@ from django.apps import AppConfig -from paperless_remote.signals import remote_consumer_declaration - class PaperlessRemoteParserConfig(AppConfig): name = "paperless_remote" - - def ready(self) -> None: - from documents.signals import document_consumer_declaration - - document_consumer_declaration.connect(remote_consumer_declaration) - - AppConfig.ready(self) diff --git a/src/paperless_remote/signals.py b/src/paperless_remote/signals.py deleted file mode 100644 index 2300be760..000000000 --- a/src/paperless_remote/signals.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import annotations - -from typing import Any - - -def get_parser(*args: Any, **kwargs: Any) -> Any: - from paperless.parsers.remote import RemoteDocumentParser - - # The new RemoteDocumentParser does not accept the progress_callback - # kwarg injected by the old signal-based consumer. logging_group is - # forwarded as a positional arg. - # Phase 4 will replace this signal path with the new ParserRegistry. - kwargs.pop("progress_callback", None) - return RemoteDocumentParser(*args, **kwargs) - - -def get_supported_mime_types() -> dict[str, str]: - from django.conf import settings - - from paperless.parsers.remote import RemoteDocumentParser - from paperless.parsers.remote import RemoteEngineConfig - - config = RemoteEngineConfig( - engine=settings.REMOTE_OCR_ENGINE, - api_key=settings.REMOTE_OCR_API_KEY, - endpoint=settings.REMOTE_OCR_ENDPOINT, - ) - if not config.engine_is_valid(): - return {} - return RemoteDocumentParser.supported_mime_types() - - -def remote_consumer_declaration(sender: Any, **kwargs: Any) -> dict[str, Any]: - return { - "parser": get_parser, - "weight": 5, - "mime_types": get_supported_mime_types(), - } diff --git a/src/paperless_tesseract/apps.py b/src/paperless_tesseract/apps.py index 8ade88400..830768c99 100644 --- a/src/paperless_tesseract/apps.py +++ b/src/paperless_tesseract/apps.py @@ -1,14 +1,5 @@ from django.apps import AppConfig -from paperless_tesseract.signals import tesseract_consumer_declaration - class PaperlessTesseractConfig(AppConfig): name = "paperless_tesseract" - - def ready(self) -> None: - from documents.signals import document_consumer_declaration - - document_consumer_declaration.connect(tesseract_consumer_declaration) - - AppConfig.ready(self) diff --git a/src/paperless_tesseract/signals.py b/src/paperless_tesseract/signals.py deleted file mode 100644 index d80d13614..000000000 --- a/src/paperless_tesseract/signals.py +++ /dev/null @@ -1,34 +0,0 @@ -from __future__ import annotations - -from typing import Any - - -def get_parser(*args: Any, **kwargs: Any) -> Any: - from paperless.parsers.tesseract import RasterisedDocumentParser - - # RasterisedDocumentParser accepts logging_group for constructor compatibility but - # does not store or use it (no legacy DocumentParser base class). - # progress_callback is also not used. Both may arrive as a positional arg - # (consumer) or a keyword arg (views); *args absorbs the positional form, - # kwargs.pop handles the keyword form. Phase 4 will replace this signal - # path with the new ParserRegistry so the shim can be removed at that point. - kwargs.pop("logging_group", None) - kwargs.pop("progress_callback", None) - return RasterisedDocumentParser(*args, **kwargs) - - -def tesseract_consumer_declaration(sender: Any, **kwargs: Any) -> dict[str, Any]: - return { - "parser": get_parser, - "weight": 0, - "mime_types": { - "application/pdf": ".pdf", - "image/jpeg": ".jpg", - "image/png": ".png", - "image/tiff": ".tif", - "image/gif": ".gif", - "image/bmp": ".bmp", - "image/webp": ".webp", - "image/heic": ".heic", - }, - } diff --git a/src/paperless_text/apps.py b/src/paperless_text/apps.py index 619d71886..9bc4ca5a8 100644 --- a/src/paperless_text/apps.py +++ b/src/paperless_text/apps.py @@ -1,14 +1,5 @@ from django.apps import AppConfig -from paperless_text.signals import text_consumer_declaration - class PaperlessTextConfig(AppConfig): name = "paperless_text" - - def ready(self) -> None: - from documents.signals import document_consumer_declaration - - document_consumer_declaration.connect(text_consumer_declaration) - - AppConfig.ready(self) diff --git a/src/paperless_text/signals.py b/src/paperless_text/signals.py deleted file mode 100644 index 916f0a7c0..000000000 --- a/src/paperless_text/signals.py +++ /dev/null @@ -1,29 +0,0 @@ -from __future__ import annotations - -from typing import Any - - -def get_parser(*args: Any, **kwargs: Any) -> Any: - from paperless.parsers.text import TextDocumentParser - - # TextDocumentParser accepts logging_group for constructor compatibility but - # does not store or use it (no legacy DocumentParser base class). - # progress_callback is also not used. Both may arrive as a positional arg - # (consumer) or a keyword arg (views); *args absorbs the positional form, - # kwargs.pop handles the keyword form. Phase 4 will replace this signal - # path with the new ParserRegistry so the shim can be removed at that point. - kwargs.pop("logging_group", None) - kwargs.pop("progress_callback", None) - return TextDocumentParser(*args, **kwargs) - - -def text_consumer_declaration(sender: Any, **kwargs: Any) -> dict[str, Any]: - return { - "parser": get_parser, - "weight": 10, - "mime_types": { - "text/plain": ".txt", - "text/csv": ".csv", - "application/csv": ".csv", - }, - } diff --git a/src/paperless_tika/apps.py b/src/paperless_tika/apps.py index 714a05188..26c94410c 100644 --- a/src/paperless_tika/apps.py +++ b/src/paperless_tika/apps.py @@ -1,15 +1,5 @@ from django.apps import AppConfig -from django.conf import settings - -from paperless_tika.signals import tika_consumer_declaration class PaperlessTikaConfig(AppConfig): name = "paperless_tika" - - def ready(self) -> None: - from documents.signals import document_consumer_declaration - - if settings.TIKA_ENABLED: - document_consumer_declaration.connect(tika_consumer_declaration) - AppConfig.ready(self) diff --git a/src/paperless_tika/signals.py b/src/paperless_tika/signals.py deleted file mode 100644 index f1fd17ef6..000000000 --- a/src/paperless_tika/signals.py +++ /dev/null @@ -1,33 +0,0 @@ -def get_parser(*args, **kwargs): - from paperless.parsers.tika import TikaDocumentParser - - # TikaDocumentParser accepts logging_group for constructor compatibility but - # does not store or use it (no legacy DocumentParser base class). - # progress_callback is also not used. Both may arrive as a positional arg - # (consumer) or a keyword arg (views); *args absorbs the positional form, - # kwargs.pop handles the keyword form. Phase 4 will replace this signal - # path with the new ParserRegistry so the shim can be removed at that point. - kwargs.pop("logging_group", None) - kwargs.pop("progress_callback", None) - return TikaDocumentParser() - - -def tika_consumer_declaration(sender, **kwargs): - return { - "parser": get_parser, - "weight": 10, - "mime_types": { - "application/msword": ".doc", - "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx", - "application/vnd.ms-excel": ".xls", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx", - "application/vnd.ms-powerpoint": ".ppt", - "application/vnd.openxmlformats-officedocument.presentationml.presentation": ".pptx", - "application/vnd.openxmlformats-officedocument.presentationml.slideshow": ".ppsx", - "application/vnd.oasis.opendocument.presentation": ".odp", - "application/vnd.oasis.opendocument.spreadsheet": ".ods", - "application/vnd.oasis.opendocument.text": ".odt", - "application/vnd.oasis.opendocument.graphics": ".odg", - "text/rtf": ".rtf", - }, - }