Projet

Général

Profil

0001-add-support-for-oxyd-as-sms-provider-1539.patch

Frédéric Péters, 29 juin 2012 13:11

Télécharger (11,5 ko)

Voir les différences:

Subject: [PATCH 1/2] add support for oxyd as sms provider (#1539)

 wcs/admin/settings.ptl  |   61 +++++++++++-----------
 wcs/qommon/publisher.py |    2 +-
 wcs/qommon/sms.py       |  130 ++++++++++++++++++++++++++++++++---------------
 wcs/workflows.py        |    2 +-
 4 files changed, 122 insertions(+), 73 deletions(-)
wcs/admin/settings.ptl
670 670
        html_top('settings', title = _('SMS'))
671 671
        '<h2>%s</h2>' % _('SMS Options')
672 672
        sms_cfg = get_cfg('sms', {})
673
        sms = SMS()
674 673
        mode = sms_cfg.get('mode', 'none')
675
        if mode != 'none':
674
        sms = SMS.get_sms_class(mode)
675
        if sms:
676 676
            '<ul>'
677 677
            try:
678
                '<li>%s %s</li>' % (_('SMS Credit:'), sms.get_money_left())
679
                '<li>%s %s</li>' % (_('SMS Left:'), sms.get_sms_left())
678
                try:
679
                    '<li>%s %s</li>' % (_('SMS Credit:'), sms.get_money_left())
680
                except NotImplementedError:
681
                     pass
682
                try:
683
                    '<li>%s %s</li>' % (_('SMS Left:'), sms.get_sms_left())
684
                except NotImplementedError:
685
                     pass
680 686
            except errors.SMSError:
681 687
                "<p>%s</li>" % _("Connection with SMS provider failed")
682 688
            '</ul>'
......
684 690
        form = Form(enctype='multipart/form-data')
685 691
        form.add(SingleSelectWidget, 'mode', title = _('SMS Mode'),
686 692
                value = mode,
687
                options = [ (str('none'), _('No support')),
688
                            (str('mobyt'), _('Mobyt provider')) ])
689

  
690
        if mode == 'mobyt':
691
            form.add(StringWidget, 'sender', title=_('Sender (number or name)'),
692
                    value = sms_cfg.get('sender', 'AuQuotidien'),
693
                    required = True)
694
            form.add(StringWidget, 'mobyt_username', title=_('Username'),
695
                    value = sms_cfg.get('mobyt_username', ''),
696
                    required = True)
697
            form.add(PasswordWidget, 'mobyt_password', title=_('Password'),
698
                    value = sms_cfg.get('mobyt_password', ''),
699
                    required = True)
700
            sender = form.get_widget('sender').parse()
701
            if sender and len(sender) > 11:
702
                form.set_error("sender", "Too long (max : 11 characters)")
703
            if form.get_submit() and not form.has_errors():
704
                cfg_submit(form, 'sms', ('mode', 'mobyt_username', 'mobyt_password', 'sender'))
705
                if mode != form.get_widget('mode').parse():
706
                    return redirect("sms")
707
            elif mode != form.get_widget('mode').parse():
708
                cfg_submit(form, 'sms', ['mode',])
709
                return redirect("sms")
693
                options = [('none', _('No support'), 'none')]+
694
                          [(str(k), _(SMS.providers.get(k)[0]), str(k)) for k in SMS.providers.keys()])
710 695

  
711 696
        form.add_submit('submit', _('Submit'))
712 697
        form.add_submit('cancel', _('Cancel'))
713 698

  
714 699
        if form.get_widget('cancel').parse():
715 700
            return redirect('.')
716
        
701

  
702
        if sms:
703
            for widget, name, title in sms.parameters:
704
                form.add(widget, name, title=_(title),
705
                         value=sms_cfg.get(name, ''),
706
                         required=True)
707
            if form.get_submit() and not form.has_errors():
708
                cfg_submit(form, 'sms', ['mode'] + [x[1] for x in sms.parameters])
