# -*- coding: utf-8 -*-
#Copyright (C) 2009 Georg Bischoff
#This program is free software; you can redistribute it and/or modify it under the terms
#of the GNU General Public License as published by the Free Software Foundation;
#either version 3 of the License, or any later version.
#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#See the GNU General Public License for more details.
#You should have received a copy of the GNU General Public License
#along with this program; if not, see <http://www.gnu.org/licenses/>.
from anbieter import anbieter
from sipgate import NoValidStatusCode
from telnumber import telnumber, NotATelNumber
import ConfigParser
import xmlrpclib
import base64
import gsm0338
import urllib, httplib
class UnknownStatusCode(Exception):
def __init__(self,code):
self.code=code
def __str__(self):
return "StatusCode %i is unknown"%self.code
class StatusCode:
statusCodes = {10 : "Empfaengernummer nicht korrekt",
20 : "Absenderkennung nicht korrekt",
30 : "Nachrichtentext nicht korrekt",
31 : "Messagetyp nicht korrekt",
40 : "SMS Route nicht korrekt",
50 : "Identifikation fehlgeschlagen",
60 : "nicht genuegend Guthaben",
70 : "Netz wird von Route nicht abgedeckt",
71 : "Feature nicht ueber diese Route moeglich",
80 : "Uebergabe an SMS-C fehlgeschlagen",
90 : "Versand nicht moeglich",
100 : "SMS wurde versendet",
999 : "SMS wird zeitversetzt verschickt"}
def __init__(self,code):
if code in self.statusCodes.keys():
self.code=code
else:
raise UnknownStatusCode(code)
def __str__(self):
try:
return self.statusCodes[self.code]
except IndexError:
raise UnkownStatusCode(self.code)
def __int__(self):
if not self.code in self.statusCodes.keys():
raise UnknownStatusCode(self.code)
return self.code
class smstrade(anbieter):
"""
s. auch http://kundencenter.smstrade.de/sites/smstrade.de.kundencenter/__pdf/SMS-Gateway_HTTP_API_v2.pdf
"""
section="smstrade"
url="https://gateway.smstrade.de"
def __init__(self):
self.domain = "smstrade.de" # website of the sms service
self.gateway = "gateway.smstrade.de" # gateway where the request will be sent
self.gatewayPort = 80 # port of the gateway
self.script = "/" # full path to the script that will handle the request
self.method = "POST" # method that will be used. Currently only POST is supported
def read_basic_config(self,filename):
"""Read basic options from the config file"""
cp = ConfigParser.ConfigParser()
cp.read([filename])
self.key=cp.get(self.section, 'key')
self.route=cp.get(self.section, 'route')
self.from_=cp.get(self.section, 'from')
self.debug=cp.get(self.section, 'debug')
def sendSMS(self,sms,recipients):
"""send SMS with $sms to $recipients"""
import logging
logging.debug('smstrade.sendSMS(%s,%s)'%(sms, str(recipients)))
sended = []
route = unicode(self.route)
message = sms.content
timestamp = None
for recipient in recipients:
try:
tel = telnumber(recipient)
if tel in sended: #only send message once per recipient
continue
sended.append(tel)
to ='00'+tel.land+tel.number
if tel.land == '49':
route=unicode("basic")
else:
route=unicode("economy")
smsSendStatus = self.__send(route, to, message, timestamp)
if int(smsSendStatus) in(100, 999):
self.updateStatus(arranged=recipient)
else:
self.updateStatus(failed=recipient)
except (NotATelNumber,NoValidStatusCode,InternetConnectionError):
self.updateStatus(failed=recipient)
def __send(self, key, route, to, message, from_=None, timestamp=None):
""" This function is the main part of the request to the sms service.
The function has to return a unicode formated string that will represent the answer of the sms service
to the request."""
import logging
logging.debug('smstrade._send(%s,%s,%s,%s)'%( route, to, message, timestamp))
parameters= {"key": self.key,
"route": route,
"to": to,
"message": message,
"charset":"utf-8",
"debug": self.debug,
}
if self.from_ is not None:
parameters["from"] = self.from_
if timestamp is not None:
parameters["senddate"] = unicode(timestamp)
parameters["concat_sms"] = "1" if len(message) > 160 else "0"
params = "&".join( ["%s=%s" % (urllib.quote(k),urllib.quote(v.encode("utf-8"))) for (k, v) in parameters.items()])
logging.debug('smstrade._send-parameters:%s\n\t->%s'%(str(parameters), str(params)) )
headers = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"}
conn = httplib.HTTPConnection("%s:%i" % (self.gateway, self.gatewayPort))
try:
conn.request(self.method, self.script, params, headers)
response = conn.getresponse()
data = response.read()
except socket.gaierror:
raise InternetConnectionError("%s:%i" % (self.gateway, self.gatewayPort))
finally:
conn.close()
try:
return StatusCode(int(data))
except UnknownStatusCode:
# this happens if the sms will be send delayed
return StatusCode(999)
def updateStatus(self, arranged=None, failed=None):
"""is a function that is called, if a new SMS/FAX was send
-arranged is non None, if SMS/FAX was sended successfully
-failed is non None, if SMS/FAX sending failed
the content will be the recipent"""
pass
class InternetConnectionError(Exception):
def __init__(self, url):
self.url = url
def __str__(self):
return "InternetConnectionError: It is not possible to open 'http://%s'. Please check your connection to the Internet!" % self.url