import logging from django.core import mail from django.contrib.auth.models import User from django.contrib.sites.models import Site from django.template import loader, Context class MassMailer(object): ''' This Class will send E-Mails via an SMTP Connection to multiple recipients. Each E-Mail will be send individually and can be personalized. It will be send as HTML and Plain-Text Message. ''' context = {} headers = {} subject = None txt_template = None html_template = None def __init__(self, subject=None, template=None, context=None): self.mail_queue = set() self.recipients = set() self.subject = subject self.template = 'email' self.context = context self.log = logging.getLogger('maillog') def open_smtp_connection(self): try: self.smtp_connection = mail.get_connection(fail_silently=False) self.smtp_connection.open() self.mail_counter = 0 except: self.log.error('Connection to SMTP server failed. Giving up!') raise False else: self.log.debug('Connected to SMTP server.') return True def close_smtp_connection(self): self.smtp_connection.close() self.log.debug("closed the SMTP connection. I'm done") def add_recipient(self, recipient): if isinstance(recipient, User): self.recipients.add(recipient) else: self.log.warn('%s is not a User Object!', recipient) def add_recipients(self, user_list): for user in user_list: if isinstance(user, User): self.log.debug('Adding %s as Recipient' % user) self.recipients.add(user) else: self.log.warn('%s is not a User Object!', user) def process_mails(self): mail_context = Context(self.context) mail_context['site'] = Site.objects.get_current() self.txt_template = loader.get_template(self.txt_template) if self.html_template: self.html_template = loader.get_template(self.html_template) for recipient in self.recipients: mail_context['recipient'] = recipient mail_to = "%s %s <%s>" % (recipient.first_name, recipient.last_name, recipient.email) message = mail.EmailMultiAlternatives( subject=self.subject, body=self.txt_template.render(mail_context), to=(mail_to,), headers=self.headers ) if self.html_template: message.attach_alternative( self.html_template.render(mail_context), "text/html" ) self.mail_queue.add(message) def set_header(self, name, value): self.headers[name] = value def send(self): ''' Process the E-Mails and send them ''' self.process_mails() if len(self.mail_queue) == 0: self.log.info('No recipients for eMail "%s", bye!', self.subject) return True else: self.log.info('Sending eMail "%s" to %d people', self.subject, len(self.mail_queue)) self.log.debug(self.recipients) self.open_smtp_connection() for mail in self.mail_queue: try: mail.send() except: self.log.warn("Mail failed for: %s", mail.to) else: self.log.info("Mail sent successful to: %s" % mail.to) self.close_smtp_connection()