2019-10-08 12:30:17 +00:00
|
|
|
"""email factor tasks"""
|
|
|
|
from smtplib import SMTPException
|
|
|
|
from typing import Any, Dict, List
|
|
|
|
|
|
|
|
from celery import group
|
|
|
|
from django.core.mail import EmailMessage
|
2019-10-11 12:24:58 +00:00
|
|
|
from structlog import get_logger
|
2019-10-08 12:30:17 +00:00
|
|
|
|
|
|
|
from passbook.factors.email.models import EmailFactor
|
|
|
|
from passbook.root.celery import CELERY_APP
|
|
|
|
|
2019-10-11 12:24:58 +00:00
|
|
|
LOGGER = get_logger()
|
|
|
|
|
2019-10-08 12:30:17 +00:00
|
|
|
|
|
|
|
def send_mails(factor: EmailFactor, *messages: List[EmailMessage]):
|
|
|
|
"""Wrapper to convert EmailMessage to dict and send it from worker"""
|
|
|
|
tasks = []
|
|
|
|
for message in messages:
|
|
|
|
tasks.append(_send_mail_task.s(factor.pk, message.__dict__))
|
|
|
|
lazy_group = group(*tasks)
|
|
|
|
promise = lazy_group()
|
|
|
|
return promise
|
|
|
|
|
2019-12-31 11:51:16 +00:00
|
|
|
|
2019-10-08 12:30:17 +00:00
|
|
|
@CELERY_APP.task(bind=True)
|
|
|
|
def _send_mail_task(self, email_factor_pk: int, message: Dict[Any, Any]):
|
|
|
|
"""Send E-Mail according to EmailFactor parameters from background worker.
|
|
|
|
Automatically retries if message couldn't be sent."""
|
|
|
|
factor: EmailFactor = EmailFactor.objects.get(pk=email_factor_pk)
|
|
|
|
backend = factor.backend
|
|
|
|
backend.open()
|
|
|
|
# Since django's EmailMessage objects are not JSON serialisable,
|
|
|
|
# we need to rebuild them from a dict
|
|
|
|
message_object = EmailMessage()
|
|
|
|
for key, value in message.items():
|
|
|
|
setattr(message_object, key, value)
|
|
|
|
message_object.from_email = factor.from_address
|
2019-10-11 12:24:58 +00:00
|
|
|
LOGGER.debug("Sending mail", to=message_object.to)
|
2019-10-08 12:30:17 +00:00
|
|
|
try:
|
|
|
|
num_sent = factor.backend.send_messages([message_object])
|
|
|
|
except SMTPException as exc:
|
|
|
|
raise self.retry(exc=exc)
|
|
|
|
if num_sent != 1:
|
|
|
|
raise self.retry()
|