From f43e6fb5ee9eb4b481e05b659771c0fa90188d31 Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Tue, 9 Feb 2016 16:28:21 +0100 Subject: [PATCH] Import mailqueue app from pgeu --- hamnadmin/hamnadmin/mailqueue/__init__.py | 0 hamnadmin/hamnadmin/mailqueue/admin.py | 5 ++ .../mailqueue/management/__init__.py | 0 .../mailqueue/management/commands/__init__.py | 0 .../management/commands/send_queued_mail.py | 34 ++++++++++++++ .../mailqueue/migrations/0001_initial.py | 22 +++++++++ .../mailqueue/migrations/__init__.py | 0 hamnadmin/hamnadmin/mailqueue/models.py | 11 +++++ hamnadmin/hamnadmin/mailqueue/util.py | 46 +++++++++++++++++++ hamnadmin/hamnadmin/settings.py | 1 + 10 files changed, 119 insertions(+) create mode 100644 hamnadmin/hamnadmin/mailqueue/__init__.py create mode 100644 hamnadmin/hamnadmin/mailqueue/admin.py create mode 100644 hamnadmin/hamnadmin/mailqueue/management/__init__.py create mode 100644 hamnadmin/hamnadmin/mailqueue/management/commands/__init__.py create mode 100755 hamnadmin/hamnadmin/mailqueue/management/commands/send_queued_mail.py create mode 100644 hamnadmin/hamnadmin/mailqueue/migrations/0001_initial.py create mode 100644 hamnadmin/hamnadmin/mailqueue/migrations/__init__.py create mode 100644 hamnadmin/hamnadmin/mailqueue/models.py create mode 100644 hamnadmin/hamnadmin/mailqueue/util.py diff --git a/hamnadmin/hamnadmin/mailqueue/__init__.py b/hamnadmin/hamnadmin/mailqueue/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hamnadmin/hamnadmin/mailqueue/admin.py b/hamnadmin/hamnadmin/mailqueue/admin.py new file mode 100644 index 0000000..ccabb81 --- /dev/null +++ b/hamnadmin/hamnadmin/mailqueue/admin.py @@ -0,0 +1,5 @@ +from django.contrib import admin + +from models import QueuedMail + +admin.site.register(QueuedMail) diff --git a/hamnadmin/hamnadmin/mailqueue/management/__init__.py b/hamnadmin/hamnadmin/mailqueue/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hamnadmin/hamnadmin/mailqueue/management/commands/__init__.py b/hamnadmin/hamnadmin/mailqueue/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hamnadmin/hamnadmin/mailqueue/management/commands/send_queued_mail.py b/hamnadmin/hamnadmin/mailqueue/management/commands/send_queued_mail.py new file mode 100755 index 0000000..6319b2e --- /dev/null +++ b/hamnadmin/hamnadmin/mailqueue/management/commands/send_queued_mail.py @@ -0,0 +1,34 @@ +# Script to send off all queued email. +# +# This script is intended to be run frequently from cron. We queue things +# up in the db so that they get automatically rolled back as necessary, +# but once we reach this point we're just going to send all of them one +# by one. +# +from django.core.management.base import BaseCommand, CommandError +from django.db import connection + +import smtplib + +from hamnadmin.mailqueue.models import QueuedMail + +class Command(BaseCommand): + help = 'Send queued mail' + + def handle(self, *args, **options): + # Grab advisory lock, if available. Lock id is just a random number + # since we only need to interlock against ourselves. The lock is + # automatically released when we're done. + curs = connection.cursor() + curs.execute("SELECT pg_try_advisory_lock(72181378)") + if not curs.fetchall()[0][0]: + raise CommandException("Failed to get advisory lock, existing send_queued_mail process stuck?") + + for m in QueuedMail.objects.all(): + # Yes, we do a new connection for each run. Just because we can. + # If it fails we'll throw an exception and just come back on the + # next cron job. And local delivery should never fail... + smtp = smtplib.SMTP("localhost") + smtp.sendmail(m.sender, m.receiver, m.fullmsg.encode('utf-8')) + smtp.close() + m.delete() diff --git a/hamnadmin/hamnadmin/mailqueue/migrations/0001_initial.py b/hamnadmin/hamnadmin/mailqueue/migrations/0001_initial.py new file mode 100644 index 0000000..cd39282 --- /dev/null +++ b/hamnadmin/hamnadmin/mailqueue/migrations/0001_initial.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='QueuedMail', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('sender', models.EmailField(max_length=100)), + ('receiver', models.EmailField(max_length=100)), + ('fullmsg', models.TextField()), + ], + ), + ] diff --git a/hamnadmin/hamnadmin/mailqueue/migrations/__init__.py b/hamnadmin/hamnadmin/mailqueue/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hamnadmin/hamnadmin/mailqueue/models.py b/hamnadmin/hamnadmin/mailqueue/models.py new file mode 100644 index 0000000..f2e7d19 --- /dev/null +++ b/hamnadmin/hamnadmin/mailqueue/models.py @@ -0,0 +1,11 @@ +from django.db import models + +class QueuedMail(models.Model): + sender = models.EmailField(max_length=100, null=False, blank=False) + receiver = models.EmailField(max_length=100, null=False, blank=False) + # We store the raw MIME message, so if there are any attachments or + # anything, we just push them right in there! + fullmsg = models.TextField(null=False, blank=False) + + def __unicode__(self): + return "%s: %s -> %s" % (self.pk, self.sender, self.receiver) diff --git a/hamnadmin/hamnadmin/mailqueue/util.py b/hamnadmin/hamnadmin/mailqueue/util.py new file mode 100644 index 0000000..2f616b6 --- /dev/null +++ b/hamnadmin/hamnadmin/mailqueue/util.py @@ -0,0 +1,46 @@ +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +from email.mime.nonmultipart import MIMENonMultipart +from email.Utils import formatdate +from email import encoders + +from models import QueuedMail + +def send_simple_mail(sender, receiver, subject, msgtxt, attachments=None, bcc=None, sendername=None, receivername=None): + # attachment format, each is a tuple of (name, mimetype,contents) + # content should be *binary* and not base64 encoded, since we need to + # use the base64 routines from the email library to get a properly + # formatted output message + msg = MIMEMultipart() + msg['Subject'] = subject + if receivername: + msg['To'] = u'{0} <{1}>'.format(receivername, receiver) + else: + msg['To'] = receiver + if sendername: + msg['From'] = u'{0} <{1}>'.format(sendername, sender) + else: + msg['From'] = sender + msg['Date'] = formatdate(localtime=True) + + msg.attach(MIMEText(msgtxt, _charset='utf-8')) + + if attachments: + for filename, contenttype, content in attachments: + main,sub = contenttype.split('/') + part = MIMENonMultipart(main,sub) + part.set_payload(content) + part.add_header('Content-Disposition', 'attachment; filename="%s"' % filename) + encoders.encode_base64(part) + msg.attach(part) + + + # Just write it to the queue, so it will be transactionally rolled back + QueuedMail(sender=sender, receiver=receiver, fullmsg=msg.as_string()).save() + # Any bcc is just entered as a separate email + if bcc: + QueuedMail(sender=sender, receiver=bcc, fullmsg=msg.as_string()).save() + +def send_mail(sender, receiver, fullmsg): + # Send an email, prepared as the full MIME encoded mail already + QueuedMail(sender=sender, receiver=receiver, fullmsg=fullmsg).save() diff --git a/hamnadmin/hamnadmin/settings.py b/hamnadmin/hamnadmin/settings.py index 649f41a..2c6c9b4 100644 --- a/hamnadmin/hamnadmin/settings.py +++ b/hamnadmin/hamnadmin/settings.py @@ -57,6 +57,7 @@ INSTALLED_APPS = ( 'django.contrib.sites', 'django.contrib.staticfiles', 'hamnadmin.register', + 'hamnadmin.mailqueue', 'django.contrib.admin', ) -- 2.39.5