add support for oxyd as sms provider (#1539)

This commit is contained in:
Frédéric Péters 2012-06-29 12:42:43 +02:00
parent 0ba0145a3e
commit e180b84fbb
4 changed files with 121 additions and 72 deletions

View File

@ -670,13 +670,19 @@ class SettingsDirectory(QommonSettingsDirectory):
html_top('settings', title = _('SMS'))
'<h2>%s</h2>' % _('SMS Options')
sms_cfg = get_cfg('sms', {})
sms = SMS()
mode = sms_cfg.get('mode', 'none')
if mode != 'none':
sms = SMS.get_sms_class(mode)
if sms:
'<ul>'
try:
'<li>%s %s</li>' % (_('SMS Credit:'), sms.get_money_left())
'<li>%s %s</li>' % (_('SMS Left:'), sms.get_sms_left())
try:
'<li>%s %s</li>' % (_('SMS Credit:'), sms.get_money_left())
except NotImplementedError:
pass
try:
'<li>%s %s</li>' % (_('SMS Left:'), sms.get_sms_left())
except NotImplementedError:
pass
except errors.SMSError:
"<p>%s</li>" % _("Connection with SMS provider failed")
'</ul>'
@ -684,39 +690,36 @@ class SettingsDirectory(QommonSettingsDirectory):
form = Form(enctype='multipart/form-data')
form.add(SingleSelectWidget, 'mode', title = _('SMS Mode'),
value = mode,
options = [ (str('none'), _('No support')),
(str('mobyt'), _('Mobyt provider')) ])
if mode == 'mobyt':
form.add(StringWidget, 'sender', title=_('Sender (number or name)'),
value = sms_cfg.get('sender', 'AuQuotidien'),
required = True)
form.add(StringWidget, 'mobyt_username', title=_('Username'),
value = sms_cfg.get('mobyt_username', ''),
required = True)
form.add(PasswordWidget, 'mobyt_password', title=_('Password'),
value = sms_cfg.get('mobyt_password', ''),
required = True)
sender = form.get_widget('sender').parse()
if sender and len(sender) > 11:
form.set_error("sender", "Too long (max : 11 characters)")
if form.get_submit() and not form.has_errors():
cfg_submit(form, 'sms', ('mode', 'mobyt_username', 'mobyt_password', 'sender'))
if mode != form.get_widget('mode').parse():
return redirect("sms")
elif mode != form.get_widget('mode').parse():
cfg_submit(form, 'sms', ['mode',])
return redirect("sms")
options = [('none', _('No support'), 'none')]+
[(str(k), _(SMS.providers.get(k)[0]), str(k)) for k in SMS.providers.keys()])
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
if form.get_widget('cancel').parse():
return redirect('.')
if sms:
for widget, name, title in sms.parameters:
form.add(widget, name, title=_(title),
value=sms_cfg.get(name, ''),
required=True)
if form.get_submit() and not form.has_errors():
cfg_submit(form, 'sms', ['mode'] + [x[1] for x in sms.parameters])
if mode != form.get_widget('mode').parse():
return redirect('sms')
else:
return redirect('.')
elif mode != form.get_widget('mode').parse():
cfg_submit(form, 'sms', ['mode',])
return redirect('sms')
else:
if form.get_submit() and form.get_widget('mode').parse() == str('none'):
return redirect('.')
if form.get_submit() and not form.has_errors():
cfg_submit(form, 'sms', ['mode',])
return redirect("sms")
return redirect('sms')
else:
form.render()

View File

@ -94,7 +94,7 @@ class QommonPublisher(Publisher):
default_configuration_path = None
auto_create_appdir = True
missing_appdir_redirect = None
use_sms_feature = False
use_sms_feature = True
app_translations = dict()
def get_root_url(self):

View File

