211 lines
7.2 KiB
Python
211 lines
7.2 KiB
Python
import logging
|
|
import smtplib
|
|
try:
|
|
import simplejson as json
|
|
except:
|
|
import json
|
|
|
|
import requests
|
|
|
|
|
|
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, **kwargs):
|
|
'''Customize a template list given an announce category'''
|
|
for template in template_list:
|
|
yield template.format(**kwargs)
|
|
|
|
|
|
def get_template(template_list, **kwargs):
|
|
template_list = get_template_list(template_list, **kwargs)
|
|
return select_template(template_list)
|
|
|
|
|
|
class HomepageTransport(object):
|
|
identifier = 'homepage'
|
|
|
|
def get_choices(self):
|
|
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',
|
|
]
|
|
|
|
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)
|
|
return qs.values_list('identifier', flat=True).distinct()
|
|
|
|
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 = 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'
|
|
|
|
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=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)
|
|
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)
|