import logging import smtplib from django.utils.importlib import import_module from django.core.mail import EmailMessage from django.template.loader import select_template from django.template import Context from django.utils.translation import ugettext_lazy as _ import app_settings import models logger = logging.getLogger() def get_transport_choices(include=[], exclude=[]): for transport in get_transports(): if include and transport.identifer not in include: continue if exclude and transport.identifer in exclude: continue for identifier, display_name in transport.get_choices(): yield (identifier, display_name) def get_transport(identifier): transports = get_transports() for transport in transports: if identifier == transport.identifier: return transport return None __TRANSPORTS = None def get_transports(): global __TRANSPORTS if __TRANSPORTS is None: transports = [] for class_path in app_settings.transport_modes: if not isinstance(class_path, basestring): class_path, kwargs = class_path else: kwargs = {} module_path, class_name = class_path.rsplit('.', 1) try: module = import_module(module_path) transports.append(getattr(module, class_name)(**kwargs)) except (ImportError, AttributeError), e: raise ImportError('Unable to load transport class %s' % class_path, e) __TRANSPORTS = transports return __TRANSPORTS def get_template_list(template_list, category): '''Customize a template list given an announce category''' for template in template_list: yield template.format(category=category.identifier) def get_template(template_list, category): template_list = get_template_list(template_list, category) return select_template(template_list) class HomepageTransport(object): identifier = 'homepage' def get_choices(self): return (('homepage', _('homepage')),) class EmailTransport(object): identifier = 'email' subject_template_list = [ 'portail_citoyen_announces/email/subject_{category}.txt', 'portail_citoyen_announces/email/subject.txt', 'portail_citoyen_announces/subject_{category}.txt', 'portail_citoyen_announces/subject.txt', ] body_template_list = [ 'portail_citoyen_announces/email/body_{category}.txt', 'portail_citoyen_announces/email/body.txt', 'portail_citoyen_announces/body_{category}.txt', 'portail_citoyen_announces/body.txt', ] def get_choices(self): return (('email', _('email')),) def get_subscriptions(self, category): return models.Subscription.objects.filter(category=category, transport=self.identifier) def get_emails(self, category): qs = self.get_subscriptions(category) return qs.values_list('identifier', flat=True).distinct() def send(self, announce): category = announce.category site = category.site subject_template = get_template(self.subject_template_list, category) body_template = get_template(self.body_template_list, category) ctx = Context({ 'announce': announce, 'site': site, 'category': category }) subject = subject_template.render(ctx).replace('\r', '').replace('\n', '') body = body_template.render(ctx) emails = self.get_emails(category) logger.info(u'sending announce %(announce)s through %(mode)s to %(count)s emails', dict(announce=announce, mode=self.identifier, count=len(emails))) try: message = EmailMessage(subject=subject, body=body, from_email=app_settings.default_from, bcc=emails) message.send() except smtplib.SMTPException, e: msg = u'unable to send announce "%s" on site "%s": %s' % (announce, site, e) logger.error(msg) except Exception, e: msg = u'unable to send announce "%s" on site "%s": %s' % (announce, site, e) logger.exception(msg) else: logger.info('announce %(announce)s sent succesfully', dict(announce=announce)) msg = u'ok' models.Sent.objects.create( announce=announce, transport=self.identifier, result=msg)