This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
corbo/corbo/utils.py

119 lines
4.7 KiB
Python

# corbo - Announces Manager
# Copyright (C) 2017 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import re
import logging
import requests
import hashlib
from html2text import HTML2Text
from emails.django import Message
from lxml import etree
from django.conf import settings
from django.template import loader
from django.utils.translation import activate
from django.core.files.storage import DefaultStorage
from django.core.urlresolvers import reverse
from django.core import signing
from django.utils.six.moves.urllib import parse as urlparse
UNSUBSCRIBE_LINK_PLACEHOLDER = '%%UNSUBSCRIBE_LINK_PLACEHOLDER%%'
def transform_image_src(src, **kwargs):
return urlparse.urljoin(settings.SITE_BASE_URL, src)
def send_email(title, content, destinations, category_id):
logger = logging.getLogger(__name__)
total_sent = 0
handler = HTML2Text()
activate(settings.LANGUAGE_CODE)
template = loader.get_template('corbo/announce.html')
message = Message(subject=title, mail_from=settings.DEFAULT_FROM_EMAIL,
html=template.render(
{'content': content, 'unsubscribe_link_placeholder': UNSUBSCRIBE_LINK_PLACEHOLDER}))
# perform transformations in message html, like inline css parsing
message.transformer.apply_to_images(func=transform_image_src)
message.transformer.load_and_transform(images_inline=True)
message.transformer.save()
orig_html = message.html
handler.body_width = 0
orig_text = handler.handle(message.html)
for dest in destinations:
unsubscribe_token = signing.dumps({'category': category_id,
'identifier': dest})
unsubscribe_link = urlparse.urljoin(settings.SITE_BASE_URL, reverse(
'unsubscribe', kwargs={'unsubscription_token': unsubscribe_token}))
message.set_headers({'List-Unsubscribe': '<%s>' % unsubscribe_link})
message.html = orig_html.replace(UNSUBSCRIBE_LINK_PLACEHOLDER, unsubscribe_link)
message.text = orig_text.replace(UNSUBSCRIBE_LINK_PLACEHOLDER, unsubscribe_link)
sent = message.send(to=dest)
if sent:
total_sent += 1
logger.info('Announce "%s" sent to %s', title, dest)
else:
logger.warning('Error occured while sending announce "%s" to %s.',
title, dest)
return total_sent
def send_sms(content, destinations):
from django.conf import settings
logger = logging.getLogger(__name__)
sent = 0
if not destinations:
return sent
if settings.SMS_GATEWAY_URL:
# remove all HTML formatting from content
html_content = etree.HTML(content)
# remove identifier prefix
destinations = [d.replace('sms:', '') for d in destinations]
data = {'to': destinations,
'message': etree.tostring(html_content, method='text'),
'from': settings.SMS_EXPEDITOR}
try:
response = requests.post(settings.SMS_GATEWAY_URL, json=data, proxies=settings.REQUESTS_PROXIES)
response.raise_for_status()
if not response.json()['err']:
# if no error returned by SMS gateway presume the that content
# was delivered to all destinations
sent = len(destinations)
else:
logger.warning('Error occured while sending sms: %s', response.json()['err_desc'])
except requests.RequestException as e:
logger.warning('Failed to reach SMS gateway: %s', e)
return sent
else:
logger.error('SMS send requested but no SMS gateway defined.')
return sent
def format_phonenumber(phonenumber):
'''formats a given string into a phone number by removing:
1. parenthesis and their content
2. every characters but numbers and plus signs
3. all plus signs after the first character.
'''
phonenumber = re.sub('\(.*?\)', '', phonenumber)
phonenumber = re.sub('[^\d+]', '', phonenumber)
if phonenumber:
phonenumber = phonenumber[0] + re.sub('[\+]', '', phonenumber[1:])
return phonenumber