diff --git a/aleksis/core/models.py b/aleksis/core/models.py index 9dacaa75fcc105b7ec7cfbaf571d95cf7afa23e1..b7a6350b91ce6a08cebc502cae0e4442edc35a40 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -9,8 +9,11 @@ from image_cropping import ImageCropField, ImageRatioField from phonenumber_field.modelfields import PhoneNumberField from .mailer import send_mail_with_template +from templated_email import send_templated_mail from .mixins import ExtensibleModel +from constance import config + class School(models.Model): """A school that will have many other objects linked to it. @@ -209,11 +212,15 @@ class Notification(models.Model): return self.title def save(self, **kwargs): - super().save(**kwargs) if not self.mailed: - send_mail_with_template(self.title, [self.user.email], "mail/notification.txt", "mail/notification.html", - {"notification": self}) + send_templated_mail( + template_name='notification', + from_email=config.MAIL_OUT, + recipient_list=[self.user.email], + context={"notification": self} + ) self.mailed = True + super().save(**kwargs) class Meta: verbose_name = _("Notification") diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py index bd0f30cff8495d05537c8b5d6f12f2875910a5ce..6874fa6fd175e2170ca99193fd03dcdeda7c2c9a 100644 --- a/aleksis/core/settings.py +++ b/aleksis/core/settings.py @@ -66,6 +66,8 @@ INSTALLED_APPS = [ "debug_toolbar", "django_select2", "hattori", + "templated_email", + "html2text", "django_otp.plugins.otp_totp", "django_otp.plugins.otp_static", "django_otp", @@ -280,6 +282,10 @@ if _settings.get("mail.server.host", None): EMAIL_HOST_USER = _settings.get("mail.server.user") EMAIL_HOST_PASSWORD = _settings.get("mail.server.password") +TEMPLATED_EMAIL_BACKEND = 'templated_email.backends.vanilla_django' +TEMPLATED_EMAIL_AUTO_PLAIN = True + + TEMPLATE_VISIBLE_SETTINGS = ["ADMINS", "DEBUG"] CONSTANCE_BACKEND = "constance.backends.database.DatabaseBackend" diff --git a/aleksis/core/templates/templated_email/email.email b/aleksis/core/templates/templated_email/email.email new file mode 100644 index 0000000000000000000000000000000000000000..cf19a4f0618bd039c88eca8c68d6a0d04f5ff70c --- /dev/null +++ b/aleksis/core/templates/templated_email/email.email @@ -0,0 +1,16 @@ +{% load i18n %} + +{% block subject %} My subject for {{username}} {% endblock %} + +{% block html %} +<main> + {% blocktrans %} + <h1>Dear {{ username }},</h1> + <p>thank you for using <em>AlekSIS</em>!</p> + + <p>Yours sincerely + <br> + AlekSIS team</p> + {% endblocktrans %} +</main> +{% endblock %} diff --git a/aleksis/core/templates/templated_email/notification.email b/aleksis/core/templates/templated_email/notification.email new file mode 100644 index 0000000000000000000000000000000000000000..60811457464fcfd28b994e221cbf0f45cf4fe936 --- /dev/null +++ b/aleksis/core/templates/templated_email/notification.email @@ -0,0 +1,28 @@ +{% load i18n %} + +{% block subject %} My subject for {{username}} {% endblock %} + +{% block html %} +<main> + {% blocktrans %} + <h1>Dear {{ username }},</h1> + <p>thank you for using <em>AlekSIS</em>!</p> + + <p>Yours sincerely + <br> + AlekSIS team</p> + + <p>Dear {{ notification.user.get_full_name }}, <br> + weǜe got a new message for you:</p> + <blockquote> + <p>{{ notification.description }}</p> + {% if notification.link %} + <a href="{{ notification.link }}">More information →</a> + {% endif %} + </blockquote> + <p>By {{ notification.app }} at {{ notification.created_at }}</p> + + <i>Your AlekSIS team</i> + {% endblocktrans %} +</main> +{% endblock %} diff --git a/apps/official/AlekSIS-App-Chronos b/apps/official/AlekSIS-App-Chronos index 60576ae5c3f6aa15e63387afe6205aa889668bbb..99c4cd0b940497f2bca5e10904c482ac8807bd0f 160000 --- a/apps/official/AlekSIS-App-Chronos +++ b/apps/official/AlekSIS-App-Chronos @@ -1 +1 @@ -Subproject commit 60576ae5c3f6aa15e63387afe6205aa889668bbb +Subproject commit 99c4cd0b940497f2bca5e10904c482ac8807bd0f diff --git a/apps/official/AlekSIS-App-Hjelp b/apps/official/AlekSIS-App-Hjelp index 2d5c162289fb95052a2407e9403de08b072a578e..0ea718b743e9c2235adceb8b09db84e8c2abd59c 160000 --- a/apps/official/AlekSIS-App-Hjelp +++ b/apps/official/AlekSIS-App-Hjelp @@ -1 +1 @@ -Subproject commit 2d5c162289fb95052a2407e9403de08b072a578e +Subproject commit 0ea718b743e9c2235adceb8b09db84e8c2abd59c diff --git a/poetry.lock b/poetry.lock index e1ff6ac3e8860e9c357406e4f9c2c28679ade292..3df468dd66024fd5651ffc494a6d3f6d014ab503 100644 --- a/poetry.lock +++ b/poetry.lock @@ -443,10 +443,6 @@ version = "3.0.1" Django = ">=1.11.3" babel = "*" -[package.dependencies.phonenumbers] -optional = true -version = ">=7.0.2" - [package.extras] phonenumbers = ["phonenumbers (>=7.0.2)"] phonenumberslite = ["phonenumberslite (>=7.0.2)"] @@ -476,6 +472,17 @@ version = "1.0.6" [package.dependencies] django = ">=1.8" +[[package]] +category = "main" +description = "Render a particular block from a template to a string." +name = "django-render-block" +optional = false +python-versions = "*" +version = "0.6" + +[package.dependencies] +django = ">=1.11" + [[package]] category = "main" description = "SASS processor to compile SCSS files into *.css, while rendering, or offline." @@ -535,6 +542,18 @@ Django = ">=1.11" [package.extras] tablib = ["tablib"] +[[package]] +category = "main" +description = "A Django oriented templated / transaction email abstraction" +name = "django-templated-email" +optional = false +python-versions = "*" +version = "2.3.0" + +[package.dependencies] +django-render-block = ">=0.5" +six = ">=1" + [[package]] category = "main" description = "Complete Two-Factor Authentication for Django" @@ -845,6 +864,14 @@ version = "3.0.5" [package.dependencies] gitdb2 = ">=2.0.0" +[[package]] +category = "main" +description = "Turn HTML into equivalent Markdown-structured text." +name = "html2text" +optional = false +python-versions = ">=3.5" +version = "2019.9.26" + [[package]] category = "main" description = "Internationalized Domain Names in Applications (IDNA)" @@ -1065,7 +1092,7 @@ description = "A collection of ASN.1-based protocols modules." name = "pyasn1-modules" optional = true python-versions = "*" -version = "0.2.7" +version = "0.2.8" [package.dependencies] pyasn1 = ">=0.4.6,<0.5.0" @@ -1092,7 +1119,7 @@ description = "Python docstring style checker" name = "pydocstyle" optional = false python-versions = ">=3.5" -version = "5.0.1" +version = "5.0.2" [package.dependencies] snowballstemmer = "*" @@ -1310,7 +1337,7 @@ description = "Alternative regular expression module, to replace re." name = "regex" optional = false python-versions = "*" -version = "2020.1.7" +version = "2020.1.8" [[package]] category = "main" @@ -1627,7 +1654,7 @@ description = "Twilio API client and TwiML generator" name = "twilio" optional = false python-versions = "*" -version = "6.35.1" +version = "6.35.2" [package.dependencies] PyJWT = ">=1.4.2" @@ -1707,7 +1734,7 @@ testing = ["pathlib2", "contextlib2", "unittest2"] ldap = ["django-auth-ldap"] [metadata] -content-hash = "f1067135f2cc47c72fa90cd424e95a40d914567249e1027cfc53910b5f4de91d" +content-hash = "bafd38016685ed70dde2d682a10efa4ae15c5a1e33ce10ef2551a60be1cfdb0f" python-versions = "^3.7" [metadata.files] @@ -1895,6 +1922,9 @@ django-pwa = [ {file = "django-pwa-1.0.6.tar.gz", hash = "sha256:b3f1ad0c5241fae4c7505423540de4db93077d7c88416ff6d2af545ffe209f34"}, {file = "django_pwa-1.0.6-py3-none-any.whl", hash = "sha256:9306105fcb637ae16fea6527be4b147d45fd53db85efb1d4f61dfea6bf793e56"}, ] +django-render-block = [ + {file = "django_render_block-0.6-py2.py3-none-any.whl", hash = "sha256:95c7dc9610378a10e0c4a10d8364ec7307210889afccd6a67a6aaa0fd599bd4d"}, +] django-sass-processor = [ {file = "django-sass-processor-0.8.tar.gz", hash = "sha256:e039551994feaaba6fcf880412b25a772dd313162a34cbb4289814988cfae340"}, ] @@ -1913,6 +1943,9 @@ django-tables2 = [ {file = "django-tables2-2.2.1.tar.gz", hash = "sha256:0d9b17f5c030ba1b5fcaeb206d8397bf58f1fdfc6beaf56e7874841b8647aa94"}, {file = "django_tables2-2.2.1-py2.py3-none-any.whl", hash = "sha256:6afa0496695e15b332e98537265d09fe01a55b28c75a85323d8e6b0dc2350280"}, ] +django-templated-email = [ + {file = "django-templated-email-2.3.0.tar.gz", hash = "sha256:536c4e5ae099eabfb9aab36087d4d7799948c654e73da55a744213d086d5bb33"}, +] 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"}, @@ -1996,6 +2029,10 @@ gitpython = [ {file = "GitPython-3.0.5-py3-none-any.whl", hash = "sha256:c155c6a2653593ccb300462f6ef533583a913e17857cfef8fc617c246b6dc245"}, {file = "GitPython-3.0.5.tar.gz", hash = "sha256:9c2398ffc3dcb3c40b27324b316f08a4f93ad646d5a6328cafbb871aa79f5e42"}, ] +html2text = [ + {file = "html2text-2019.9.26-py3-none-any.whl", hash = "sha256:55ce85704f244fc18890c5ded89fa22ff7333e41e9f3cad04d51f48d62ad8834"}, + {file = "html2text-2019.9.26.tar.gz", hash = "sha256:6f56057c5c2993b5cc5b347cb099bdf6d095828fef1b53ef4e2a2bf2a1be9b4f"}, +] idna = [ {file = "idna-2.8-py2.py3-none-any.whl", hash = "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"}, {file = "idna-2.8.tar.gz", hash = "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407"}, @@ -2175,19 +2212,19 @@ pyasn1 = [ {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, ] pyasn1-modules = [ - {file = "pyasn1-modules-0.2.7.tar.gz", hash = "sha256:0c35a52e00b672f832e5846826f1fb7507907f7d52fba6faa9e3c4cbe874fe4b"}, - {file = "pyasn1_modules-0.2.7-py2.4.egg", hash = "sha256:233f55c840e821e76828262db976ac894b285909d22d060c2bdb522e7bf28cc6"}, - {file = "pyasn1_modules-0.2.7-py2.5.egg", hash = "sha256:9ca5e376a6d9dee35bb3a62608dfa2e6698798aa6b8db3c7afd0eb31af0d63c7"}, - {file = "pyasn1_modules-0.2.7-py2.6.egg", hash = "sha256:27581362b4253b9c999882a64df974124cde12be0bf2c04148a0d68bc6bbb7b8"}, - {file = "pyasn1_modules-0.2.7-py2.7.egg", hash = "sha256:13a6955947d8a554de78fc305a4d651f20fb5580b88612a5f0661d4f189d27ac"}, - {file = "pyasn1_modules-0.2.7-py2.py3-none-any.whl", hash = "sha256:b6ada4f840fe51abf5a6bd545b45bf537bea62221fa0dde2e8a553ed9f06a4e3"}, - {file = "pyasn1_modules-0.2.7-py3.1.egg", hash = "sha256:9b972f81f59d896cebb9ebb1d44296f1acb28bf7869443c37551f4eed8d74f83"}, - {file = "pyasn1_modules-0.2.7-py3.2.egg", hash = "sha256:64f6aecf26e93f6a3ba3725b4eb9f532551747d7a63ca9ff43aef12f4bf11eac"}, - {file = "pyasn1_modules-0.2.7-py3.3.egg", hash = "sha256:33c220a2701032261a23eea6e9881404ac6fc7ff96f183b5353fea8fc8962547"}, - {file = "pyasn1_modules-0.2.7-py3.4.egg", hash = "sha256:24d54188cb7abd750e0a2cba61b7b46a75608175a0c3c1b1eee08322915d8d21"}, - {file = "pyasn1_modules-0.2.7-py3.5.egg", hash = "sha256:7b4edf07ca2f759d7cf693184be09f22e067c2eb52b03c770d0a2e9de1c67dfd"}, - {file = "pyasn1_modules-0.2.7-py3.6.egg", hash = "sha256:eaf35047a0b068e3e0c2a99618b13b65c98c329661daa78c9d44a4ef0fe8139e"}, - {file = "pyasn1_modules-0.2.7-py3.7.egg", hash = "sha256:c14b107a67ee36a7f183ae9f4803ffde4a03b67f3192eab0a62e851af71371d3"}, + {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"}, + {file = "pyasn1_modules-0.2.8-py2.4.egg", hash = "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"}, + {file = "pyasn1_modules-0.2.8-py2.5.egg", hash = "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"}, + {file = "pyasn1_modules-0.2.8-py2.6.egg", hash = "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"}, + {file = "pyasn1_modules-0.2.8-py2.7.egg", hash = "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"}, + {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"}, + {file = "pyasn1_modules-0.2.8-py3.1.egg", hash = "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d"}, + {file = "pyasn1_modules-0.2.8-py3.2.egg", hash = "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"}, + {file = "pyasn1_modules-0.2.8-py3.3.egg", hash = "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"}, + {file = "pyasn1_modules-0.2.8-py3.4.egg", hash = "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811"}, + {file = "pyasn1_modules-0.2.8-py3.5.egg", hash = "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed"}, + {file = "pyasn1_modules-0.2.8-py3.6.egg", hash = "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"}, + {file = "pyasn1_modules-0.2.8-py3.7.egg", hash = "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"}, ] pycodestyle = [ {file = "pycodestyle-2.5.0-py2.py3-none-any.whl", hash = "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56"}, @@ -2228,8 +2265,8 @@ pycryptodome = [ {file = "pycryptodome-3.9.4.tar.gz", hash = "sha256:a168e73879619b467072509a223282a02c8047d932a48b74fbd498f27224aa04"}, ] pydocstyle = [ - {file = "pydocstyle-5.0.1-py3-none-any.whl", hash = "sha256:4167fe954b8f27ebbbef2fbcf73c6e8ad1e7bb31488fce44a69fdfc4b0cd0fae"}, - {file = "pydocstyle-5.0.1.tar.gz", hash = "sha256:a0de36e549125d0a16a72a8c8c6c9ba267750656e72e466e994c222f1b6e92cb"}, + {file = "pydocstyle-5.0.2-py3-none-any.whl", hash = "sha256:da7831660b7355307b32778c4a0dbfb137d89254ef31a2b2978f50fc0b4d7586"}, + {file = "pydocstyle-5.0.2.tar.gz", hash = "sha256:f4f5d210610c2d153fae39093d44224c17429e2ad7da12a8b419aba5c2f614b5"}, ] pyflakes = [ {file = "pyflakes-2.1.1-py2.py3-none-any.whl", hash = "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0"}, @@ -2308,27 +2345,27 @@ qrcode = [ {file = "qrcode-6.1.tar.gz", hash = "sha256:505253854f607f2abf4d16092c61d4e9d511a3b4392e60bff957a68592b04369"}, ] regex = [ - {file = "regex-2020.1.7-cp27-cp27m-win32.whl", hash = "sha256:e77f64a3ae8b9a555e170a3908748b4e2ccd0c58f8385f328baf8fc70f9ea497"}, - {file = "regex-2020.1.7-cp27-cp27m-win_amd64.whl", hash = "sha256:841056961d441f05b949d9003e7f2b5d51a11dd52d8bd7c0a5325943b6a0ea6b"}, - {file = "regex-2020.1.7-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:bcd9bcba67ae8d1e1b21426ea7995f7ca08260bea601ba15e13e5ca8588208ef"}, - {file = "regex-2020.1.7-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6d999447f77b1b638ea620bde466b958144af90ac2e9b1f23b98a79ced14ce3f"}, - {file = "regex-2020.1.7-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:b2faf1dce478c0ca1c92575bdc48b7afdce3a887a02afb6342fae476af41bbe2"}, - {file = "regex-2020.1.7-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:a4677dc8245f1127b70fa79fb7f15a61eae0fee36ae15cbbe017207485fe9a5c"}, - {file = "regex-2020.1.7-cp36-cp36m-win32.whl", hash = "sha256:dd69d165bee099b02d122d1e0dd55a85ebf9a65493dcd17124b628db9edfc833"}, - {file = "regex-2020.1.7-cp36-cp36m-win_amd64.whl", hash = "sha256:ed75b64c6694bbe840b3340191b2039f633fd1ec6fc567454e47d7326eda557f"}, - {file = "regex-2020.1.7-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:93e797cf16e07b315413d1157b5ce7a7c2b28b2b95768e25c0ccd290443661ad"}, - {file = "regex-2020.1.7-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:52814a8423d52a7e0f070dbb79f7bdfce5221992b881f83bad69f8daf4b831c3"}, - {file = "regex-2020.1.7-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ef85a6a15342559bed737dc16dfb1545dc043ca5bf5bce6bff4830f0e7a74395"}, - {file = "regex-2020.1.7-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d47a89e6029852c88fff859dbc9a11dcec820413b4c2510e80ced1c99c3e79ea"}, - {file = "regex-2020.1.7-cp37-cp37m-win32.whl", hash = "sha256:13901ac914de7a7e58a92f99c71415e268e88ac4be8b389d8360c38e64b2f1c5"}, - {file = "regex-2020.1.7-cp37-cp37m-win_amd64.whl", hash = "sha256:08047f4b31254489316b489c24983d72c0b9d520da084b8c624f45891a9c6da2"}, - {file = "regex-2020.1.7-cp38-cp38-manylinux1_i686.whl", hash = "sha256:895f95344182b4ecb84044910e62ad33ca63a7e7b447c7ba858d24e9f1aad939"}, - {file = "regex-2020.1.7-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:79530d60a8644f72f78834c01a2d70a60be110e2f4a0a612b78da23ef60c2730"}, - {file = "regex-2020.1.7-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:ec75e8baa576aed6065b615a8f8e91a05e42b492b24ffd16cbb075ad62fb9185"}, - {file = "regex-2020.1.7-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:15b6f7e10f764c5162242a7db89da51218a38299415ba5e70f235a6a83c53b94"}, - {file = "regex-2020.1.7-cp38-cp38-win32.whl", hash = "sha256:08d042155592c24cbdb81158a99aeeded4493381a1aba5eba9def6d29961042c"}, - {file = "regex-2020.1.7-cp38-cp38-win_amd64.whl", hash = "sha256:46d01bb4139e7051470037f8b9a5b90c48cb77a3d307c2621bf3791bfae4d9d8"}, - {file = "regex-2020.1.7.tar.gz", hash = "sha256:7391eeee49bb3ce895ca43479eaca810f0c2608556711fa02a82075768f81a37"}, + {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"}, + {file = "regex-2020.1.8-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:4eae742636aec40cf7ab98171ab9400393360b97e8f9da67b1867a9ee0889b26"}, + {file = "regex-2020.1.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bd25bb7980917e4e70ccccd7e3b5740614f1c408a642c245019cff9d7d1b6149"}, + {file = "regex-2020.1.8-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3e77409b678b21a056415da3a56abfd7c3ad03da71f3051bbcdb68cf44d3c34d"}, + {file = "regex-2020.1.8-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:07b39bf943d3d2fe63d46281d8504f8df0ff3fe4c57e13d1656737950e53e525"}, + {file = "regex-2020.1.8-cp36-cp36m-win32.whl", hash = "sha256:23e2c2c0ff50f44877f64780b815b8fd2e003cda9ce817a7fd00dea5600c84a0"}, + {file = "regex-2020.1.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27429b8d74ba683484a06b260b7bb00f312e7c757792628ea251afdbf1434003"}, + {file = "regex-2020.1.8-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0e182d2f097ea8549a249040922fa2b92ae28be4be4895933e369a525ba36576"}, + {file = "regex-2020.1.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e3cd21cc2840ca67de0bbe4071f79f031c81418deb544ceda93ad75ca1ee9f7b"}, + {file = "regex-2020.1.8-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ecc6de77df3ef68fee966bb8cb4e067e84d4d1f397d0ef6fce46913663540d77"}, + {file = "regex-2020.1.8-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:26ff99c980f53b3191d8931b199b29d6787c059f2e029b2b0c694343b1708c35"}, + {file = "regex-2020.1.8-cp37-cp37m-win32.whl", hash = "sha256:7bcd322935377abcc79bfe5b63c44abd0b29387f267791d566bbb566edfdd146"}, + {file = "regex-2020.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:10671601ee06cf4dc1bc0b4805309040bb34c9af423c12c379c83d7895622bb5"}, + {file = "regex-2020.1.8-cp38-cp38-manylinux1_i686.whl", hash = "sha256:98b8ed7bb2155e2cbb8b76f627b2fd12cf4b22ab6e14873e8641f266e0fb6d8f"}, + {file = "regex-2020.1.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6a6ba91b94427cd49cd27764679024b14a96874e0dc638ae6bdd4b1a3ce97be1"}, + {file = "regex-2020.1.8-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:6a6ae17bf8f2d82d1e8858a47757ce389b880083c4ff2498dba17c56e6c103b9"}, + {file = "regex-2020.1.8-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:0932941cdfb3afcbc26cc3bcf7c3f3d73d5a9b9c56955d432dbf8bbc147d4c5b"}, + {file = "regex-2020.1.8-cp38-cp38-win32.whl", hash = "sha256:d58e4606da2a41659c84baeb3cfa2e4c87a74cec89a1e7c56bee4b956f9d7461"}, + {file = "regex-2020.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:e7c7661f7276507bce416eaae22040fd91ca471b5b33c13f8ff21137ed6f248c"}, + {file = "regex-2020.1.8.tar.gz", hash = "sha256:d0f424328f9822b0323b3b6f2e4b9c90960b24743d220763c7f07071e0778351"}, ] requests = [ {file = "requests-2.22.0-py2.py3-none-any.whl", hash = "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"}, @@ -2438,7 +2475,7 @@ tqdm = [ {file = "tqdm-4.41.1.tar.gz", hash = "sha256:4789ccbb6fc122b5a6a85d512e4e41fc5acad77216533a6f2b8ce51e0f265c23"}, ] twilio = [ - {file = "twilio-6.35.1.tar.gz", hash = "sha256:c784e55d150ebeb2ba837afbab7168edfb91db57e77a9da49f2a1892688a1930"}, + {file = "twilio-6.35.2.tar.gz", hash = "sha256:a086443642c0e1f13c8f8f087b426ca81ec883efbe496d8279180a49bb9287bc"}, ] typed-ast = [ {file = "typed_ast-1.4.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e"}, @@ -2473,7 +2510,6 @@ urllib3 = [ ] 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 5a49aed0f2f807b3ab2e71a4fb14e4809ce336e3..ca765440c34293939f5bf613c129ec9eb6748c98 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,6 +53,8 @@ django-pwa = "^1.0.6" django-constance = {git = "https://github.com/jazzband/django-constance", rev = "590fa02eb30e377da0eda5cc3a84254b839176a7", extras = ["database"]} django_widget_tweaks = "^1.4.5" django-filter = "^2.2.0" +django-templated-email = "^2.3.0" +html2text = "^2019.9.26" [tool.poetry.extras] ldap = ["django-auth-ldap"]