Project

General

Profile

Download (4.17 KB) Statistics
| Branch: | Tag: | Revision:

root / corbo / utils.py @ d0bd7a5a

1
# corbo - Announces Manager
2
# Copyright (C) 2017 Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

    
17
import os
18
import logging
19
import requests
20
import urlparse
21
import hashlib
22
from html2text import HTML2Text
23
from emails.django import Message
24
from lxml import etree
25

    
26
from django.conf import settings
27
from django.template import loader, Context
28
from django.utils.translation import activate
29
from django.core.files.storage import DefaultStorage
30
from django.core.urlresolvers import reverse
31
from django.core import signing
32

    
33

    
34
UNSUBSCRIBE_LINK_PLACEHOLDER = '%%UNSUBSCRIBE_LINK_PLACEHOLDER%%'
35

    
36

    
37
def transform_image_src(src, **kwargs):
38
    return urlparse.urljoin(settings.SITE_BASE_URL, src)
39

    
40
def send_email(title, content, destinations, category_id):
41
    logger = logging.getLogger(__name__)
42
    total_sent = 0
43
    handler = HTML2Text()
44
    activate(settings.LANGUAGE_CODE)
45
    template = loader.get_template('corbo/announce.html')
46
    message = Message(subject=title, mail_from=settings.DEFAULT_FROM_EMAIL,
47
            html=template.render(
48
            Context({'content': content,
49
            'unsubscribe_link_placeholder': UNSUBSCRIBE_LINK_PLACEHOLDER})))
50

    
51
    # perform transformations in message html, like inline css parsing
52
    message.transformer.apply_to_images(func=transform_image_src)
53
    message.transformer.load_and_transform(images_inline=True)
54
    message.transformer.save()
55
    orig_html = message.html
56
    handler.body_width = 0
57
    orig_text = handler.handle(message.html)
58

    
59
    for dest in destinations:
60
        unsubscribe_token = signing.dumps({'category': category_id,
61
                                           'identifier': dest})
62
        unsubscribe_link = urlparse.urljoin(settings.SITE_BASE_URL, reverse(
63
            'unsubscribe', kwargs={'unsubscription_token': unsubscribe_token}))
64
        message.set_headers({'List-Unsubscribe': '<%s>' % unsubscribe_link})
65
        message.html = orig_html.replace(UNSUBSCRIBE_LINK_PLACEHOLDER, unsubscribe_link)
66
        message.text = orig_text.replace(UNSUBSCRIBE_LINK_PLACEHOLDER, unsubscribe_link)
67

    
68
        sent = message.send(to=dest)
69
        if sent:
70
            total_sent += 1
71
            logger.info('Announce "%s" sent to %s', title, dest)
72
        else:
73
            logger.warning('Error occured while sending announce "%s" to %s.',
74
                           title, dest)
75
    return total_sent
76

    
77
def send_sms(content, destinations):
78
    from django.conf import settings
79
    logger = logging.getLogger(__name__)
80
    sent = 0
81
    if not destinations:
82
        return sent
83
    if settings.SMS_GATEWAY_URL:
84
        # remove all HTML formatting from content
85
        html_content = etree.HTML(content)
86
        # remove identifier prefix
87
        destinations = [d.replace('sms:', '') for d in destinations]
88
        data = {'to': destinations,
89
                'message': etree.tostring(html_content, method='text'),
90
                'from': settings.SMS_EXPEDITOR}
91
        try:
92
            response = requests.post(settings.SMS_GATEWAY_URL, json=data, proxies=settings.REQUESTS_PROXIES)
93
            response.raise_for_status()
94
            if not response.json()['err']:
95
                # if no error returned by SMS gateway presume the that content
96
                # was delivered to all destinations
97
                sent = len(destinations)
98
            else:
99
                logger.warning('Error occured while sending sms: %s', response.json()['err_desc'])
100
        except requests.RequestException as e:
101
            logger.warning('Failed to reach SMS gateway: %s', e)
102
            return sent
103
    else:
104
        logger.error('SMS send requested but no SMS gateway defined.')
105
    return sent
(10-10/13)