@ -14,29 +14,31 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import re
import urllib2
import urllib
from quixote import get_publisher, redirect
from qommon import errors
from qommon import get_cfg
from qommon.form import StringWidget, PasswordWidget
class SMS:
""" This class allows to send a SMS using Mobyt provider """
def __init__(self, provider = None):
class MobytSMS():
"""This class allows to send a SMS using Mobyt provider"""
parameters = [
(StringWidget, 'sender', N_('Sender (number or name)')),
(StringWidget, 'mobyt_username', N_('Username')),
(PasswordWidget, 'mobyt_password', N_('Password')),
]
def __init__(self):
sms_cfg = get_cfg('sms', {})
if not provider:
self.provider = sms_cfg.get('mode', '')
self.user = None
self.password = None
if self.provider == "mobyt":
self.user = sms_cfg.get('mobyt_username', '')
self.password = sms_cfg.get('mobyt_password', '')
self.user = sms_cfg.get('mobyt_username', '')
self.password = sms_cfg.get('mobyt_password', '')
def _mobyt_send(self, sender, destinations, text, quality='l'):
def send(self, sender, destinations, text, quality='l'):
""" Send a sms using Mobyt provider"""
rcpt = ""
for dest in destinations:
@ -59,7 +61,7 @@ class SMS:
if answer[:2] == "KO":
raise errors.SMSError(answer[3:])
def _mobyt_credit(self, type):
def get_credit(self, type):
""" """
params = urllib.urlencode({
'user': self.user,
@ -76,41 +78,85 @@ class SMS:
raise errors.SMSError(answer[3:])
else:
return answer[3:]
def send(self, destinations, text, sender, quality=None):
"""
Send a sms
destinations : tuple with phone numbers (+YYXXXXXXXXX)
"""
if self.provider == "mobyt":
if not quality:
quality = 'l'
self._mobyt_send(sender, destinations, text, quality)
else:
raise errors.SMSError("Unknow SMS provider")
def get_sms_left(self, type="standard"):
"""
type (mobyt provider) : standard, lowcost or top
"""
if self.provider == "mobyt":
if type == "standard":
return self._mobyt_credit("l")
elif type == "lowcost":
return self._mobyt_credit("ll")
elif type == "top":
return self._mobyt_credit("n")
else:
raise errors.SMSError("%s is invalid type for provider Mobyt" % type)
if type == "standard":
return self.get_credit("l")
elif type == "lowcost":
return self.get_credit("ll")
elif type == "top":
return self.get_credit("n")
else:
raise errors.SMSError("Unknow SMS provider")
raise errors.SMSError("%s is invalid type for provider Mobyt" % type)
def get_money_left(self):
""" return money left in euros """
if self.provider == "mobyt":
return self._mobyt_credit("credit")
return self.get_credit("credit")
class OxydSMS:
"""This class allows to send a SMS using Oxyd provider"""
parameters = [
(StringWidget, 'oxyd_username', N_('Username')),
(PasswordWidget, 'oxyd_password', N_('Password')),
(StringWidget, 'oxyd_default_country_code', N_('Default Country Code')),
]
def __init__(self):
sms_cfg = get_cfg('sms', {})
self.user = sms_cfg.get('oxyd_username', '')
self.password = sms_cfg.get('oxyd_password', '')
self.default_country_code = sms_cfg.get('oxyd_default_country_code')
if not self.default_country_code:
self.default_country_code = '33' # arbitrary
def send(self, sender, destinations, text, quality=None):
"""Send a SMS using Oxyd provider"""
# unfortunately it lacks a batch API...
for dest in destinations:
# oxyd needs the number prefixed by the country code, this is
# really unfortunate.
number = ''.join(re.findall('\d', dest))
if dest.startswith('+'):
pass # it already is fully qualified
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 = self.default_country_code + number[1:]
try:
r = urllib2.urlopen('http://sms.oxyd.fr/send.php?id=%s&pass=%s&num=%s&sms=%s&flash=0' % (
self.user, self.password,
number,
text))
except Exception, e:
# XXX: add proper handling of errors
raise errors.SMSError('urlopen oxyd.fr failed : %s' % e)
r.close()
def get_sms_left(self, type='standard'):
raise NotImplementedError
def get_money_left(self):
raise NotImplementedError
class SMS:
providers = {
'mobyt': (N_('Mobyt provider'), MobytSMS),
'oxyd': (N_('Oxyd provider'), OxydSMS),
}
def get_sms_class(cls, provider_id):
if not provider_id:
sms_cfg = get_cfg('sms', {})
provider_id = sms_cfg.get('mode', '')
if provider_id in cls.providers:
return cls.providers.get(provider_id)[1]()
else:
raise errors.SMSError("Unknow SMS provider")
return None
get_sms_class = classmethod(get_sms_class)

View File

@ -844,7 +844,7 @@ class SendSMSWorkflowStatusItem(WorkflowStatusItem):
sms_cfg = get_cfg('sms', {})
sender = sms_cfg.get('sender', 'AuQuotidien')[:11]
try:
SMS().send([self.compute(x) for x in self.to], sms_body[:160], sender)
SMS.get_sms_class().send([self.compute(x) for x in self.to], sms_body[:160], sender)
except errors.SMSError, e:
get_logger().error(e)