Projet

Général

Profil

0003-add-orange-contact-everyone-SMS-backend-9163.patch

Benjamin Dauvergne, 02 décembre 2015 16:45

Télécharger (12,2 ko)

Voir les différences:

Subject: [PATCH 3/5] add orange contact everyone SMS backend (#9163)

 MANIFEST.in                                       |  1 +
 passerelle/apps/orange/__init__.py                |  0
 passerelle/apps/orange/forms.py                   | 14 ++++++
 passerelle/apps/orange/migrations/0001_initial.py | 31 ++++++++++++
 passerelle/apps/orange/migrations/__init__.py     |  0
 passerelle/apps/orange/models.py                  | 59 +++++++++++++++++++++++
 passerelle/apps/orange/orange.pem                 | 15 ++++++
 passerelle/apps/orange/soap.py                    | 55 +++++++++++++++++++++
 passerelle/apps/orange/urls.py                    | 13 +++++
 passerelle/apps/orange/views.py                   | 37 ++++++++++++++
 passerelle/settings.py                            |  2 +
 passerelle/urls.py                                | 10 ++++
 12 files changed, 237 insertions(+)
 create mode 100644 passerelle/apps/orange/__init__.py
 create mode 100644 passerelle/apps/orange/forms.py
 create mode 100644 passerelle/apps/orange/migrations/0001_initial.py
 create mode 100644 passerelle/apps/orange/migrations/__init__.py
 create mode 100644 passerelle/apps/orange/models.py
 create mode 100644 passerelle/apps/orange/orange.pem
 create mode 100644 passerelle/apps/orange/soap.py
 create mode 100644 passerelle/apps/orange/urls.py
 create mode 100644 passerelle/apps/orange/views.py
MANIFEST.in
5 5
# locales
6 6
recursive-include passerelle/locale *.po *.mo
7 7

  
8
include passerelle/apps/orange/orange.pem
8 9
include LICENSE
9 10
include MANIFEST.in
10 11
include VERSION
passerelle/apps/orange/forms.py
1
from django.utils.text import slugify
2
from django import forms
3

  
4
from .models import OrangeSMSGateway
5

  
6
class OrangeSMSGatewayForm(forms.ModelForm):
7
    class Meta:
8
        model = OrangeSMSGateway
9
        exclude = ('slug', 'users')
10

  
11
    def save(self, commit=True):
12
        if not self.instance.slug:
13
            self.instance.slug = slugify(self.instance.title)
14
        return super(OrangeSMSGatewayForm, self).save(commit=commit)
passerelle/apps/orange/migrations/0001_initial.py
1
# -*- coding: utf-8 -*-
2
from __future__ import unicode_literals
3

  
4
from django.db import models, migrations
5
import passerelle.sms
6

  
7

  
8
class Migration(migrations.Migration):
9

  
10
    dependencies = [
11
        ('base', '0002_auto_20151009_0326'),
12
    ]
13

  
14
    operations = [
15
        migrations.CreateModel(
16
            name='OrangeSMSGateway',
17
            fields=[
18
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
19
                ('title', models.CharField(max_length=50)),
20
                ('slug', models.SlugField()),
21
                ('description', models.TextField()),
22
                ('keystore', models.FileField(help_text='Certificate and private key in PEM format', upload_to=b'orange', null=True, verbose_name='Keystore', blank=True)),
23
                ('users', models.ManyToManyField(to='base.ApiUser', blank=True)),
24
            ],
25
            options={
26
                'db_table': 'sms_orange',
27
                'verbose_name': 'Orange',
28
            },
29
            bases=(models.Model, passerelle.sms.SMSGatewayMixin),
30
        ),
31
    ]
passerelle/apps/orange/models.py
1
import re
2
import urllib
3
import urllib2
4
import logging
5
import json
6

  
7
from django.utils.translation import ugettext_lazy as _
8
from django.db import models
9
from django.core.urlresolvers import reverse
10

  
11
from passerelle.base.models import BaseResource
12
from passerelle.sms import SMSGatewayMixin
13

  
14
from . import soap
15

  
16
class OrangeError(Exception):
17
    pass
18

  
19

  
20
class OrangeSMSGateway(BaseResource, SMSGatewayMixin):
21
    keystore = models.FileField(upload_to='orange',
22
            blank=True, null=True,
23
            verbose_name=_('Keystore'),
24
            help_text=_('Certificate and private key in PEM format'))
25
    default_country_code = '33'
26

  
27
    class Meta:
28
        verbose_name = 'Orange'
29
        db_table = 'sms_orange'
30

  
31
    @classmethod
32
    def get_verbose_name(cls):
33
        return cls._meta.verbose_name
34

  
35
    @classmethod
36
    def get_icon_class(cls):
37
        return 'phone'
38

  
39
    def get_absolute_url(self):
40
        return reverse('orange-view', kwargs={'slug': self.slug})
41

  
42
    @classmethod
43
    def get_add_url(cls):
44
        return reverse('orange-add')
45

  
46
    def get_edit_url(self):
47
        return reverse('orange-edit', kwargs={'slug': self.slug})
48

  
49
    def get_delete_url(self):
50
        return reverse('orange-delete', kwargs={'slug': self.slug})
51

  
52
    def send(self, text, sender, destinations):
53
        logger = logging.getLogger('passerelle.apps.orange')
54
        """Send a SMS using the Orange provider"""
55
        # unfortunately it lacks a batch API...
56
        destinations = self.clean_numbers(destinations, self.default_country_code)
57
        text = unicode(text).encode('utf-8')
58

  
59
        soap.ContactEveryoneSoap(instance=self).send_message(destinations, text)
passerelle/apps/orange/orange.pem
1
-----BEGIN CERTIFICATE-----
2
MIICWzCCAcQCAQAwDQYJKoZIhvcNAQEEBQAwdjELMAkGA1UEBhMCRlIxDzANBgNV
3
BAgTBkZyYW5jZTENMAsGA1UEBxMEQ2FlbjEXMBUGA1UEChMORnJhbmNlIFRlbGVj
4
b20xDDAKBgNVBAsTA0RQUzEMMAoGA1UEAxMDRERQMRIwEAYJKoZIhvcNAQkBFgNE
5
SU0wHhcNMDYxMTA4MjAyNDUxWhcNMTYxMTA1MjAyNDUxWjB2MQswCQYDVQQGEwJG
6
UjEPMA0GA1UECBMGRnJhbmNlMQ0wCwYDVQQHEwRDYWVuMRcwFQYDVQQKEw5GcmFu
7
Y2UgVGVsZWNvbTEMMAoGA1UECxMDRFBTMQwwCgYDVQQDEwNERFAxEjAQBgkqhkiG
8
9w0BCQEWA0RJTTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxp5nnfYr4ZsV
9
QgIzYkz42Urc+0z49cm8JL5DQAcceIUpWYnCOSjDCEivvkYlBGEaSQhx6goLgpAk
10
6264BhFIa9tFJBz0VCbZ5erGANNFpi1zK9nglfGMkfgQmPXFcVF+hi9ztff+WHGR
11
SknuxzXAICG0/PfPy/LcpVC9E35IkG8CAwEAATANBgkqhkiG9w0BAQQFAAOBgQAk
12
plMn6da0Yu2YZ7dSP9UBrWygN3iD93Krk5H9KcJCFKXRcZsKw/871J+fFxOFxe5u
13
l/wraMBF+oo9aMBIsrHwzPkPr6/T3+cYScJAcoP0vRqGjbhio1BvoSvH4lsfmJsF
14
L9cgc58xgDNwztKHqggDtiFCWVEBpYk2jbMnoy7/xg==
15
-----END CERTIFICATE-----
passerelle/apps/orange/soap.py
1
import datetime
2
import os.path
3

  
4

  
5
from passerelle.soap import Soap
6
from passerelle.xml_builder import XmlBuilder
7

  
8

  
9
class ContactEveryoneSoap(Soap):
10
    WSDL_URL = ('https://www.api-contact-everyone.fr.orange-business.com/'
11
                'ContactEveryone/services/MultiDiffusionWS?wsdl')
12
    ORANGE_CERTIFICATE = os.path.join(os.path.dirname(__file__), 'orange.pem')
13

  
14
    url = WSDL_URL
15

  
16
    class ProfileListBuilder(XmlBuilder):
17
        schema = (
18
            'PROFILE_LIST',
19
            ('?loop', 'recipients',
20
             ('PROFILE',
21
              ('DEST_NAME', 'name_{to}'),
22
              ('DEST_FORENAME', 'forename_{to}'),
23
              ('DEST_ID', 'ID_{to}'),
24
              ('TERMINAL_GROUP',
25
               ('TERMINAL',
26
                ('TERMINAL_NAME', 'mobile1'),
27
                ('TERMINAL_ADDR', '{to}'),
28
                ('MEDIA_TYPE_GROUP',
29
                 ('MEDIA_TYPE', 'sms')))))))
30
        encoding = 'latin1'
31

  
32
    @property
33
    def verify(self):
34
        # Do not break if certificate is not updated
35
        if datetime.datetime.now() < datetime.datetime(2016, 11, 5):
36
            return self.ORANGE_CERTIFICATE
37
        else:
38
            return False
39

  
40
    def send_message(self, recipients, content):
41
        client = self.get_client()
42
        message = client.factory.create('WSMessage')
43
        message.fullContenu = True
44
        message.content = content
45
        message.subject = content
46
        message.resumeContent = content
47
        message.strategy = 'sms'
48
        send_profiles = self.ProfileListBuilder().string(
49
            context={'recipients': [{'to': to} for to in recipients]})
50
        message.sendProfiles = send_profiles
51
        # XXX: handle webfault and other problems
52
        try:
53
            client.service.sendMessage(message)
54
        except Exception, e:
55
            print e.__dict__
passerelle/apps/orange/urls.py
1
from django.conf.urls import patterns, url
2
from views import *
3

  
4
urlpatterns = patterns('',
5
    url(r'^(?P<slug>[\w,-]+)/$', OrangeDetailView.as_view(), name='orange-view'),
6
    url(r'^(?P<slug>[\w,-]+)/send$', OrangeSendView.as_view(), name='orange-send'),
7
)
8

  
9
management_urlpatterns = patterns('',
10
    url(r'^add$', OrangeCreateView.as_view(), name='orange-add'),
11
    url(r'^(?P<slug>[\w,-]+)/edit$', OrangeUpdateView.as_view(), name='orange-edit'),
12
    url(r'^(?P<slug>[\w,-]+)/delete$', OrangeDeleteView.as_view(), name='orange-delete'),
13
)
passerelle/apps/orange/views.py
1
from django.core.urlresolvers import reverse
2
from django.views.generic.edit import CreateView, UpdateView, DeleteView
3

  
4
from passerelle.base.views import ResourceView
5
from passerelle.sms.views import SendView
6

  
7
from .models import OrangeSMSGateway
8
from .forms import OrangeSMSGatewayForm
9

  
10

  
11
class OrangeDetailView(ResourceView):
12
    model = OrangeSMSGateway
13
    template_name = 'passerelle/manage/messages_service_view.html'
14

  
15

  
16
class OrangeCreateView(CreateView):
17
    model = OrangeSMSGateway
18
    template_name = 'passerelle/manage/service_form.html'
19
    form_class = OrangeSMSGatewayForm
20

  
21

  
22
class OrangeUpdateView(UpdateView):
23
    model = OrangeSMSGateway
24
    template_name = 'passerelle/manage/service_form.html'
25
    form_class = OrangeSMSGatewayForm
26

  
27

  
28
class OrangeDeleteView(DeleteView):
29
    model = OrangeSMSGateway
30
    template_name = 'passerelle/manage/service_confirm_delete.html'
31

  
32
    def get_success_url(self):
33
        return reverse('manage-home')
34

  
35

  
36
class OrangeSendView(SendView):
37
    model = OrangeSMSGateway
passerelle/settings.py
111 111
    'bdp',
112 112
    'base_adresse',
113 113
    'csvdatasource',
114
    'orange',
114 115
    # backoffice templates and static
115 116
    'gadjo',
116 117
)
......
123 124
PASSERELLE_APP_OXYD_ENABLED = True
124 125
PASSERELLE_APP_OVH_ENABLED = True
125 126
PASSERELLE_APP_MOBYT_ENABLED = True
127
PASSERELLE_APP_ORANGE_ENABLED = True
126 128

  
127 129
PASSERELLE_APP_BDP_ENABLED = False
128 130
PASSERELLE_APP_GDC_ENABLED = False
passerelle/urls.py
22 22
import concerto.urls
23 23
import bdp.urls
24 24
import base_adresse.urls
25
import orange.urls
25 26

  
26 27
admin.autodiscover()
27 28

  
......
131 132
    )
132 133
)
133 134

  
135
urlpatterns += required(
136
    app_enabled('orange'),
137
    patterns('',
138
        url(r'^orange/', include(orange.urls.urlpatterns)),
139
        url(r'^manage/orange/',
140
            decorated_includes(login_required, include(orange.urls.management_urlpatterns))),
141
    )
142
)
143

  
134 144
# add patterns from apps
135 145
urlpatterns = register_apps_urls(urlpatterns)
136 146

  
137
-