diff --git a/aleksis/core/__init__.py b/aleksis/core/__init__.py index 2484be76410f3d59a7bed7dda78c5f4e0f2a1c63..21a49f0785f3977d9a265059a32ec957c9e1eb3c 100644 --- a/aleksis/core/__init__.py +++ b/aleksis/core/__init__.py @@ -1,5 +1,11 @@ import pkg_resources +try: + from .celery import app as celery_app +except ModuleNotFoundError: + # Celery is not available + celery_app = None + try: __version__ = pkg_resources.get_distribution("AlekSIS").version except Exception: diff --git a/aleksis/core/celery.py b/aleksis/core/celery.py new file mode 100644 index 0000000000000000000000000000000000000000..2f4dce954576a5d688311c466bc2b9fb4ad4e151 --- /dev/null +++ b/aleksis/core/celery.py @@ -0,0 +1,8 @@ +import os +from celery import Celery + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "aleksis.core.settings") + +app = Celery("aleksis") # noqa +app.config_from_object('django.conf:settings', namespace='CELERY') +app.autodiscover_tasks() diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py index a4ea184b7523af9b0fd034fe3efcf21716847c5f..199ba298fbbaa201bd5090325d4e786ec4e54e9a 100644 --- a/aleksis/core/settings.py +++ b/aleksis/core/settings.py @@ -368,7 +368,16 @@ if _settings.get("2fa.twilio.sid", None): TWILIO_TOKEN = _settings.get("2fa.twilio.token") TWILIO_CALLER_ID = _settings.get("2fa.twilio.callerid") -_settings.populate_obj(sys.modules[__name__]) +if _settings.get("celery.enabled", False): + INSTALLED_APPS += ("django_celery_beat", "django_celery_results") + CELERY_BROKER_URL = "redis://localhost" + CELERY_RESULT_BACKEND = "django-db" + CELERY_CACHE_BACKEND = "django-cache" + CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler" + + if _settings.get("celery.email", False): + INSTALLED_APPS += ("djcelery_email",) + EMAIL_BACKEND = "djcelery_email.backends.CeleryEmailBackend" PWA_APP_NAME = "AlekSIS" # dbsettings PWA_APP_DESCRIPTION = "AlekSIS – The free school information system" # dbsettings diff --git a/aleksis/core/templatetags/templatetags/msg_box.py b/aleksis/core/templatetags/msg_box.py similarity index 100% rename from aleksis/core/templatetags/templatetags/msg_box.py rename to aleksis/core/templatetags/msg_box.py diff --git a/aleksis/core/templatetags/templatetags/__init__.py b/aleksis/core/templatetags/templatetags/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/aleksis/core/templatetags/templatetags/copy_filter.py b/aleksis/core/templatetags/templatetags/copy_filter.py deleted file mode 100644 index 9ee6181b430174b1f8dec5eff3276531f7e7e44b..0000000000000000000000000000000000000000 --- a/aleksis/core/templatetags/templatetags/copy_filter.py +++ /dev/null @@ -1,8 +0,0 @@ -import copy as copylib - -from django import template - -register = template.Library() - -register.filter("copy", copylib.copy) -register.filter("deepcopy", copylib.deepcopy) diff --git a/aleksis/core/templatetags/templatetags/tex.py b/aleksis/core/templatetags/templatetags/tex.py deleted file mode 100644 index 333c3d31d819eb4c3b41ef6513d3b2b9df3ff30e..0000000000000000000000000000000000000000 --- a/aleksis/core/templatetags/templatetags/tex.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Django filters, needed when creating LaTeX files with the django template language - -Written by Rocco Schulz (http://is-gr8.com/), modified by SchoolApps-Team -""" -from django.template.defaultfilters import stringfilter, register -from django.template.loader import render_to_string - - -@register.filter -@stringfilter -def brackets(value): - """ - surrounds the value with { } - You have to use this filter whenever you would need something like - {{{ field }}} in a template. - """ - return "{%s}" % value - - -REPLACEMENTS = { - "§": "\\textsection{}", - "$": "\\textdollar{}", - "LaTeX": "\\LaTeX \\ ", - " TeX": " \\TeX \\ ", - "€": "\\euro", - ">": "$>$", - "<": "$<$" -} - -ESCAPES = ("&", "{", "}", "%") - - -@register.filter -@stringfilter -def texify(value): - """ - escapes/replaces special character with appropriate latex commands - """ - tex_value = [] - - # escape special symbols - for char in value: - tex_value.append("%s" % ("\\%s" % char if char in ESCAPES else char)) - tex_value = "".join(tex_value) - - # replace symbols / words with latex commands - for key, value in REPLACEMENTS.items(): - tex_value = tex_value.replace(key, value) - - return "%s" % tex_value diff --git a/aleksis/core/templatetags/templatetags/url_name.py b/aleksis/core/templatetags/templatetags/url_name.py deleted file mode 100644 index 20f63c673b00f0d736652db62937f9dc68947db2..0000000000000000000000000000000000000000 --- a/aleksis/core/templatetags/templatetags/url_name.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.urls import resolve -from django import template - -register = template.Library() - - -def get_url_name(request): # Only one argument. - """Gets url_name""" - try: - return resolve(request.path_info).url_name - except Exception as e: - return e - - -register.filter("url_name", get_url_name) diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py index 0a5aab7cb8765fd6e9a70a020770a083e01c13a1..5669323611a2a09a6b82a9d0a8523336381bfa7e 100644 --- a/aleksis/core/util/core_helpers.py +++ b/aleksis/core/util/core_helpers.py @@ -102,3 +102,22 @@ def has_person(obj: Union[HttpRequest, Model]) -> bool: return False return getattr(obj, "person", None) is not None + + +def celery_optional(orig: Callable) -> Callable: + """ Decorator that makes Celery optional for a function. + + If Celery is configured and available, it wraps the function in a Task + and calls its delay method when invoked; if not, it leaves it untouched + and it is executed synchronously. + """ + + if hasattr(settings, "CELERY_RESULT_BACKEND"): + from ..celery import app # noqa + task = app.task(orig) + + def wrapped(*args, **kwargs): + task.delay(*args, **kwargs) + return wrapped + else: + return orig diff --git a/poetry.lock b/poetry.lock index 73e774ec7523336f1d76a01ea821b22aeaebfa23..f26d4ed1eb2979d0ede5264676e9236de394f58a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -6,6 +6,17 @@ optional = false python-versions = "*" version = "0.7.12" +[[package]] +category = "main" +description = "Low-level AMQP client for Python (fork of amqplib)." +name = "amqp" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.5.2" + +[package.dependencies] +vine = ">=1.1.3,<5.0.0a1" + [[package]] category = "dev" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." @@ -89,6 +100,14 @@ soupsieve = ">=1.2" html5lib = ["html5lib"] lxml = ["lxml"] +[[package]] +category = "main" +description = "Python multiprocessing fork with improvements and bugfixes" +name = "billiard" +optional = true +python-versions = "*" +version = "3.6.1.0" + [[package]] category = "dev" description = "The uncompromising code formatter." @@ -109,6 +128,62 @@ typed-ast = ">=1.4.0" [package.extras] d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] +[[package]] +category = "main" +description = "Distributed Task Queue." +name = "celery" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*," +version = "4.4.0" + +[package.dependencies] +billiard = ">=3.6.1,<4.0" +kombu = ">=4.6.7,<4.7" +pytz = ">0.0-dev" +vine = "1.3.0" + +[package.dependencies.Django] +optional = true +version = ">=1.11" + +[package.dependencies.redis] +optional = true +version = ">=3.2.0" + +[package.extras] +arangodb = ["pyArango (>=1.3.2)"] +auth = ["cryptography"] +azureblockblob = ["azure-storage (0.36.0)", "azure-common (1.1.5)", "azure-storage-common (1.1.0)"] +brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"] +cassandra = ["cassandra-driver"] +consul = ["python-consul"] +cosmosdbsql = ["pydocumentdb (2.3.2)"] +couchbase = ["couchbase", "couchbase-cffi"] +couchdb = ["pycouchdb"] +django = ["Django (>=1.11)"] +dynamodb = ["boto3 (>=1.9.178)"] +elasticsearch = ["elasticsearch"] +eventlet = ["eventlet (>=0.24.1)"] +gevent = ["gevent"] +librabbitmq = ["librabbitmq (>=1.5.0)"] +lzma = ["backports.lzma"] +memcache = ["pylibmc"] +mongodb = ["pymongo (>=3.3.0)"] +msgpack = ["msgpack"] +pymemcache = ["python-memcached"] +pyro = ["pyro4"] +redis = ["redis (>=3.2.0)"] +riak = ["riak (>=2.0)"] +s3 = ["boto3 (>=1.9.125)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +solar = ["ephem"] +sqlalchemy = ["sqlalchemy"] +sqs = ["boto3 (>=1.9.125)", "pycurl"] +tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=1.3.1)"] +zstd = ["zstandard"] + [[package]] category = "main" description = "Python package for providing Mozilla's CA Bundle." @@ -161,6 +236,9 @@ optional = false python-versions = "*" version = "5.0.6" +[package.dependencies] +six = "*" + [[package]] category = "dev" description = "Code coverage measurement for Python" @@ -254,6 +332,42 @@ version = "2.2.0" [package.dependencies] Django = ">=1.8" +[[package]] +category = "main" +description = "Database-backed Periodic Tasks." +name = "django-celery-beat" +optional = true +python-versions = "*" +version = "1.5.0" + +[package.dependencies] +django-timezone-field = ">=2.0" +python-crontab = ">=2.3.4" + +[[package]] +category = "main" +description = "An async Django email backend using celery" +name = "django-celery-email" +optional = true +python-versions = "*" +version = "3.0.0" + +[package.dependencies] +celery = ">=4.0" +django = ">=2.2" +django-appconf = "*" + +[[package]] +category = "main" +description = "Celery result backends for Django." +name = "django-celery-results" +optional = true +python-versions = "*" +version = "1.1.2" + +[package.dependencies] +celery = ">=4.3,<5.0" + [[package]] category = "main" description = "Django admin CKEditor integration." @@ -273,6 +387,11 @@ optional = false python-versions = "*" version = "2.5.0" +[package.dependencies] +[package.dependencies.django-picklefield] +optional = true +version = "*" + [package.extras] database = ["django-picklefield"] redis = ["redis"] @@ -281,7 +400,6 @@ redis = ["redis"] reference = "590fa02eb30e377da0eda5cc3a84254b839176a7" type = "git" url = "https://github.com/jazzband/django-constance" - [[package]] category = "main" description = "A configurable set of panels that display various debug information about the current request/response." @@ -581,6 +699,18 @@ version = "2.3.0" django-render-block = ">=0.5" six = ">=1" +[[package]] +category = "main" +description = "A Django app providing database and form fields for pytz timezone objects." +name = "django-timezone-field" +optional = true +python-versions = ">=3.5" +version = "4.0" + +[package.dependencies] +django = ">=2.2" +pytz = "*" + [[package]] category = "main" description = "Complete Two-Factor Authentication for Django" @@ -721,12 +851,11 @@ category = "main" description = "Faker is a Python package that generates fake data for you." name = "faker" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "3.0.1" +python-versions = ">=3.4" +version = "4.0.0" [package.dependencies] python-dateutil = ">=2.4" -six = ">=1.10" text-unidecode = "1.3" [[package]] @@ -916,7 +1045,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "1.2.0" [[package]] -category = "dev" +category = "main" description = "Read metadata from Python packages" marker = "python_version < \"3.8\"" name = "importlib-metadata" @@ -959,6 +1088,37 @@ MarkupSafe = ">=0.23" [package.extras] i18n = ["Babel (>=0.8)"] +[[package]] +category = "main" +description = "Messaging library for Python." +name = "kombu" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "4.6.7" + +[package.dependencies] +amqp = ">=2.5.2,<2.6" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.18" + +[package.extras] +azureservicebus = ["azure-servicebus (>=0.21.1)"] +azurestoragequeues = ["azure-storage-queue"] +consul = ["python-consul (>=0.6.0)"] +librabbitmq = ["librabbitmq (>=1.5.2)"] +mongodb = ["pymongo (>=3.3.0)"] +msgpack = ["msgpack"] +pyro = ["pyro4"] +qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"] +redis = ["redis (>=3.3.11)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +sqlalchemy = ["sqlalchemy"] +sqs = ["boto3 (>=1.4.4)", "pycurl (7.43.0.2)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=1.3.1)"] + [[package]] category = "main" description = "Sass for Python: A straightforward binding of libsass for Python." @@ -987,7 +1147,7 @@ python-versions = "*" version = "0.6.1" [[package]] -category = "dev" +category = "main" description = "More routines for operating on iterables, beyond itertools" name = "more-itertools" optional = false @@ -1279,6 +1439,21 @@ version = "3.4.6" [package.extras] testing = ["pytest", "coverage (>=3.6)", "pytest-cov"] +[[package]] +category = "main" +description = "Python Crontab API" +name = "python-crontab" +optional = true +python-versions = "*" +version = "2.4.0" + +[package.dependencies] +python-dateutil = "*" + +[package.extras] +cron-description = ["cron-descriptor"] +cron-schedule = ["croniter"] + [[package]] category = "main" description = "Extensions to the standard Python datetime module" @@ -1337,7 +1512,7 @@ category = "main" description = "YAML parser and emitter for Python" name = "pyyaml" optional = false -python-versions = "*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" version = "5.3" [[package]] @@ -1358,6 +1533,17 @@ maintainer = ["zest.releaser"] pil = ["pillow"] test = ["pytest", "pytest-cov", "mock"] +[[package]] +category = "main" +description = "Python client for Redis key-value store" +name = "redis" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.3.11" + +[package.extras] +hiredis = ["hiredis (>=0.1.3)"] + [[package]] category = "dev" description = "Alternative regular expression module, to replace re." @@ -1434,8 +1620,8 @@ category = "main" description = "Python 2 and 3 compatibility utilities" name = "six" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "1.13.0" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +version = "1.14.0" [[package]] category = "dev" @@ -1721,6 +1907,14 @@ brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] +[[package]] +category = "main" +description = "Promises, promises, promises." +name = "vine" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.3.0" + [[package]] category = "dev" description = "Measures number of Terminal column cells of wide-character codes" @@ -1742,7 +1936,7 @@ pycryptodome = "*" six = "*" [[package]] -category = "dev" +category = "main" description = "Backport of pathlib-compatible object wrapper for zip files" marker = "python_version < \"3.8\"" name = "zipp" @@ -1758,10 +1952,11 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["pathlib2", "contextlib2", "unittest2"] [extras] +celery = ["Celery", "django-celery-results", "django-celery-beat", "django-celery-email"] ldap = ["django-auth-ldap"] [metadata] -content-hash = "e312e9803fee3289e4d403de297d432c3747e437c1b3fedbd2b8baeca3bfa9b0" +content-hash = "b2a7c1d9e1318e93322b69bf5b9eaeaee6b6fc4b3f983f1a0c88d2c934f8d848" python-versions = "^3.7" [metadata.files] @@ -1769,6 +1964,10 @@ alabaster = [ {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, ] +amqp = [ + {file = "amqp-2.5.2-py2.py3-none-any.whl", hash = "sha256:6e649ca13a7df3faacdc8bbb280aa9a6602d22fd9d545336077e573a1f4ff3b8"}, + {file = "amqp-2.5.2.tar.gz", hash = "sha256:77f1aef9410698d20eaeac5b73a87817365f457a507d82edf292e12cbb83b08d"}, +] appdirs = [ {file = "appdirs-1.4.3-py2.py3-none-any.whl", hash = "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"}, {file = "appdirs-1.4.3.tar.gz", hash = "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92"}, @@ -1798,10 +1997,18 @@ beautifulsoup4 = [ {file = "beautifulsoup4-4.8.2-py3-none-any.whl", hash = "sha256:9fbb4d6e48ecd30bcacc5b63b94088192dcda178513b2ae3c394229f8911b887"}, {file = "beautifulsoup4-4.8.2.tar.gz", hash = "sha256:05fd825eb01c290877657a56df4c6e4c311b3965bda790c613a3d6fb01a5462a"}, ] +billiard = [ + {file = "billiard-3.6.1.0-py3-none-any.whl", hash = "sha256:01afcb4e7c4fd6480940cfbd4d9edc19d7a7509d6ada533984d0d0f49901ec82"}, + {file = "billiard-3.6.1.0.tar.gz", hash = "sha256:b8809c74f648dfe69b973c8e660bcec00603758c9db8ba89d7719f88d5f01f26"}, +] black = [ {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, ] +celery = [ + {file = "celery-4.4.0-py2.py3-none-any.whl", hash = "sha256:7c544f37a84a5eadc44cab1aa8c9580dff94636bb81978cdf9bf8012d9ea7d8f"}, + {file = "celery-4.4.0.tar.gz", hash = "sha256:d3363bb5df72d74420986a435449f3c3979285941dff57d5d97ecba352a0e3e2"}, +] certifi = [ {file = "certifi-2019.11.28-py2.py3-none-any.whl", hash = "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3"}, {file = "certifi-2019.11.28.tar.gz", hash = "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"}, @@ -1885,6 +2092,18 @@ django-bulk-update = [ {file = "django-bulk-update-2.2.0.tar.gz", hash = "sha256:5ab7ce8a65eac26d19143cc189c0f041d5c03b9d1b290ca240dc4f3d6aaeb337"}, {file = "django_bulk_update-2.2.0-py2.py3-none-any.whl", hash = "sha256:49a403392ae05ea872494d74fb3dfa3515f8df5c07cc277c3dc94724c0ee6985"}, ] +django-celery-beat = [ + {file = "django-celery-beat-1.5.0.tar.gz", hash = "sha256:659b39232c454ac27022bf679939bce0471fd482f3ee9276f5199716cb4afad9"}, + {file = "django_celery_beat-1.5.0-py2.py3-none-any.whl", hash = "sha256:61c92d4b600a9f24406ee0b8d01a9b192253e15d047e3325e1d81e2cacf7aba6"}, +] +django-celery-email = [ + {file = "django-celery-email-3.0.0.tar.gz", hash = "sha256:5546cbba80952cc3b8a0ffa4206ce90a4a996a7ffd1c385a2bdb65903ca18ece"}, + {file = "django_celery_email-3.0.0-py2.py3-none-any.whl", hash = "sha256:0f72da39cb2ea83c69440566e87f27cd72f68f247f98ce99fb29889fcf329406"}, +] +django-celery-results = [ + {file = "django_celery_results-1.1.2-py2.py3-none-any.whl", hash = "sha256:932277e9382528f74778b30cf90e17941cba577b7d73cee09ed55e4972972c32"}, + {file = "django_celery_results-1.1.2.tar.gz", hash = "sha256:e735dc3e705a0e21afc3b6fa2918ec388258145fcbaad3727c493c5707d25034"}, +] django-ckeditor = [ {file = "django-ckeditor-5.8.0.tar.gz", hash = "sha256:46fc9c7346ea36183dc0cea350f98704f8b04c4722b7fe4fb18baf8ae20423fb"}, {file = "django_ckeditor-5.8.0-py2.py3-none-any.whl", hash = "sha256:a59bab13f4481318f8a048b1b0aef5c7da768a6352dcfb9ba0e77d91fbb9462a"}, @@ -1985,6 +2204,10 @@ django-tables2 = [ django-templated-email = [ {file = "django-templated-email-2.3.0.tar.gz", hash = "sha256:536c4e5ae099eabfb9aab36087d4d7799948c654e73da55a744213d086d5bb33"}, ] +django-timezone-field = [ + {file = "django-timezone-field-4.0.tar.gz", hash = "sha256:7e3620fe2211c2d372fad54db8f86ff884098d018d56fda4dca5e64929e05ffc"}, + {file = "django_timezone_field-4.0-py3-none-any.whl", hash = "sha256:758b7d41084e9ea2e89e59eb616e9b6326e6fbbf9d14b6ef062d624fe8cc6246"}, +] django-two-factor-auth = [ {file = "django-two-factor-auth-1.10.0.tar.gz", hash = "sha256:3c3af3cd747462be18e7494c4068a2bdc606d7a2d2b2914f8d4590fc80995a71"}, {file = "django_two_factor_auth-1.10.0-py2.py3-none-any.whl", hash = "sha256:0945260fa84e4522d8fa951c35e401616579fd8564938441614399dc588a1c1f"}, @@ -2016,8 +2239,8 @@ entrypoints = [ {file = "entrypoints-0.3.tar.gz", hash = "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"}, ] faker = [ - {file = "Faker-3.0.1-py2.py3-none-any.whl", hash = "sha256:6eb3581e990e36ef6f1cf37f70f9a799e119e1a7b94a6062a14f1b8d781c67e4"}, - {file = "Faker-3.0.1.tar.gz", hash = "sha256:c7f7466cb9ba58d582f713494acdb5ebcc462336c5e38c5230b0cdab37069985"}, + {file = "Faker-4.0.0-py3-none-any.whl", hash = "sha256:047d4d1791bfb3756264da670d99df13d799bb36e7d88774b1585a82d05dbaec"}, + {file = "Faker-4.0.0.tar.gz", hash = "sha256:1b1a58961683b30c574520d0c739c4443e0ef6a185c04382e8cc888273dbebed"}, ] flake8 = [ {file = "flake8-3.7.9-py2.py3-none-any.whl", hash = "sha256:49356e766643ad15072a789a20915d3c91dc89fd313ccd71802303fd67e4deca"}, @@ -2091,6 +2314,10 @@ jinja2 = [ {file = "Jinja2-2.10.3-py2.py3-none-any.whl", hash = "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f"}, {file = "Jinja2-2.10.3.tar.gz", hash = "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"}, ] +kombu = [ + {file = "kombu-4.6.7-py2.py3-none-any.whl", hash = "sha256:2a9e7adff14d046c9996752b2c48b6d9185d0b992106d5160e1a179907a5d4ac"}, + {file = "kombu-4.6.7.tar.gz", hash = "sha256:67b32ccb6fea030f8799f8fd50dd08e03a4b99464ebc4952d71d8747b1a52ad1"}, +] libsass = [ {file = "libsass-0.19.4-cp27-cp27m-macosx_10_14_intel.whl", hash = "sha256:74acd9adf506142699dfa292f0e569fdccbd9e7cf619e8226f7117de73566e32"}, {file = "libsass-0.19.4-cp27-cp27m-win32.whl", hash = "sha256:50778d4be269a021ba2bf42b5b8f6ff3704ab96a82175a052680bddf3ba7cc9f"}, @@ -2346,6 +2573,9 @@ python-box = [ {file = "python-box-3.4.6.tar.gz", hash = "sha256:694a7555e3ff9fbbce734bbaef3aad92b8e4ed0659d3ed04d56b6a0a0eff26a9"}, {file = "python_box-3.4.6-py2.py3-none-any.whl", hash = "sha256:a71d3dc9dbaa34c8597d3517c89a8041bd62fa875f23c0f3dad55e1958e3ce10"}, ] +python-crontab = [ + {file = "python-crontab-2.4.0.tar.gz", hash = "sha256:3ac1608ff76032e6fc6e16b5fbf83b51557e0e066bf78e9f88571571e7bd7ae6"}, +] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, @@ -2382,6 +2612,10 @@ qrcode = [ {file = "qrcode-6.1-py2.py3-none-any.whl", hash = "sha256:3996ee560fc39532910603704c82980ff6d4d5d629f9c3f25f34174ce8606cf5"}, {file = "qrcode-6.1.tar.gz", hash = "sha256:505253854f607f2abf4d16092c61d4e9d511a3b4392e60bff957a68592b04369"}, ] +redis = [ + {file = "redis-3.3.11-py2.py3-none-any.whl", hash = "sha256:3613daad9ce5951e426f460deddd5caf469e08a3af633e9578fc77d362becf62"}, + {file = "redis-3.3.11.tar.gz", hash = "sha256:8d0fc278d3f5e1249967cba2eb4a5632d19e45ce5c09442b8422d15ee2c22cc2"}, +] regex = [ {file = "regex-2020.1.8-cp27-cp27m-win32.whl", hash = "sha256:4e8f02d3d72ca94efc8396f8036c0d3bcc812aefc28ec70f35bb888c74a25161"}, {file = "regex-2020.1.8-cp27-cp27m-win_amd64.whl", hash = "sha256:e6c02171d62ed6972ca8631f6f34fa3281d51db8b326ee397b9c83093a6b7242"}, @@ -2425,8 +2659,8 @@ selenium = [ {file = "selenium-3.141.0.tar.gz", hash = "sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d"}, ] six = [ - {file = "six-1.13.0-py2.py3-none-any.whl", hash = "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd"}, - {file = "six-1.13.0.tar.gz", hash = "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"}, + {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, + {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, ] smmap2 = [ {file = "smmap2-2.0.5-py2.py3-none-any.whl", hash = "sha256:0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde"}, @@ -2547,8 +2781,13 @@ urllib3 = [ {file = "urllib3-1.25.7-py2.py3-none-any.whl", hash = "sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293"}, {file = "urllib3-1.25.7.tar.gz", hash = "sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"}, ] +vine = [ + {file = "vine-1.3.0-py2.py3-none-any.whl", hash = "sha256:ea4947cc56d1fd6f2095c8d543ee25dad966f78692528e68b4fada11ba3f98af"}, + {file = "vine-1.3.0.tar.gz", hash = "sha256:133ee6d7a9016f177ddeaf191c1f58421a1dcc6ee9a42c58b34bed40e1d2cd87"}, +] wcwidth = [ {file = "wcwidth-0.1.8-py2.py3-none-any.whl", hash = "sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603"}, + {file = "wcwidth-0.1.8.tar.gz", hash = "sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"}, ] yubiotp = [ {file = "YubiOTP-0.2.2.post1-py2.py3-none-any.whl", hash = "sha256:7e281801b24678f4bda855ce8ab975a7688a912f5a6cb22b6c2b16263a93cbd2"}, diff --git a/pyproject.toml b/pyproject.toml index 35d340e82953303a1ec553bed59ddce25057f715..77cdc3486b024ae6ff0b0d4ded2175a651146705 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,13 +54,18 @@ django-constance = {git = "https://github.com/jazzband/django-constance", rev = django_widget_tweaks = "^1.4.5" django-filter = "^2.2.0" django-templated-email = "^2.3.0" -html2text = "^2019.9.26" +html2text = "^2020.0.0" django-ckeditor = "^5.8.0" django-js-reverse = "^0.9.1" calendarweek = "^0.4.3" +Celery = {version="^4.4.0", optional=true, extras=["django", "redis"]} +django-celery-results = {version="^1.1.2", optional=true} +django-celery-beat = {version="^1.5.0", optional=true} +django-celery-email = {version="^3.0.0", optional=true} [tool.poetry.extras] ldap = ["django-auth-ldap"] +celery = ["Celery", "django-celery-results", "django-celery-beat", "django-celery-email"] [tool.poetry.dev-dependencies] sphinx = "^2.1"