0001-add-support-for-oxyd-as-sms-provider-1539.patch
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 |
- |