Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

send_queued_mail.py 2.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import tempfile
  2. import sys
  3. from django.core.management.base import BaseCommand
  4. from django.db import connection
  5. from django.db.models import Q
  6. from django.utils.timezone import now
  7. from ...lockfile import FileLock, FileLocked
  8. from ...mail import send_queued
  9. from ...models import Email, STATUS
  10. from ...logutils import setup_loghandlers
  11. logger = setup_loghandlers()
  12. default_lockfile = tempfile.gettempdir() + "/post_office"
  13. class Command(BaseCommand):
  14. def add_arguments(self, parser):
  15. parser.add_argument(
  16. '-p', '--processes',
  17. type=int,
  18. default=1,
  19. help='Number of processes used to send emails',
  20. )
  21. parser.add_argument(
  22. '-L', '--lockfile',
  23. default=default_lockfile,
  24. help='Absolute path of lockfile to acquire',
  25. )
  26. parser.add_argument(
  27. '-l', '--log-level',
  28. type=int,
  29. help='"0" to log nothing, "1" to only log errors',
  30. )
  31. def handle(self, *args, **options):
  32. logger.info('Acquiring lock for sending queued emails at %s.lock' %
  33. options['lockfile'])
  34. try:
  35. with FileLock(options['lockfile']):
  36. while 1:
  37. try:
  38. send_queued(options['processes'],
  39. options.get('log_level'))
  40. except Exception as e:
  41. logger.error(e, exc_info=sys.exc_info(),
  42. extra={'status_code': 500})
  43. raise
  44. # Close DB connection to avoid multiprocessing errors
  45. connection.close()
  46. if not Email.objects.filter(status=STATUS.queued) \
  47. .filter(Q(scheduled_time__lte=now()) | Q(scheduled_time=None)).exists():
  48. break
  49. except FileLocked:
  50. logger.info('Failed to acquire lock, terminating now.')