diff --git a/portail_citoyen_announces/admin.py b/portail_citoyen_announces/admin.py index ba94b4f..2686cba 100644 --- a/portail_citoyen_announces/admin.py +++ b/portail_citoyen_announces/admin.py @@ -2,6 +2,7 @@ import os from django.contrib import admin from django.contrib.sites.models import get_current_site +from django.db import connection import models import transports @@ -23,7 +24,9 @@ class SendingAction(object): def __call__(self, modeladmin, request, queryset): pid = os.fork() if pid != 0: + connection.close() return + connection.close() transport = transports.get_transport(self.mode) for announce in queryset.select_related(): transport.send(announce) diff --git a/portail_citoyen_announces/forms.py b/portail_citoyen_announces/forms.py index 187574d..934d723 100644 --- a/portail_citoyen_announces/forms.py +++ b/portail_citoyen_announces/forms.py @@ -45,5 +45,6 @@ class SubscriptionForm(forms.Form): for category, transport in wanted_subscriptions: models.Subscription.objects.get_or_create( user=self.user, + identifier=self.user.mobile, category=category, transport=transport) diff --git a/portail_citoyen_announces/templates/portail_citoyen_announces/announce_list.html b/portail_citoyen_announces/templates/portail_citoyen_announces/announce_list.html index 0db6ec7..2541913 100644 --- a/portail_citoyen_announces/templates/portail_citoyen_announces/announce_list.html +++ b/portail_citoyen_announces/templates/portail_citoyen_announces/announce_list.html @@ -9,4 +9,6 @@ {% endif %} {% endfor %} +{% if subscriptions %}

{% trans "Subscriptions" %}: {{ subscriptions|join:", " }}

+{% endif %} diff --git a/portail_citoyen_announces/transports.py b/portail_citoyen_announces/transports.py index d3830ee..7fb18c5 100644 --- a/portail_citoyen_announces/transports.py +++ b/portail_citoyen_announces/transports.py @@ -1,5 +1,12 @@ import logging import smtplib +import re +try: + import simplejson as json +except: + import json + +import requests from django.utils.importlib import import_module @@ -42,24 +49,28 @@ def get_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)()) + 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): +def get_template_list(template_list, **kwargs): '''Customize a template list given an announce category''' for template in template_list: - yield template.format(category=category.identifier) + yield template.format(**kwargs) -def get_template(template_list, category): - template_list = get_template_list(template_list, category) +def get_template(template_list, **kwargs): + template_list = get_template_list(template_list, **kwargs) return select_template(template_list) @@ -70,6 +81,79 @@ class HomepageTransport(object): return (('homepage', _('homepage')),) +class SMSTransport(object): + body_template_list = [ + 'portail_citoyen_announces/{identifier}/body_{category}.txt', + 'portail_citoyen_announces/{identifier}/body.txt', + 'portail_citoyen_announces/body_{category}.txt', + 'portail_citoyen_announces/body.txt', + ] + mobile_re = re.compile('^0[67][0-9]{8}$') + + def __init__(self, url, from_mobile, login=None, password=None, identifier='sms'): + self.url = url + self.from_mobile = from_mobile + self.login = login + self.password = password + self.identifier = identifier + + def get_choices(self): + return ((self.identifier, self.identifier),) + + def get_subscriptions(self, category): + return models.Subscription.objects.filter(category=category, + transport=self.identifier) + + def get_sms(self, category): + qs = self.get_subscriptions(category) + for subscription in qs: + sms = '' + if subscription.identifier: + sms = subscription.identifier + elif subscription.user: + sms = subscription.user.mobile + if self.mobile_re.match(sms): + yield sms + + def send(self, announce): + category = announce.category + site = category.site + body_template = get_template(self.body_template_list, + category=category.identifier, identifier=self.identifier) + ctx = Context({ 'announce': announce, 'site': site, 'category': category }) + body = body_template.render(ctx) + sms = list(self.get_sms(category)) + logger.info(u'sending announce %(announce)s through %(mode)s to %(count)s emails', + dict(announce=announce, mode=self.identifier, count=len(sms))) + try: + payload = { + 'message': body, + 'from': self.from_mobile, + 'to': list(sms), + } + response = requests.post(self.url, data=json.dumps(payload)) + json_response = response.json() + if json_response['err'] != 0: + msg = u'unable to send announce "%s" on site "%s": %s' % (announce, + site, json_response) + logger.error(msg) + else: + logger.info('announce %(announce)s sent succesfully', + dict(announce=announce)) + msg = u'ok' + 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) + models.Sent.objects.create( + announce=announce, + transport=self.identifier, + result=msg) + class EmailTransport(object): identifier = 'email' @@ -101,8 +185,10 @@ class EmailTransport(object): 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) + subject_template = get_template(self.subject_template_list, + category=category.identifier, identifier=self.identifier) + body_template = get_template(self.body_template_list, + category=category.identifier, identifier=self.identifier) ctx = Context({ 'announce': announce, 'site': site, 'category': category }) subject = subject_template.render(ctx).replace('\r', '').replace('\n', '') body = body_template.render(ctx)