# HG changeset patch # User Sandro Knauß # Date 1256955659 -3600 # Node ID f25033cf93e0374edd42822928d9a00cb550278a # Parent 4a33882f3a49db0c0a6a48699683f738a48cd4f9 Backend auswahl nun möglich diff -r 4a33882f3a49 -r f25033cf93e0 iro/.eric4project/iro.e4q --- a/iro/.eric4project/iro.e4q Wed Oct 28 03:36:27 2009 +0100 +++ b/iro/.eric4project/iro.e4q Sat Oct 31 03:20:59 2009 +0100 @@ -1,7 +1,7 @@ - + \ No newline at end of file diff -r 4a33882f3a49 -r f25033cf93e0 iro/.eric4project/iro.e4t --- a/iro/.eric4project/iro.e4t Wed Oct 28 03:36:27 2009 +0100 +++ b/iro/.eric4project/iro.e4t Sat Oct 31 03:20:59 2009 +0100 @@ -1,6 +1,6 @@ - + \ No newline at end of file diff -r 4a33882f3a49 -r f25033cf93e0 iro/anbieter/sipgate.py --- a/iro/anbieter/sipgate.py Wed Oct 28 03:36:27 2009 +0100 +++ b/iro/anbieter/sipgate.py Sat Oct 31 03:20:59 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 4a33882f3a49 -r f25033cf93e0 iro/anbieter/smstrade.py --- a/iro/anbieter/smstrade.py Wed Oct 28 03:36:27 2009 +0100 +++ b/iro/anbieter/smstrade.py Sat Oct 31 03:20:59 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 diff -r 4a33882f3a49 -r f25033cf93e0 iro/iro.e4p --- a/iro/iro.e4p Wed Oct 28 03:36:27 2009 +0100 +++ b/iro/iro.e4p Sat Oct 31 03:20:59 2009 +0100 @@ -1,7 +1,7 @@ - + @@ -31,6 +31,10 @@ anbieter/telnumber.py anbieter/test.py test.py + providerlist.py + joblist.py + job.py + anbieter/smstrade.py @@ -42,6 +46,7 @@ iro.conf.inst + iro.conf iro.py diff -r 4a33882f3a49 -r f25033cf93e0 iro/iro.py --- a/iro/iro.py Wed Oct 28 03:36:27 2009 +0100 +++ b/iro/iro.py Sat Oct 31 03:20:59 2009 +0100 @@ -15,12 +15,11 @@ from xmlrpc import SecureUserDBXMLRPCServer,UserDB -from user import User, Admin, NotSupportedFeature +from user import User, Admin import anbieter import ConfigParser - -from job import MessageJob +from job import SMSJob, FAXJob, MailJob from joblist import Joblist from providerlist import Providerlist @@ -88,7 +87,10 @@ class MyManager(BaseManager): pass - MyManager.register('MessageJob', MessageJob) + MyManager.register('SMSJob', SMSJob) + MyManager.register('FAXob', FAXJob) + MyManager.register('MailJob',FAXJob) + MyManager.register('Providerlist',Providerlist) manager = MyManager() manager.start() @@ -106,7 +108,7 @@ #Benutzerdatenbank erstellen queue = Queue() - provider=Providerlist() + provider=manager.Providerlist() provider.add("sipgate", sip, ["sms", "fax", ]) provider.add("smstrade", smstrade, ["sms", ]) provider.add("geonet", None, ["sms", "fax", ]) diff -r 4a33882f3a49 -r f25033cf93e0 iro/job.py --- a/iro/job.py Wed Oct 28 03:36:27 2009 +0100 +++ b/iro/job.py Sat Oct 31 03:20:59 2009 +0100 @@ -16,7 +16,8 @@ ''' Basic class for all jobs ''' - def __init__(self,provider,name): + def __init__(self,providerlist,provider, name): + self.providerlist=providerlist self.provider=provider self.name=name self.status = "init" @@ -37,7 +38,7 @@ return self.name def getProvider(self): - return self.provider + return None def addGood(self, good): if type(good) == list: @@ -55,18 +56,20 @@ ''' A specialized class for smsjobs ''' - def __init__(self,provider,name, message,recipients): + def __init__(self,providerlist,provider, name, message,recipients): self.message=message self.recipients=recipients - Job.__init__(self,provider, name) + Job.__init__(self,providerlist,provider, name) def stop(self): pass - + + + def start(self): Job.start(self) - self.provider.setJob(self) - self.message.sendto(self.provider, self.recipients) + self.getProvider().setJob(self) + self.message.sendto(self.getProvider(), self.recipients) self.status="sended" def getMessage(self): @@ -76,4 +79,28 @@ return self.recipients +class SMSJob(MessageJob): + def __init__(self,providerlist,provider, name, message,recipients): + MessageJob.__init__(self,providerlist,provider, name, message,recipients) + + def getProvider(self): + return self.providerlist.getProvider("sms", self.provider) + + def start(self): + MessageJob.start(self) +class FAXJob(MessageJob): + def __init__(self,providerlist,provider, name, message,recipients): + MessageJob.__init__(self,providerlist,provider, name, message,recipients) + + def getProvider(self): + return self.providerlist.getProvider("fax", self.provider) + +class MailJob(MessageJob): + def __init__(self,providerlist,provider, name, message,recipients): + MessageJob.__init__(self,providerlist,provider, name, message,recipients) + + def getProvider(self): + return self.providerlist.getProvider("mail", self.provider) + + diff -r 4a33882f3a49 -r f25033cf93e0 iro/joblist.py --- a/iro/joblist.py Wed Oct 28 03:36:27 2009 +0100 +++ b/iro/joblist.py Sat Oct 31 03:20:59 2009 +0100 @@ -39,21 +39,21 @@ ''' creates a new SMS ''' - job=self.manager.MessageJob(self.providerlist.getProvider("sms",provider),message, content.SMS(message),recipients) + job=self.manager.SMSJob(self.providerlist, provider,message, content.SMS(message),recipients) return self.__registerJob__(job) def newFAX(self,subject, fax,recipients,provider="default"): ''' creates a new Fax ''' - job=self.manager.MessageJob(self.providerlist.getProvider("fax",provider),subject, content.FAX(subject, fax),recipients) + job=self.manager.FaxJob(self.providerlist, provider,subject, content.FAX(subject, fax),recipients) return self.__registerJob__(job) def newMail(self,subject, body,recipients,provider="default"): ''' creates a new Mail ''' - job=self.manager.MessageJob(self.providerlist.getProvider("mail",provider),subject, content.Mail(subject, body),recipients) + job=self.manager.MailJob(self.providerlist, provider,subject, content.Mail(subject, body),recipients) return self.__registerJob__(job) def _createID(self): diff -r 4a33882f3a49 -r f25033cf93e0 iro/providerlist.py --- a/iro/providerlist.py Wed Oct 28 03:36:27 2009 +0100 +++ b/iro/providerlist.py Sat Oct 31 03:20:59 2009 +0100 @@ -43,5 +43,5 @@ if not stype in self.provider[name] ["types"]: raise "argh" - + return self.provider[name]["class"]