0001-sms-add-a-button-to-test-sending-sms-45333.patch
passerelle/apps/mobyt/models.py | ||
---|---|---|
14 | 14 |
('ll', _('sms low-cost')), |
15 | 15 |
('n', _('sms top')), |
16 | 16 |
) |
17 | 17 |
username = models.CharField(verbose_name=_('Username'), max_length=64) |
18 | 18 |
password = models.CharField(verbose_name=_('Password'), max_length=64) |
19 | 19 |
quality = models.CharField(max_length=4, choices=MESSAGES_QUALITIES, default='l', |
20 | 20 |
verbose_name=_('Message quality')) |
21 | 21 | |
22 |
manager_view_template_name = 'passerelle/manage/messages_service_view.html' |
|
23 | ||
24 | 22 |
TEST_DEFAULTS = { |
25 | 23 |
'create_kwargs': { |
26 | 24 |
'username': 'john', |
27 | 25 |
'password': 'doe', |
28 | 26 |
}, |
29 | 27 |
'test_vectors': [ |
30 | 28 |
{ |
31 | 29 |
'response': '', |
passerelle/apps/orange/models.py | ||
---|---|---|
43 | 43 |
raise OrangeError('Orange returned Invalid JSON content: %s' % response.text) |
44 | 44 | |
45 | 45 | |
46 | 46 |
class OrangeSMSGateway(SMSResource): |
47 | 47 |
username = models.CharField(verbose_name=_('Identifier'), max_length=64) |
48 | 48 |
password = models.CharField(verbose_name=_('Password'), max_length=64) |
49 | 49 |
groupname = models.CharField(verbose_name=_('Group'), max_length=64) |
50 | 50 | |
51 |
manager_view_template_name = 'passerelle/manage/messages_service_view.html' |
|
52 | ||
53 | 51 |
class Meta: |
54 | 52 |
verbose_name = _('Orange') |
55 | 53 |
db_table = 'sms_orange' |
56 | 54 | |
57 | 55 |
def get_access_token(self): |
58 | 56 |
headers = {'content-type': 'application/x-www-form-urlencoded'} |
59 | 57 |
params = {'username': self.username, 'password': self.password} |
60 | 58 |
response = self.requests.post(URL_TOKEN, data=params, headers=headers) |
passerelle/apps/ovh/models.py | ||
---|---|---|
65 | 65 |
), |
66 | 66 |
) |
67 | 67 |
msg_class = models.IntegerField(choices=MESSAGES_CLASSES, default=1, |
68 | 68 |
verbose_name=_('Message class')) |
69 | 69 |
credit_threshold_alert = models.PositiveIntegerField(verbose_name=_('Credit alert threshold'), |
70 | 70 |
default=100) |
71 | 71 |
credit_left = models.PositiveIntegerField(verbose_name=_('Credit left'), default=0) |
72 | 72 | |
73 |
manager_view_template_name = 'passerelle/manage/messages_service_view.html' |
|
74 | ||
75 | 73 |
TEST_DEFAULTS = { |
76 | 74 |
'create_kwargs': { |
77 | 75 |
'account': '1234', |
78 | 76 |
'username': 'john', |
79 | 77 |
'password': 'doe', |
80 | 78 |
}, |
81 | 79 |
'test_vectors': [ |
82 | 80 |
{ |
passerelle/apps/oxyd/models.py | ||
---|---|---|
7 | 7 |
from passerelle.utils.jsonresponse import APIError |
8 | 8 |
from passerelle.sms.models import SMSResource |
9 | 9 | |
10 | 10 | |
11 | 11 |
class OxydSMSGateway(SMSResource): |
12 | 12 |
username = models.CharField(verbose_name=_('Username'), max_length=64) |
13 | 13 |
password = models.CharField(verbose_name=_('Password'), max_length=64) |
14 | 14 | |
15 |
manager_view_template_name = 'passerelle/manage/messages_service_view.html' |
|
16 | ||
17 | 15 |
TEST_DEFAULTS = { |
18 | 16 |
'create_kwargs': { |
19 | 17 |
'username': 'john', |
20 | 18 |
'password': 'doe', |
21 | 19 |
}, |
22 | 20 |
'test_vectors': [ |
23 | 21 |
{ |
24 | 22 |
'response': '', |
passerelle/base/__init__.py | ||
---|---|---|
34 | 34 |
except ImportError: |
35 | 35 |
return None |
36 | 36 | |
37 | 37 | |
38 | 38 |
class ConnectorAppConfig(ConnectorAppMixin, django.apps.AppConfig): |
39 | 39 |
pass |
40 | 40 | |
41 | 41 | |
42 |
class ConnectorSMSMixin(ConnectorAppMixin): |
|
43 |
def get_management_urls(self): |
|
44 |
urlpatterns = super(ConnectorSMSMixin, self).get_management_urls() or [] |
|
45 |
urlpatterns += import_string('passerelle.sms.urls.management_urlpatterns') |
|
46 |
return urlpatterns |
|
47 | ||
48 |
class ConnectorSMSConfig(ConnectorSMSMixin, django.apps.AppConfig): |
|
49 |
pass |
|
50 | ||
51 | ||
42 | 52 |
class AppConfig(django.apps.AppConfig): |
43 | 53 |
name = 'passerelle.base' |
44 | 54 | |
45 | 55 |
def ready(self): |
46 | 56 |
# once all applications are ready, go through them and mark them as |
47 | 57 |
# connectors if they have a get_connector_model() method or a model |
48 | 58 |
# that inherits from BaseResource. |
49 | 59 |
from .models import BaseResource |
60 |
from passerelle.sms.models import SMSResource |
|
50 | 61 |
for app in apps.get_app_configs(): |
51 | 62 |
connector_model = None |
52 | 63 |
if hasattr(app, 'get_connector_model'): |
53 | 64 |
connector_model = app.get_connector_model() |
54 | 65 |
else: |
55 | 66 |
for model in app.get_models(): |
56 | 67 |
if issubclass(model, BaseResource): |
57 | 68 |
connector_model = model |
58 | 69 |
app._connector_model = model |
70 |
if issubclass(model, SMSResource): |
|
71 |
app._is_sms_connector = True |
|
59 | 72 |
break |
73 | ||
60 | 74 |
if not connector_model: |
61 | 75 |
continue |
62 | 76 |
if app.__class__ is django.apps.AppConfig: |
63 | 77 |
# switch class if it's an application without a custom |
64 | 78 |
# appconfig. |
65 |
app.__class__ = ConnectorAppConfig |
|
79 |
if getattr(app, "_is_sms_connector", False): |
|
80 |
app.__class__ = ConnectorSMSConfig |
|
81 |
else: |
|
82 |
app.__class__ = ConnectorAppConfig |
|
66 | 83 |
else: |
67 | 84 |
# add mixin to base classes if it's an application with a |
68 | 85 |
# custom appconfig. |
69 | 86 |
app.__class__.__bases__ = (ConnectorAppMixin,) + app.__class__.__bases__ |
70 | 87 | |
71 | 88 |
default_app_config = 'passerelle.base.AppConfig' |
passerelle/sms/forms.py | ||
---|---|---|
1 |
from django import forms |
|
2 |
from django.utils.translation import ugettext_lazy as _ |
|
3 | ||
4 | ||
5 |
class SmsTestSendForm(forms.Form): |
|
6 |
number = forms.CharField(label=_('To'), max_length=12) |
|
7 |
sender = forms.CharField(label=_('From'), max_length=12) |
|
8 |
message = forms.CharField(label=_('Message'), max_length=128) |
passerelle/sms/models.py | ||
---|---|---|
34 | 34 | |
35 | 35 |
default_country_code = models.CharField(verbose_name=_('Default country code'), max_length=3, |
36 | 36 |
default=u'33') |
37 | 37 |
default_trunk_prefix = models.CharField(verbose_name=_('Default trunk prefix'), max_length=2, |
38 | 38 |
default=u'0') # Yeah France first ! |
39 | 39 |
# FIXME: add regexp field, to check destination and from format |
40 | 40 |
max_message_length = models.IntegerField(_('Maximum message length'), default=160) |
41 | 41 | |
42 |
manager_view_template_name = 'passerelle/manage/messages_service_view.html' |
|
43 | ||
42 | 44 |
def clean_numbers(self, destinations): |
43 | 45 |
numbers = [] |
44 | 46 |
for dest in destinations: |
45 | 47 |
# most gateways needs the number prefixed by the country code, this is |
46 | 48 |
# really unfortunate. |
47 | 49 |
dest = dest.strip() |
48 | 50 |
number = ''.join(re.findall('[0-9]', dest)) |
49 | 51 |
if dest.startswith('+'): |
passerelle/sms/templates/passerelle/manage/messages_service_test_send.html | ||
---|---|---|
1 |
{% extends "passerelle/base.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block appbar %} |
|
5 |
<h2>{% trans "Test Nico" %}</h2> |
|
6 |
{% endblock %} |
|
7 | ||
8 |
{% block content %} |
|
9 | ||
10 |
<form method="post" enctype="multipart/form-data"> |
|
11 |
{% csrf_token %} |
|
12 |
{{ form.as_p }} |
|
13 |
<div class="buttons"> |
|
14 |
<button>{% trans "Send SMS" %}</button> |
|
15 |
<a class="cancel" href="{% url 'manage-home' %}">{% trans 'Cancel' %}</a> |
|
16 |
</div> |
|
17 |
</form> |
|
18 |
{% endblock %} |
passerelle/sms/templates/passerelle/manage/messages_service_view.html | ||
---|---|---|
1 |
{% extends "passerelle/manage/service_view.html" %} |
|
2 |
{% load i18n passerelle %} |
|
3 | ||
4 |
{% block endpoints %} |
|
5 |
{{ block.super }} |
|
6 |
<div> |
|
7 |
<a rel="popup" href="/manage{{ object.get_absolute_url }}test-send/"> |
|
8 |
{% trans 'Send a test message' %} |
|
9 |
</a> |
|
10 |
</div> |
|
11 |
{% endblock %} |
|
12 | ||
13 |
{% debug %} |
passerelle/sms/urls.py | ||
---|---|---|
1 |
from django.conf.urls import url |
|
2 | ||
3 |
from . import views |
|
4 | ||
5 |
management_urlpatterns = [ |
|
6 |
url(r'^(?P<slug>[\w,-]+)/test-send/$', |
|
7 |
views.SmsTestSendView.as_view(), name='sms-test-send'), |
|
8 |
] |
passerelle/sms/views.py | ||
---|---|---|
1 |
from django.apps import apps |
|
2 |
from django.contrib import messages |
|
3 |
from django.utils.translation import ugettext_lazy as _ |
|
4 |
from django.views.generic import FormView |
|
5 | ||
6 |
from passerelle.utils.jsonresponse import APIError |
|
7 | ||
8 |
from .forms import SmsTestSendForm |
|
9 | ||
10 | ||
11 |
class SmsTestSendView(FormView): |
|
12 |
form_class = SmsTestSendForm |
|
13 |
template_name = 'passerelle/manage/messages_service_test_send.html' |
|
14 | ||
15 |
def get_instance(self): |
|
16 |
name = self.kwargs['connector'] |
|
17 |
slug = self.kwargs['slug'] |
|
18 |
model_name = '%sSMSGateway' % name.capitalize() |
|
19 |
model = apps.get_model(name, model_name) |
|
20 |
return model.objects.get(slug=slug) |
|
21 | ||
22 |
def get_success_url(self): |
|
23 |
instance = self.get_instance() |
|
24 |
return instance.get_absolute_url() |
|
25 | ||
26 |
def form_valid(self, form): |
|
27 |
instance = self.get_instance() |
|
28 |
number = form.cleaned_data['number'] |
|
29 |
sender = form.cleaned_data['sender'] |
|
30 |
message = form.cleaned_data['message'] |
|
31 |
try: |
|
32 |
number = instance.clean_numbers([number])[0] |
|
33 |
instance.send_msg(text=message, sender=sender, destinations=[number]) |
|
34 |
except APIError as exc: |
|
35 |
messages.error(self.request, _('Sending SMS fails: %s' % exc)) |
|
36 |
else: |
|
37 |
messages.success(self.request, _('An SMS was just sent')) |
|
38 |
return super(SmsTestSendView, self).form_valid(form) |
passerelle/templates/passerelle/manage/messages_service_view.html | ||
---|---|---|
1 |
{% extends "passerelle/manage/service_view.html" %} |
|
2 |
{% load i18n passerelle %} |
|
3 | ||
4 |
{% block description %} |
|
5 |
{% if object.description %}{{object.description|linebreaks}}{% endif %} |
|
6 |
{% endblock %} |
|
7 | ||
8 |
{% block endpoints %} |
|
9 |
<ul> |
|
10 |
<li>{% trans 'Sending a message:' %} <a href="send" >{{ site_base_uri }}{{ object.get_absolute_url }}send</a> (POST)</li> |
|
11 |
</ul> |
|
12 |
{% endblock %} |
|
13 |
- |