-
-
Save pije76/10452035 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# encoding: utf-8 | |
import sys, os, getopt | |
from django.core.management import setup_environ | |
import settings | |
setup_environ(settings) | |
from django.db.models import Q | |
from YOUR_SITE.models import QueuedEmail | |
class Usage(Exception): | |
def __init__(self, msg): | |
self.msg = msg | |
def main(argv=None): | |
if argv is None: | |
argv = sys.argv | |
try: | |
try: | |
opts, args = getopt.getopt(argv[1:], "hv", ["help", "verbose"]) | |
except getopt.error, msg: | |
raise Usage(msg) | |
for option, value in opts: | |
if option in ("-v", "--verbose"): | |
verbose = True | |
if option in ("-h", "--help"): | |
raise Usage("QueuedEmail queue flush tool. Use -v for verbose.") | |
except Usage, err: | |
print >> sys.stderr, sys.argv[0].split("/")[-1] + ": " + str(err.msg) | |
print >> sys.stderr, "\t for help use --help" | |
return 2 | |
mailqueue = FSQueuedEmail.objects.filter( | |
Q(status=0) & (Q(to__isnull=False) | Q(toaddress__isnull=False) & Q(subject__isnull=False)) | |
) | |
if verbose: | |
print "###\t Mail queue contains %s items to be sent.\n" % len(mailqueue) | |
for qm in mailqueue: | |
if verbose: | |
print "###\t Sending message..." | |
print "---\t TO:\t\t\t %s" % qm.to | |
print "---\t TOADDRESS:\t\t %s" % qm.toaddress | |
print "---\t SUBJECT:\t\t %s" % qm.subject | |
# output will be 1 if sending was successful | |
# messages will be saved to the DB with the | |
# same number for their status. | |
if qm.sendit() == 1: | |
if verbose: | |
print "---\t Mail sent OK\n" | |
else: | |
print "###\t MAIL FAIL\n" | |
if __name__ == "__main__": | |
sys.exit(main()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.core.mail import send_mail | |
import smtplib | |
class QueuedEmail(models.Model): | |
""" | |
DATABASE EMAIL QUEUE -- | |
QueuedEmail stashes your sites' messages in a table, so you don't have to wait on | |
synchronous calls to django.core.mail.send_mail. Mail stays in the database after | |
sending for as long as you leave them there, which provides a paper trail and | |
a basis for analytics. I wrote it for use with an invitation-only site, where | |
the flushqueuedemail.py script is run with a cron job. | |
USAGE EXAMPLE -- | |
This simple bit here will queue a new message from within any python code: | |
def some_view_function(request): | |
(...) | |
invitation = FSQueuedEmail( | |
toaddress=invite.sentto, | |
subject="Welcome", | |
body=u''' | |
Hello, | |
Welcome to the site, %s. Your username is %s. | |
Regards, | |
The Management | |
''' % ( | |
request.user.get_full_name(), | |
request.user.username, | |
) | |
) | |
invitation.save() | |
(...) | |
You can pass either an instance of django.contrib.auth.models.User in the 'to' param, or use | |
a string with an email address in it with 'toaddress'. One can easily integrate templating, | |
or compose emails programmatically, or embed the email text for quick development and testing. | |
Add this model to your site, and flush the queue with the attached command-line tool (or write your | |
own, it's like one query and one loop, and hey it could be smaller.) | |
Enjoy! | |
-fish2000 | |
""" | |
class Meta: | |
abstract = False | |
verbose_name = "queued email message" | |
verbose_name_plural = "queued email messages" | |
status = models.IntegerField(verbose_name="Status", | |
editable=True, | |
null=False, | |
default=0, | |
choices=( | |
(-1, 'SMTP Fail'), | |
(0, 'Queued'), | |
(1, 'Sent OK'), | |
(2, 'Unexpected Error'), | |
)) | |
createdate = models.DateTimeField('Created on', | |
default=datetime.now, | |
blank=True, | |
editable=False) | |
modifydate = models.DateTimeField('Last modified on', | |
default=datetime.now, | |
blank=True, | |
editable=False) | |
senddate = models.DateTimeField('Send after', | |
default=datetime.now, | |
blank=True, | |
editable=True) | |
subject = models.CharField(verbose_name="Subject", | |
default="", | |
unique=False, | |
blank=True, | |
max_length=255) | |
body = models.TextField(verbose_name="Body", | |
default="", | |
unique=False, | |
blank=True) | |
to = models.ForeignKey(User, | |
default=None, | |
unique=False, | |
blank=True, | |
null=True, | |
verbose_name="To (User)") | |
toaddress = models.EmailField(verbose_name="To (Additional address or addresses)", | |
default=None, | |
unique=False, | |
blank=True, | |
null=True, | |
max_length=255) | |
def save(self, force_insert=False, force_update=False): | |
self.modifydate = datetime.now() | |
super(QueuedEmail, self).save(force_insert, force_update) | |
def sendit(self): | |
if self.senddate < datetime.now(): | |
if self.subject and self.body: | |
if self.toaddress: | |
try: | |
self.status = send_mail( | |
# one can insert [sitename] or somesuch | |
# at the start of the subject here | |
"%s" % self.subject, | |
self.body, | |
settings.EMAIL_HOST_USER, | |
[self.toaddress] | |
) | |
except smtplib.SMTPException: | |
self.status = -1 | |
self.save() | |
else: | |
self.save() | |
elif self.to and self.to.email: | |
try: | |
self.status = send_mail( | |
"%s" % self.subject, | |
self.body, | |
settings.EMAIL_HOST_USER, | |
[self.to.email] | |
) | |
except smtplib.SMTPException: | |
self.status = -1 | |
self.save() | |
else: | |
self.save() | |
return self.status |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment