diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 55c95018d..79a7a553b 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -141,9 +141,15 @@ def _parse_beat_schedule() -> Dict: }, ] for task in tasks: + # Either get the environment setting or use the default value = os.getenv(task["env_key"], task["env_default"]) + # Don't add disabled tasks to the schedule if value == "disable": continue + # I find https://crontab.guru/ super helpful + # crontab(5) format + # - five time-and-date fields + # - separated by at least one blank minute, hour, day_month, month, day_week = value.split(" ") schedule[task["name"]] = { "task": task["task"], diff --git a/src/paperless/tests/test_settings.py b/src/paperless/tests/test_settings.py index 71926542d..a8b5cd11f 100644 --- a/src/paperless/tests/test_settings.py +++ b/src/paperless/tests/test_settings.py @@ -1,7 +1,10 @@ import datetime +import os from unittest import mock from unittest import TestCase +from celery.schedules import crontab +from paperless.settings import _parse_beat_schedule from paperless.settings import _parse_ignore_dates from paperless.settings import _parse_redis_url from paperless.settings import default_threads_per_worker @@ -139,3 +142,130 @@ class TestIgnoreDateParsing(TestCase): ]: result = _parse_redis_url(input) self.assertTupleEqual(expected, result) + + def test_schedule_configuration_default(self): + """ + GIVEN: + - No configured task schedules + WHEN: + - The celery beat schedule is built + THEN: + - The default schedule is returned + """ + schedule = _parse_beat_schedule() + + self.assertDictEqual( + { + "Check all e-mail accounts": { + "task": "paperless_mail.tasks.process_mail_accounts", + "schedule": crontab(minute="*/10"), + }, + "Train the classifier": { + "task": "documents.tasks.train_classifier", + "schedule": crontab(minute="5", hour="*/1"), + }, + "Optimize the index": { + "task": "documents.tasks.index_optimize", + "schedule": crontab(minute=0, hour=0), + }, + "Perform sanity check": { + "task": "documents.tasks.sanity_check", + "schedule": crontab(minute=30, hour=0, day_of_week="sun"), + }, + }, + schedule, + ) + + def test_schedule_configuration_changed(self): + """ + GIVEN: + - Email task is configured non-default + WHEN: + - The celery beat schedule is built + THEN: + - The email task is configured per environment + - The default schedule is returned for other tasks + """ + with mock.patch.dict( + os.environ, + {"PAPERLESS_EMAIL_TASK_CRON": "*/50 * * * mon"}, + ): + schedule = _parse_beat_schedule() + + self.assertDictEqual( + { + "Check all e-mail accounts": { + "task": "paperless_mail.tasks.process_mail_accounts", + "schedule": crontab(minute="*/50", day_of_week="mon"), + }, + "Train the classifier": { + "task": "documents.tasks.train_classifier", + "schedule": crontab(minute="5", hour="*/1"), + }, + "Optimize the index": { + "task": "documents.tasks.index_optimize", + "schedule": crontab(minute=0, hour=0), + }, + "Perform sanity check": { + "task": "documents.tasks.sanity_check", + "schedule": crontab(minute=30, hour=0, day_of_week="sun"), + }, + }, + schedule, + ) + + def test_schedule_configuration_disabled(self): + """ + GIVEN: + - Search index task is disabled + WHEN: + - The celery beat schedule is built + THEN: + - The search index task is not present + - The default schedule is returned for other tasks + """ + with mock.patch.dict(os.environ, {"PAPERLESS_INDEX_TASK_CRON": "disable"}): + schedule = _parse_beat_schedule() + + self.assertDictEqual( + { + "Check all e-mail accounts": { + "task": "paperless_mail.tasks.process_mail_accounts", + "schedule": crontab(minute="*/10"), + }, + "Train the classifier": { + "task": "documents.tasks.train_classifier", + "schedule": crontab(minute="5", hour="*/1"), + }, + "Perform sanity check": { + "task": "documents.tasks.sanity_check", + "schedule": crontab(minute=30, hour=0, day_of_week="sun"), + }, + }, + schedule, + ) + + def test_schedule_configuration_disabled_all(self): + """ + GIVEN: + - All tasks are disabled + WHEN: + - The celery beat schedule is built + THEN: + - No tasks are scheduled + """ + with mock.patch.dict( + os.environ, + { + "PAPERLESS_EMAIL_TASK_CRON": "disable", + "PAPERLESS_TRAIN_TASK_CRON": "disable", + "PAPERLESS_SANITY_TASK_CRON": "disable", + "PAPERLESS_INDEX_TASK_CRON": "disable", + }, + ): + schedule = _parse_beat_schedule() + + self.assertDictEqual( + {}, + schedule, + )