mail_backends.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import logging
  2. from celery import shared_task
  3. from django.conf import settings
  4. from django.core.mail import get_connection
  5. from django.core.mail.backends.base import BaseEmailBackend
  6. from djcelery_email.utils import dict_to_email, email_to_dict
  7. logger = logging.getLogger(__name__)
  8. class MultiLaneEmailBackend(BaseEmailBackend):
  9. config = {'ignore_result': True, 'queue': 'celery'}
  10. default_backend = 'django.core.mail.backends.smtp.EmailBackend'
  11. def __init__(self, lane: str, fail_silently=False, **kwargs):
  12. self.config.update(name=lane)
  13. self.config.update(settings.TASK_CONFIG[lane])
  14. self.task_kwargs = kwargs.copy()
  15. # Make a copy tor ensure we don't modify input dict when we set the 'lane'
  16. self.task_kwargs['debug'] = self.task_kwargs.pop('debug', {}).copy()
  17. self.task_kwargs['debug']['lane'] = lane
  18. super().__init__(fail_silently)
  19. def send_messages(self, email_messages):
  20. dict_messages = [email_to_dict(msg) for msg in email_messages]
  21. TASKS[self.config['name']].delay(dict_messages, **self.task_kwargs)
  22. return len(email_messages)
  23. @staticmethod
  24. def _run_task(messages, debug, **kwargs):
  25. logger.warning('Sending queued email, details: %s', debug)
  26. kwargs.setdefault('backend', kwargs.pop('backbackend', MultiLaneEmailBackend.default_backend))
  27. with get_connection(**kwargs) as connection:
  28. return connection.send_messages([dict_to_email(message) for message in messages])
  29. @property
  30. def task(self):
  31. return shared_task(**self.config)(self._run_task)
  32. # Define tasks so that Celery can discovery them
  33. TASKS = {
  34. name: MultiLaneEmailBackend(lane=name, fail_silently=True).task
  35. for name in settings.TASK_CONFIG
  36. }