import requests from django.utils.translation import ugettext_lazy as _ from django.db import models from django.utils.encoding import force_text from passerelle.utils.jsonresponse import APIError from passerelle.base.models import BaseResource from passerelle.sms import SMSGatewayMixin class OVHSMSGateway(BaseResource, SMSGatewayMixin): URL = 'https://www.ovh.com/cgi-bin/sms/http2sms.cgi' MESSAGES_CLASSES = ( (0, _('Message are directly shown to users on phone screen ' 'at reception. The message is never stored, neither in the ' 'phone memory nor in the SIM card. It is deleted as ' 'soon as the user validate the display.')), (1, _('Messages are stored in the phone memory, or in the ' 'SIM card if the memory is full. ')), (2, _('Messages are stored in the SIM card.')), (3, _('Messages are stored in external storage like a PDA or ' 'a PC.')), ) 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(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=_('Credit left'), default=0) # FIXME: add regexp field, to check destination and from format manager_view_template_name = 'passerelle/manage/messages_service_view.html' TEST_DEFAULTS = { 'create_kwargs': { 'account': '1234', 'username': 'john', 'password': 'doe', }, 'test_vectors': [ { 'response': '', 'result': { 'err': 1, 'err_desc': 'OVH error: bad JSON response', } }, { 'response': { 'status': 100, 'creditLeft': 47, 'SmsIds': [1234], }, 'result': { 'err': 0, 'data': { 'credit_left': 47.0, 'ovh_result': { 'SmsIds': [1234], 'creditLeft': 47, 'status': 100 }, 'sms_ids': [1234], 'warning': 'credit level too low for ovhsmsgateway: 47.0 (threshold 100)', } } } ], } class Meta: verbose_name = 'OVH' db_table = 'sms_ovh' def send_msg(self, text, sender, destinations, **kwargs): """Send a SMS using the OVH provider""" destinations = self.clean_numbers(destinations, self.default_country_code, self.default_trunk_prefix) text = force_text(text).encode('utf-8') to = ','.join(destinations) params = { 'account': self.account.encode('utf-8'), 'login': self.username.encode('utf-8'), 'password': self.password.encode('utf-8'), 'from': sender.encode('utf-8'), 'to': to, 'message': text, 'contentType': 'text/json', 'class': self.msg_class, } if not kwargs['stop']: params.update({'noStop': 1}) try: response = self.requests.post(self.URL, data=params) except requests.RequestException as e: raise APIError('OVH error: POST failed, %s' % e) else: try: result = response.json() except ValueError as e: raise APIError('OVH error: bad JSON response') else: if not isinstance(result, dict): raise APIError('OVH error: bad JSON response %r, it should be a dictionnary' % result) if 100 <= result['status'] < 200: ret = {} credit_left = float(result['creditLeft']) # update credit left OVHSMSGateway.objects.filter(id=self.id).update(credit_left=credit_left) if credit_left < self.credit_threshold_alert: ret['warning'] = ('credit level too low for %s: %s (threshold %s)' % (self.slug, credit_left, self.credit_threshold_alert)) ret['credit_left'] = credit_left ret['ovh_result'] = result ret['sms_ids'] = result.get('SmsIds', []) return ret else: raise APIError('OVH error: %r' % result)