# HG changeset patch # User Sandro Knauß # Date 1256955044 -3600 # Node ID 4c5f1cf088f684c6961b4efb1f227522b6f8c661 # Parent cec27aeb7e69fa2fcece031cf163950acd951e18 smstrade verbessert diff -r cec27aeb7e69 -r 4c5f1cf088f6 iro/anbieter/sipgate.py --- a/iro/anbieter/sipgate.py Wed Oct 28 03:03:46 2009 +0100 +++ b/iro/anbieter/sipgate.py Sat Oct 31 03:10:44 2009 +0100 @@ -59,6 +59,7 @@ def __connect(self): """connect to sipgate XMLRPC Server""" + self.samurai=xmlrpclib.Server(self.url%(self.user,self.password)).samurai args_identify = { "ClientName" : "anbieter.py", @@ -70,6 +71,7 @@ def __send_method(self, func, args=None): """execute $func and test weather if the func ran successfully or not""" + if args==None: xmlrpc_result = func() else: @@ -77,11 +79,13 @@ if xmlrpc_result['StatusCode'] != 200: raise NoValidStatusCode("There was an error during identification to the server! %d %s"% (xmlrpc_result['StatusCode'], xmlrpc_result['StatusString'])) + return xmlrpc_result def __send(self,args,recipients): """main sending method - sending the args to $recipients""" sended=[] + self.__connect() for recipient in recipients: try: @@ -90,7 +94,7 @@ if tel in sended: #only send message once per recipient continue sended.append(tel) - + args["RemoteUri"]="sip:%s%s@sipgate.net"%(tel.land,tel.number) xmlrpc_result = self.__send_method(self.samurai.SessionInitiate, args) self.updateStatus(arranged=recipient) diff -r cec27aeb7e69 -r 4c5f1cf088f6 iro/anbieter/smstrade.py --- a/iro/anbieter/smstrade.py Wed Oct 28 03:03:46 2009 +0100 +++ b/iro/anbieter/smstrade.py Sat Oct 31 03:10:44 2009 +0100 @@ -1,143 +1,146 @@ -# -*- 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 . - - -from anbieter import anbieter -from telnumber import telnumber, NotATelNumber -import ConfigParser -import xmlrpclib -import base64 - -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 - - self.maxMessageLength = None # maximum length of message; None if should not be set - self.smsCanBeSendDelayed = True # True if sms can be sent delayed by the sms service. Otherwise False - self.senderRe = r"^.{0,11}|[0-9]{0,15}" # RegEx for the sender-input-field - - self.routes = ("basicplus", "economy", "gold", "direct") # possible routes that can be used - self.routesWithSourceIdentifier = ("gold", "direct") # routes where a sender can be defined - -# statusCodes that the sms service returns on requests - self.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"} - - self.parameters = {} # don't write anything into this dict! Don't delete it! - - 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""" - sended = [] - key = self.key - route = unicode(self.route) - message = unicode(sms.content.toPlainText()) - from_ = unicode(self.from_) - 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 = unicode((tel.number)).strip() - smsSendStatus = self.__sendSms( - key, route, to, message, from_, timestamp) - 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.""" - self.parameters["key"] = key - self.parameters["route"] = route - self.parameters["to"] = to - self.parameters["message"] = message - self.parameters["debug"] = self.debug - - if from_ is not None: - self.parameters["from"] = from_ - else: - if "from" in self.parameters.keys(): - del(self.parameters["from"]) - - if timestamp is not None: - self.parameters["senddate"] = unicode(timestamp) - else: - if "senddate" in self.parameters.keys(): - del(self.parameters["senddate"]) - - self.parameters["concat_sms"] = "1" if len(message) > 160 else "0" - - params = urllib.urlencode(dict([k, v.encode('iso-8859-1')] for k, v in self.parameters.items())) - 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)) - else: - conn.close() - - try: - return self.statusCodes[int(data)] - except ValueError: - # this happens if the sms will be send delayed - return self.statusCodes[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 +# -*- 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 . + + +from anbieter import anbieter +from sipgate import NoValidStatusCode +from telnumber import telnumber, NotATelNumber +import ConfigParser +import xmlrpclib +import base64 +import urllib, httplib + +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 + + self.maxMessageLength = None # maximum length of message; None if should not be set + self.smsCanBeSendDelayed = True # True if sms can be sent delayed by the sms service. Otherwise False + self.senderRe = r"^.{0,11}|[0-9]{0,15}" # RegEx for the sender-input-field + + self.routes = ("basicplus", "economy", "gold", "direct") # possible routes that can be used + self.routesWithSourceIdentifier = ("gold", "direct") # routes where a sender can be defined + + # statusCodes that the sms service returns on requests + self.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"} + + self.parameters = {} # don't write anything into this dict! Don't delete it! + + 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""" + sended = [] + key = self.key + route = unicode(self.route) + message = unicode(sms.content) + from_ = unicode(self.from_) + 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 = unicode((tel.number)).strip() + code, smsSendStatus = self.__send(key, route, to, message, from_, timestamp) + if code in(100, 999): + self.updateStatus(arranged=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.""" + self.parameters["key"] = key + self.parameters["route"] = route + self.parameters["to"] = to + self.parameters["message"] = message + self.parameters["debug"] = self.debug + + if from_ is not None: + self.parameters["from"] = from_ + else: + if "from" in self.parameters.keys(): + del(self.parameters["from"]) + + if timestamp is not None: + self.parameters["senddate"] = unicode(timestamp) + else: + if "senddate" in self.parameters.keys(): + del(self.parameters["senddate"]) + + self.parameters["concat_sms"] = "1" if len(message) > 160 else "0" + + params = urllib.urlencode(dict([k, v.encode('iso-8859-1')] for k, v in self.parameters.items())) + 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)) + else: + conn.close() + + try: + return int(data), self.statusCodes[int(data)] + except ValueError: + # this happens if the sms will be send delayed + return 999, self.statusCodes[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