# -*- coding: utf-8 -*- from __future__ import unicode_literals import os import logging from django.conf import settings from django.core.mail import EmailMultiAlternatives from django.template.base import TemplateDoesNotExist from django.template.loader import render_to_string logger = logging.getLogger(__name__) class EmailTemplate(object): """Provide pattern to organize and send your common email messages. All Emails should be stored on these paths: /email//subject.txt /email//message.html /email//message.txt Examples: >>> email = EmailTemplate('', {'date', datetime.now().date}) >>> email.send(['foo@bar.com'], context={'name': 'Bill'}) Only process your email templates: >>> user_data = {'name': 'Bill'} >>> subject = email.get_subject(user_data) >>> message = email.get_message_txt(user_data) >>> from django.core.mail import send_mail >>> send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, ['bill@foo.bar']) Prevents method "send" to massive send. >>> email = EmailTemplate('', {'date', datetime.now().date}) >>> messages = [] >>> messages.append(email.send(['bill@foo.bar'], context={'name': 'Bill'}, commit=False)) >>> messages.append(email.send(['jonh@foo.bar'], context={'name': 'Jonh'}, commit=False)) >>> from django.core import mail >>> connection = mail.get_connection() >>> connection.send_messages(messages) """ template_base_dir = 'email' template_subject = 'subject.txt' template_message_html = 'message.html' template_message_txt = 'message.txt' def __init__(self, name, default_context=None, **kwargs): self.name = name self.default_context = default_context or {} def __unicode__(self): return self.name @property def template_dir(self): return os.path.join(self.template_base_dir, self.name) @property def subject(self): """Template path of subject""" return os.path.join(self.template_dir, self.template_subject) @property def message_html(self): """Template path of html message""" return os.path.join(self.template_dir, self.template_message_html) @property def message_txt(self): """Template path of text message""" return os.path.join(self.template_dir, self.template_message_txt) def _get_template(self, template, context=None): _context = self.default_context.copy() if context: _context.update(context) try: return render_to_string(template, _context) except TemplateDoesNotExist: logger.debug("Email template {} doesn't exists.".format(template)) return None def get_subject(self, context=None): return self._get_template(self.subject, context) def get_message_html(self, context=None): return self._get_template(self.message_html, context) def get_message_txt(self, context=None): return self._get_template(self.message_txt, context) def send(self, recipient_list, context=None, commit=True, **kwargs): """Send email message and return EmailMessage instance. Params: recipient_list -> List of emails to sent. context -> Contex data of template. commit -> If false, prevents to send message, only returning the EmailMessage instance. kwargs -> Uses to pass other EmailMessage params like from_email, bcc, cc and headers. """ subject = self.get_subject(context) msg_html = self.get_message_html(context) msg_txt = self.get_message_txt(context) message = EmailMultiAlternatives( subject=subject, body=msg_txt, to=recipient_list, from_email=kwargs.get('from_email', settings.DEFAULT_FROM_EMAIL), bcc=kwargs.get('bcc'), cc=kwargs.get('cc'), headers=kwargs.get('headers')) if msg_html: message.attach_alternative(msg_html, 'text/html') if commit: sent = message.send( fail_silently=kwargs.get('fail_silently', False)) return message