709
                if mode != form.get_widget('mode').parse():
710
                    return redirect('sms')
711
                else:
712
                    return redirect('.')
713
            elif mode != form.get_widget('mode').parse():
714
                cfg_submit(form, 'sms', ['mode',])
715
                return redirect('sms')
716
        else:
717
            if form.get_submit() and form.get_widget('mode').parse() == str('none'):
718
                return redirect('.')
719

  
717 720
        if form.get_submit() and not form.has_errors():
718 721
            cfg_submit(form, 'sms', ['mode',])
719
            return redirect("sms")
722
            return redirect('sms')
720 723
        else:
721 724
            form.render()
722 725

  
wcs/qommon/publisher.py
94 94
    default_configuration_path = None
95 95
    auto_create_appdir = True
96 96
    missing_appdir_redirect = None
97
    use_sms_feature = False
97
    use_sms_feature = True
98 98
    app_translations = dict()
99 99

  
100 100
    def get_root_url(self):
wcs/qommon/sms.py
14 14
# You should have received a copy of the GNU General Public License
15 15
# along with this program; if not, see <http://www.gnu.org/licenses/>.
16 16

  
17
import re
17 18
import urllib2
18 19
import urllib
19 20

  
20

  
21 21
from quixote import get_publisher, redirect
22 22

  
23 23
from qommon import errors
24 24
from qommon import get_cfg
25
from qommon.form import StringWidget, PasswordWidget
25 26

  
26
class SMS:
27
    """ This class allows to send a SMS using Mobyt provider """
28 27

  
29
    def __init__(self, provider = None):
28
class MobytSMS():
29
    """This class allows to send a SMS using Mobyt provider"""
30
    parameters = [
31
         (StringWidget, 'sender', N_('Sender (number or name)')),
32
         (StringWidget, 'mobyt_username', N_('Username')),
33
         (PasswordWidget, 'mobyt_password', N_('Password')),
34
    ]
35

  
36
    def __init__(self):
30 37
        sms_cfg = get_cfg('sms', {})
31
        if not provider:
32
            self.provider = sms_cfg.get('mode', '')
33
        self.user = None
34
        self.password = None
35
        if self.provider == "mobyt":
36
            self.user = sms_cfg.get('mobyt_username', '')
37
            self.password = sms_cfg.get('mobyt_password', '')
38

  
39
    def _mobyt_send(self, sender, destinations, text, quality='l'):
38
        self.user = sms_cfg.get('mobyt_username', '')
39
        self.password = sms_cfg.get('mobyt_password', '')
40

  
41
    def send(self, sender, destinations, text, quality='l'):
40 42
        """ Send a sms using Mobyt provider"""
41 43
        rcpt = ""
42 44
        for dest in destinations:
......
59 61
        if answer[:2] == "KO":
60 62
            raise errors.SMSError(answer[3:])
61 63

  
62
    def _mobyt_credit(self, type):
64
    def get_credit(self, type):
63 65
        """ """
