From cd6e3bd335b831b152fa374a8f559065f0a7ed09 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Tue, 31 Mar 2015 15:53:13 +0200 Subject: [PATCH] sms: improve SMSGatewayMixin.clean_numbers() - 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 --- .../0002_choositsmsgateway_default_trunk_prefix.py | 20 ++++++++++++++++++++ passerelle/apps/choosit/models.py | 4 +++- .../0002_mobytsmsgateway_default_trunk_prefix.py | 20 ++++++++++++++++++++ passerelle/apps/mobyt/models.py | 5 ++++- .../0002_ovhsmsgateway_default_trunk_prefix.py | 20 ++++++++++++++++++++ passerelle/apps/ovh/models.py | 6 ++++-- .../0002_oxydsmsgateway_default_trunk_prefix.py | 20 ++++++++++++++++++++ passerelle/apps/oxyd/models.py | 5 +++-- passerelle/sms/__init__.py | 19 ++++++++++++------- tests/test_sms.py | 12 ++++++------ 10 files changed, 112 insertions(+), 19 deletions(-) create mode 100644 passerelle/apps/choosit/migrations/0002_choositsmsgateway_default_trunk_prefix.py create mode 100644 passerelle/apps/mobyt/migrations/0002_mobytsmsgateway_default_trunk_prefix.py create mode 100644 passerelle/apps/ovh/migrations/0002_ovhsmsgateway_default_trunk_prefix.py create mode 100644 passerelle/apps/oxyd/migrations/0002_oxydsmsgateway_default_trunk_prefix.py diff --git a/passerelle/apps/choosit/migrations/0002_choositsmsgateway_default_trunk_prefix.py b/passerelle/apps/choosit/migrations/0002_choositsmsgateway_default_trunk_prefix.py new file mode 100644 index 0000000..3ee7e8f --- /dev/null +++ b/passerelle/apps/choosit/migrations/0002_choositsmsgateway_default_trunk_prefix.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('choosit', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='choositsmsgateway', + name='default_trunk_prefix', + field=models.CharField(default='0', max_length=2), + preserve_default=True, + ), + ] diff --git a/passerelle/apps/choosit/models.py b/passerelle/apps/choosit/models.py index 7916f2c..be3a4b8 100644 --- a/passerelle/apps/choosit/models.py +++ b/passerelle/apps/choosit/models.py @@ -18,6 +18,7 @@ class ChoositError(Exception): class ChoositSMSGateway(BaseResource, SMSGatewayMixin): key = models.CharField(max_length=64) default_country_code = models.CharField(max_length=3, default=u'33') + default_trunk_prefix = models.CharField(max_length=2, default=u'0') # FIXME: add regexp field, to check destination and from format class Meta: @@ -50,7 +51,8 @@ class ChoositSMSGateway(BaseResource, SMSGatewayMixin): # from http://sms.choosit.com/documentation_technique.html # unfortunately it lacks a batch API... destinations = self.clean_numbers(destinations, - self.default_country_code, prefix='') + self.default_country_code, + self.default_trunk_prefix) for dest in destinations: params = { 'key': self.key, diff --git a/passerelle/apps/mobyt/migrations/0002_mobytsmsgateway_default_trunk_prefix.py b/passerelle/apps/mobyt/migrations/0002_mobytsmsgateway_default_trunk_prefix.py new file mode 100644 index 0000000..e558555 --- /dev/null +++ b/passerelle/apps/mobyt/migrations/0002_mobytsmsgateway_default_trunk_prefix.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('mobyt', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='mobytsmsgateway', + name='default_trunk_prefix', + field=models.CharField(default='0', max_length=2), + preserve_default=True, + ), + ] diff --git a/passerelle/apps/mobyt/models.py b/passerelle/apps/mobyt/models.py index af09c22..a158ed8 100644 --- a/passerelle/apps/mobyt/models.py +++ b/passerelle/apps/mobyt/models.py @@ -31,6 +31,7 @@ class MobytSMSGateway(BaseResource, SMSGatewayMixin): 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') + default_trunk_prefix = models.CharField(max_length=2, default=u'0') # FIXME: add regexp field, to check destination and from format class Meta: @@ -61,7 +62,9 @@ class MobytSMSGateway(BaseResource, SMSGatewayMixin): def send(self, text, sender, destinations): """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 = urllib.urlencode({ 'user': self.username, diff --git a/passerelle/apps/ovh/migrations/0002_ovhsmsgateway_default_trunk_prefix.py b/passerelle/apps/ovh/migrations/0002_ovhsmsgateway_default_trunk_prefix.py new file mode 100644 index 0000000..bf19c87 --- /dev/null +++ b/passerelle/apps/ovh/migrations/0002_ovhsmsgateway_default_trunk_prefix.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('ovh', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='ovhsmsgateway', + name='default_trunk_prefix', + field=models.CharField(default='0', max_length=2), + preserve_default=True, + ), + ] diff --git a/passerelle/apps/ovh/models.py b/passerelle/apps/ovh/models.py index b78ac0e..9a9892d 100644 --- a/passerelle/apps/ovh/models.py +++ b/passerelle/apps/ovh/models.py @@ -38,6 +38,7 @@ class OVHSMSGateway(BaseResource, SMSGatewayMixin): default=1, verbose_name=_('message class')) credit_threshold_alert = models.PositiveIntegerField(default=100) default_country_code = models.CharField(max_length=3, default=u'33') + default_trunk_prefix = models.CharField(max_length=2, default=u'0') credit_left = models.PositiveIntegerField(default=0) # FIXME: add regexp field, to check destination and from format @@ -68,8 +69,9 @@ class OVHSMSGateway(BaseResource, SMSGatewayMixin): def send(self, text, sender, destinations): """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) diff --git a/passerelle/apps/oxyd/migrations/0002_oxydsmsgateway_default_trunk_prefix.py b/passerelle/apps/oxyd/migrations/0002_oxydsmsgateway_default_trunk_prefix.py new file mode 100644 index 0000000..effad47 --- /dev/null +++ b/passerelle/apps/oxyd/migrations/0002_oxydsmsgateway_default_trunk_prefix.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('oxyd', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='oxydsmsgateway', + name='default_trunk_prefix', + field=models.CharField(default='0', max_length=2), + preserve_default=True, + ), + ] diff --git a/passerelle/apps/oxyd/models.py b/passerelle/apps/oxyd/models.py index 6a78c42..4215b43 100644 --- a/passerelle/apps/oxyd/models.py +++ b/passerelle/apps/oxyd/models.py @@ -21,6 +21,7 @@ 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') + default_trunk_prefix = models.CharField(max_length=2, default=u'0') # FIXME: add regexp field, to check destination and from format class Meta: @@ -50,9 +51,9 @@ class OxydSMSGateway(BaseResource, SMSGatewayMixin): def send(self, text, sender, destinations): """Send a SMS using the Oxyd provider""" - # unfortunately it lacks a batch API... destinations = self.clean_numbers(destinations, - self.default_country_code, prefix='') + self.default_country_code, + self.default_trunk_prefix) for dest in destinations: params = urllib.urlencode({ 'id': self.username, diff --git a/passerelle/sms/__init__.py b/passerelle/sms/__init__.py index 6197d14..14addf5 100644 --- a/passerelle/sms/__init__.py +++ b/passerelle/sms/__init__.py @@ -6,20 +6,25 @@ 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 diff --git a/tests/test_sms.py b/tests/test_sms.py index c0e204b..5efb598 100644 --- a/tests/test_sms.py +++ b/tests/test_sms.py @@ -1,11 +1,11 @@ from passerelle.sms import SMSGatewayMixin 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'] + assert SMSGatewayMixin.clean_numbers(['+ 33 12']) == ['003312'] + assert SMSGatewayMixin.clean_numbers(['0 0 33 12']) == ['003312'] + assert SMSGatewayMixin.clean_numbers(['0 12']) == ['003312'] 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'] -- 2.1.4