sms: improve SMSGatewayMixin.clean_numbers() (fixes #6867)
- normalize numbers to the 00... international format - a default_trunk_prefix setting to all sms backends - set default_trunk_prefix and default_country_code to French ones - modify test
This commit is contained in:
parent
9388339ead
commit
14abe6efcd
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('choosit', '0004_auto_20160407_0456'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='choositsmsgateway',
|
||||
name='default_trunk_prefix',
|
||||
field=models.CharField(default='0', max_length=2),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -14,8 +14,11 @@ from .choosit import ChoositRegisterWS
|
|||
|
||||
|
||||
class ChoositSMSGateway(BaseResource, SMSGatewayMixin):
|
||||
key = models.CharField(max_length=64)
|
||||
default_country_code = models.CharField(max_length=3, default=u'33')
|
||||
key = models.CharField(verbose_name=_('Key'), max_length=64)
|
||||
default_country_code = models.CharField(verbose_name=_('Default country code'), max_length=3,
|
||||
default=u'33')
|
||||
default_trunk_prefix = models.CharField(verbose_name=_('Default trunk prefix'), max_length=2,
|
||||
default=u'0')
|
||||
# FIXME: add regexp field, to check destination and from format
|
||||
|
||||
TEST_DEFAULTS = {
|
||||
|
@ -29,9 +32,9 @@ class ChoositSMSGateway(BaseResource, SMSGatewayMixin):
|
|||
'err': 1,
|
||||
'err_desc': 'Choosit error: some destinations failed',
|
||||
'data': [
|
||||
[u'33688888888', u'Choosit error: bad JSON response No JSON object '
|
||||
[u'0033688888888', u'Choosit error: bad JSON response No JSON object '
|
||||
'could be decoded'],
|
||||
[u'33677777777', u'Choosit error: bad JSON response No JSON object '
|
||||
[u'0033677777777', u'Choosit error: bad JSON response No JSON object '
|
||||
'could be decoded'],
|
||||
]
|
||||
}
|
||||
|
@ -44,8 +47,8 @@ class ChoositSMSGateway(BaseResource, SMSGatewayMixin):
|
|||
'err': 1,
|
||||
'err_desc': 'Choosit error: some destinations failed',
|
||||
'data': [
|
||||
[u'33688888888', u'Choosit error: not ok'],
|
||||
[u'33677777777', u'Choosit error: not ok'],
|
||||
[u'0033688888888', u'Choosit error: not ok'],
|
||||
[u'0033677777777', u'Choosit error: not ok'],
|
||||
],
|
||||
}
|
||||
},
|
||||
|
@ -57,8 +60,8 @@ class ChoositSMSGateway(BaseResource, SMSGatewayMixin):
|
|||
'result': {
|
||||
'err': 0,
|
||||
'data': [
|
||||
[u'33688888888', {'result': u'Envoi terminé', 'sms_id': 1234}],
|
||||
[u'33677777777', {'result': u'Envoi terminé', 'sms_id': 1234}],
|
||||
[u'0033688888888', {'result': u'Envoi terminé', 'sms_id': 1234}],
|
||||
[u'0033677777777', {'result': u'Envoi terminé', 'sms_id': 1234}],
|
||||
],
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +86,9 @@ class ChoositSMSGateway(BaseResource, SMSGatewayMixin):
|
|||
"""Send a SMS using the Choosit provider"""
|
||||
# from http://sms.choosit.com/documentation_technique.html
|
||||
# unfortunately it lacks a batch API...
|
||||
destinations = self.clean_numbers(destinations, self.default_country_code, prefix='')
|
||||
destinations = self.clean_numbers(destinations,
|
||||
self.default_country_code,
|
||||
self.default_trunk_prefix)
|
||||
results = []
|
||||
for dest in destinations:
|
||||
params = {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mobyt', '0004_auto_20160407_0456'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='mobytsmsgateway',
|
||||
name='default_trunk_prefix',
|
||||
field=models.CharField(default='0', max_length=2),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -15,11 +15,14 @@ class MobytSMSGateway(BaseResource, SMSGatewayMixin):
|
|||
('ll', _('sms low-cost')),
|
||||
('n', _('sms top')),
|
||||
)
|
||||
username = models.CharField(max_length=64)
|
||||
password = models.CharField(max_length=64)
|
||||
username = models.CharField(verbose_name=_('Username'), max_length=64)
|
||||
password = models.CharField(verbose_name=_('Password'), max_length=64)
|
||||
quality = models.CharField(max_length=4, choices=MESSAGES_QUALITIES, default='l',
|
||||
verbose_name=_('message quality'))
|
||||
default_country_code = models.CharField(max_length=3, default=u'33')
|
||||
verbose_name=_('Message quality'))
|
||||
default_country_code = models.CharField(verbose_name=_('Default contry code'), max_length=3,
|
||||
default=u'33')
|
||||
default_trunk_prefix = models.CharField(verbose_name=_('Default trunk prefix'), max_length=2,
|
||||
default=u'0')
|
||||
# FIXME: add regexp field, to check destination and from format
|
||||
|
||||
manager_view_template_name = 'passerelle/manage/messages_service_view.html'
|
||||
|
@ -53,7 +56,9 @@ class MobytSMSGateway(BaseResource, SMSGatewayMixin):
|
|||
def send_msg(self, text, sender, destinations, **kwargs):
|
||||
"""Send a SMS using the Mobyt provider"""
|
||||
# unfortunately it lacks a batch API...
|
||||
destinations = self.clean_numbers(destinations, self.default_country_code)
|
||||
destinations = self.clean_numbers(destinations,
|
||||
self.default_country_code,
|
||||
self.default_trunk_prefix)
|
||||
rcpt = ','.join(destinations)
|
||||
params = {
|
||||
'user': self.username,
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('ovh', '0004_auto_20160407_0456'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='ovhsmsgateway',
|
||||
name='default_trunk_prefix',
|
||||
field=models.CharField(default='0', max_length=2),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -21,14 +21,18 @@ class OVHSMSGateway(BaseResource, SMSGatewayMixin):
|
|||
(3, _('Messages are stored in external storage like a PDA or '
|
||||
'a PC.')),
|
||||
)
|
||||
account = models.CharField(max_length=64)
|
||||
username = models.CharField(max_length=64)
|
||||
password = models.CharField(max_length=64)
|
||||
account = models.CharField(verbose_name=_('Account'), max_length=64)
|
||||
username = models.CharField(verbose_name=_('Username'), max_length=64)
|
||||
password = models.CharField(verbose_name=_('Password'), max_length=64)
|
||||
msg_class = models.IntegerField(choices=MESSAGES_CLASSES, default=1,
|
||||
verbose_name=_('message class'))
|
||||
credit_threshold_alert = models.PositiveIntegerField(default=100)
|
||||
default_country_code = models.CharField(max_length=3, default=u'33')
|
||||
credit_left = models.PositiveIntegerField(default=0)
|
||||
verbose_name=_('Message class'))
|
||||
credit_threshold_alert = models.PositiveIntegerField(verbose_name=_('Credit alert threshold'),
|
||||
default=100)
|
||||
default_country_code = models.CharField(verbose_name=_('Default country code'), max_length=3,
|
||||
default=u'33')
|
||||
default_trunk_prefix = models.CharField(verbose_name=_('Default trunk prefix'), max_length=2,
|
||||
default=u'0')
|
||||
credit_left = models.PositiveIntegerField(verbose_name=_('Dredit left'), default=0)
|
||||
# FIXME: add regexp field, to check destination and from format
|
||||
|
||||
manager_view_template_name = 'passerelle/manage/messages_service_view.html'
|
||||
|
@ -83,8 +87,9 @@ class OVHSMSGateway(BaseResource, SMSGatewayMixin):
|
|||
|
||||
def send_msg(self, text, sender, destinations, **kwargs):
|
||||
"""Send a SMS using the OVH provider"""
|
||||
# unfortunately it lacks a batch API...
|
||||
destinations = self.clean_numbers(destinations, self.default_country_code)
|
||||
destinations = self.clean_numbers(destinations,
|
||||
self.default_country_code,
|
||||
self.default_trunk_prefix)
|
||||
|
||||
text = unicode(text).encode('utf-8')
|
||||
to = ','.join(destinations)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('oxyd', '0004_auto_20160407_0456'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='oxydsmsgateway',
|
||||
name='default_trunk_prefix',
|
||||
field=models.CharField(default='0', max_length=2),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
|
@ -5,12 +5,16 @@ from django.db import models
|
|||
from passerelle.utils.jsonresponse import APIError
|
||||
from passerelle.base.models import BaseResource
|
||||
from passerelle.sms import SMSGatewayMixin
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class OxydSMSGateway(BaseResource, SMSGatewayMixin):
|
||||
username = models.CharField(max_length=64)
|
||||
password = models.CharField(max_length=64)
|
||||
default_country_code = models.CharField(max_length=3, default=u'33')
|
||||
username = models.CharField(verbose_name=_('Username'), max_length=64)
|
||||
password = models.CharField(verbose_name=_('Password'), max_length=64)
|
||||
default_country_code = models.CharField(verbose_name=_('Default country code'), max_length=3,
|
||||
default=u'33')
|
||||
default_trunk_prefix = models.CharField(verbose_name=_('Default trunk prefix'), max_length=2,
|
||||
default=u'0')
|
||||
# FIXME: add regexp field, to check destination and from format
|
||||
|
||||
manager_view_template_name = 'passerelle/manage/messages_service_view.html'
|
||||
|
@ -27,8 +31,8 @@ class OxydSMSGateway(BaseResource, SMSGatewayMixin):
|
|||
'err': 1,
|
||||
'err_desc': 'OXYD error: some destinations failed',
|
||||
'data': [
|
||||
['33688888888', "OXYD error: received content '' instead of 200"],
|
||||
['33677777777', "OXYD error: received content '' instead of 200"],
|
||||
['0033688888888', "OXYD error: received content '' instead of 200"],
|
||||
['0033677777777', "OXYD error: received content '' instead of 200"],
|
||||
],
|
||||
}
|
||||
},
|
||||
|
@ -54,7 +58,9 @@ class OxydSMSGateway(BaseResource, SMSGatewayMixin):
|
|||
def send_msg(self, text, sender, destinations, **kwargs):
|
||||
"""Send a SMS using the Oxyd provider"""
|
||||
# unfortunately it lacks a batch API...
|
||||
destinations = self.clean_numbers(destinations, self.default_country_code, prefix='')
|
||||
destinations = self.clean_numbers(destinations,
|
||||
self.default_country_code,
|
||||
self.default_trunk_prefix)
|
||||
results = []
|
||||
for dest in destinations:
|
||||
params = {
|
||||
|
|
|
@ -11,21 +11,26 @@ class SMSGatewayMixin(object):
|
|||
category = _('SMS Providers')
|
||||
|
||||
@classmethod
|
||||
def clean_numbers(cls, destinations, default_country_code, prefix='+'):
|
||||
def clean_numbers(cls, destinations, default_country_code='33',
|
||||
default_trunk_prefix='0'): # Yeah France first !
|
||||
numbers = []
|
||||
for dest in destinations:
|
||||
# most gateways needs the number prefixed by the country code, this is
|
||||
# really unfortunate.
|
||||
dest = dest.strip()
|
||||
number = ''.join(re.findall('[0-9]', dest))
|
||||
if dest.startswith('+'):
|
||||
pass # it already is fully qualified
|
||||
number = '00' + number
|
||||
elif number.startswith('00'):
|
||||
# assumes 00 is international access code, remove it
|
||||
number = number[2:]
|
||||
elif number.startswith('0'):
|
||||
# local prefix, remove 0 and add default country code
|
||||
number = default_country_code + number[1:]
|
||||
numbers.append(prefix + number)
|
||||
pass
|
||||
elif number.startswith(default_trunk_prefix):
|
||||
number = '00' + default_country_code + number[len(default_trunk_prefix):]
|
||||
else:
|
||||
raise NotImplementedError('phone number %r is unsupported (no '
|
||||
'international prefix, no local '
|
||||
'trunk prefix)' % number)
|
||||
numbers.append(number)
|
||||
return numbers
|
||||
|
||||
@endpoint('json-api', perm='can_send_messages', methods=['post'])
|
||||
|
|
|
@ -15,15 +15,12 @@ klasses = SMSGatewayMixin.__subclasses__()
|
|||
|
||||
|
||||
def test_clean_numbers():
|
||||
assert SMSGatewayMixin.clean_numbers(['+ 33 12'], '33') == ['+3312']
|
||||
assert SMSGatewayMixin.clean_numbers(['0 0 33 12'], '33') == ['+3312']
|
||||
assert SMSGatewayMixin.clean_numbers(['0 12'], '33') == ['+3312']
|
||||
|
||||
|
||||
def test_clean_numbers_no_prefix():
|
||||
assert SMSGatewayMixin.clean_numbers(['+ 33 12'], '33', prefix='') == ['3312']
|
||||
assert SMSGatewayMixin.clean_numbers(['0 0 33 12'], '33', prefix='') == ['3312']
|
||||
assert SMSGatewayMixin.clean_numbers(['0 12'], '33', prefix='') == ['3312']
|
||||
assert SMSGatewayMixin.clean_numbers(['+ 33 12']) == ['003312']
|
||||
assert SMSGatewayMixin.clean_numbers(['0 0 33 12']) == ['003312']
|
||||
assert SMSGatewayMixin.clean_numbers(['0 12']) == ['003312']
|
||||
assert SMSGatewayMixin.clean_numbers(['+ 33 12'], '32', '1') == ['003312']
|
||||
assert SMSGatewayMixin.clean_numbers(['0 0 33 12'], '32', '1') == ['003312']
|
||||
assert SMSGatewayMixin.clean_numbers(['1 12'], '32', '1') == ['003212']
|
||||
|
||||
|
||||
@pytest.fixture(params=klasses)
|
||||
|
@ -60,11 +57,11 @@ def test_connectors(app, connector):
|
|||
for test_vector in getattr(connector, 'TEST_DEFAULTS', {}).get('test_vectors', []):
|
||||
with utils.mock_url(connector.URL, test_vector['response']):
|
||||
result = app.post_json(path, params=payload)
|
||||
print result.json
|
||||
for key, value in test_vector['result'].iteritems():
|
||||
assert key in result.json
|
||||
assert result.json[key] == value
|
||||
|
||||
|
||||
def test_manage_views(admin_user, app, connector):
|
||||
url = '/%s/%s/' % (connector.get_connector_slug(), connector.slug)
|
||||
resp = app.get(url)
|
||||
|
|
Loading…
Reference in New Issue