64 66
        params = urllib.urlencode({
65 67
            'user': self.user,
......
76 78
            raise errors.SMSError(answer[3:])
77 79
        else:
78 80
            return answer[3:]
79
        
80

  
81
    def send(self, destinations, text, sender, quality=None):
82
        """
83
        Send a sms
84
        destinations : tuple with phone numbers (+YYXXXXXXXXX)
85
        """
86
        if self.provider == "mobyt":
87
            if not quality:
88
                quality = 'l'
89
            self._mobyt_send(sender, destinations, text, quality)
90
        else:
91
            raise errors.SMSError("Unknow SMS provider")
92 81

  
93 82
    def get_sms_left(self, type="standard"):
94 83
        """
95 84
        type (mobyt provider) : standard, lowcost or top
96 85
        """
97
        if self.provider == "mobyt":
98
            if type == "standard":
99
                return self._mobyt_credit("l")
100
            elif type == "lowcost":
101
                return self._mobyt_credit("ll")
102
            elif type == "top":
103
                return self._mobyt_credit("n")
104
            else:
105
                raise errors.SMSError("%s is invalid type for provider Mobyt" % type)
86
        if type == "standard":
87
            return self.get_credit("l")
88
        elif type == "lowcost":
89
            return self.get_credit("ll")
90
        elif type == "top":
91
            return self.get_credit("n")
106 92
        else:
107
            raise errors.SMSError("Unknow SMS provider")
93
            raise errors.SMSError("%s is invalid type for provider Mobyt" % type)
108 94

  
109 95
    def get_money_left(self):
110 96
        """ return money left in euros """
111
        if self.provider == "mobyt":
112
            return self._mobyt_credit("credit")
97
        return self.get_credit("credit")
98

  
99

  
100
class OxydSMS:
101
    """This class allows to send a SMS using Oxyd provider"""
102
    parameters = [
103
         (StringWidget, 'oxyd_username', N_('Username')),
104
         (PasswordWidget, 'oxyd_password', N_('Password')),
105
         (StringWidget, 'oxyd_default_country_code', N_('Default Country Code')),
106
    ]
107

  
108
    def __init__(self):
109
        sms_cfg = get_cfg('sms', {})
110
        self.user = sms_cfg.get('oxyd_username', '')
111
        self.password = sms_cfg.get('oxyd_password', '')
112
        self.default_country_code = sms_cfg.get('oxyd_default_country_code')
113
        if not self.default_country_code:
114
            self.default_country_code = '33' # arbitrary
115

  
116
    def send(self, sender, destinations, text, quality=None):
117
        """Send a SMS using Oxyd provider"""
118
        # unfortunately it lacks a batch API...
119
        for dest in destinations:
120
            # oxyd needs the number prefixed by the country code, this is
121
            # really unfortunate.
122
            number = ''.join(re.findall('\d', dest))
123
            if dest.startswith('+'):
124
                pass # it already is fully qualified
125
            elif number.startswith('00'):
126
                # assumes 00 is international access code, remove it
127
                number = number[2:]
128
            elif number.startswith('0'):
129
                # local prefix, remove 0 and add default country code
130
                number = self.default_country_code + number[1:]
131
            try:
132
                r = urllib2.urlopen('http://sms.oxyd.fr/send.php?id=%s&pass=%s&num=%s&sms=%s&flash=0' % (
133
                        self.user, self.password,
134
                        number,
135
                        text))
136
            except Exception, e:
137
                # XXX: add proper handling of errors
138
                raise errors.SMSError('urlopen oxyd.fr failed : %s' % e)
139
            r.close()
140

  
141
    def get_sms_left(self, type='standard'):
142
        raise NotImplementedError
143

  
144
    def get_money_left(self):
145
        raise NotImplementedError
146

  
147

  
148
class SMS:
149
    providers = {
150
        'mobyt': (N_('Mobyt provider'), MobytSMS),
151
        'oxyd': (N_('Oxyd provider'), OxydSMS),
152
    }
153

  
154
    def get_sms_class(cls, provider_id):
155
        if not provider_id:
156
            sms_cfg = get_cfg('sms', {})
157
            provider_id = sms_cfg.get('mode', '')
158
        if provider_id in cls.providers:
159
            return cls.providers.get(provider_id)[1]()
113 160
        else:
114
            raise errors.SMSError("Unknow SMS provider")
115
        
116
        
161
            return None
162
    get_sms_class = classmethod(get_sms_class)
wcs/workflows.py
844 844
        sms_cfg = get_cfg('sms', {})
845 845
        sender = sms_cfg.get('sender', 'AuQuotidien')[:11]
846 846
        try:
847
            SMS().send([self.compute(x) for x in self.to], sms_body[:160], sender)
847
            SMS.get_sms_class().send([self.compute(x) for x in self.to], sms_body[:160], sender)
848 848
        except errors.SMSError, e:
849 849
            get_logger().error(e)
850 850

  
851
-