18 import ConfigParser |
18 import ConfigParser |
19 import xmlrpclib |
19 import xmlrpclib |
20 import base64 |
20 import base64 |
21 import urllib, httplib |
21 import urllib, httplib |
22 |
22 |
23 class smstrade(anbieter): |
23 class UnknownStatusCode(Exception): |
24 """ |
24 def __init__(self,code): |
25 s. auch http://kundencenter.smstrade.de/sites/smstrade.de.kundencenter/__pdf/SMS-Gateway_HTTP_API_v2.pdf |
25 self.code=code |
26 """ |
|
27 section="smstrade" |
|
28 url="https://gateway.smstrade.de" |
|
29 def __init__(self): |
|
30 self.domain = "smstrade.de" # website of the sms service |
|
31 self.gateway = "gateway.smstrade.de" # gateway where the request will be sent |
|
32 self.gatewayPort = 80 # port of the gateway |
|
33 self.script = "/" # full path to the script that will handle the request |
|
34 self.method = "POST" # method that will be used. Currently only POST is supported |
|
35 |
26 |
36 self.maxMessageLength = None # maximum length of message; None if should not be set |
27 def __str__(self): |
37 self.smsCanBeSendDelayed = True # True if sms can be sent delayed by the sms service. Otherwise False |
28 return "StatusCode %i is unknown"%self.code |
38 self.senderRe = r"^.{0,11}|[0-9]{0,15}" # RegEx for the sender-input-field |
|
39 |
29 |
40 self.routes = ("basicplus", "economy", "gold", "direct") # possible routes that can be used |
|
41 self.routesWithSourceIdentifier = ("gold", "direct") # routes where a sender can be defined |
|
42 |
30 |
43 # statusCodes that the sms service returns on requests |
31 class StatusCode: |
44 self.statusCodes = {10 : "Empfaengernummer nicht korrekt", |
32 statusCodes = {10 : "Empfaengernummer nicht korrekt", |
45 20 : "Absenderkennung nicht korrekt", |
33 20 : "Absenderkennung nicht korrekt", |
46 30 : "Nachrichtentext nicht korrekt", |
34 30 : "Nachrichtentext nicht korrekt", |
47 31 : "Messagetyp nicht korrekt", |
35 31 : "Messagetyp nicht korrekt", |
48 40 : "SMS Route nicht korrekt", |
36 40 : "SMS Route nicht korrekt", |
49 50 : "Identifikation fehlgeschlagen", |
37 50 : "Identifikation fehlgeschlagen", |
53 80 : "Uebergabe an SMS-C fehlgeschlagen", |
41 80 : "Uebergabe an SMS-C fehlgeschlagen", |
54 90 : "Versand nicht moeglich", |
42 90 : "Versand nicht moeglich", |
55 100 : "SMS wurde versendet", |
43 100 : "SMS wurde versendet", |
56 999 : "SMS wird zeitversetzt verschickt"} |
44 999 : "SMS wird zeitversetzt verschickt"} |
57 |
45 |
58 self.parameters = {} # don't write anything into this dict! Don't delete it! |
46 def __init__(self,code): |
|
47 if code in self.statusCodes.keys(): |
|
48 self.code=code |
|
49 else: |
|
50 raise UnknownStatusCode(code) |
|
51 |
|
52 def __str__(self): |
|
53 try: |
|
54 return self.statusCodes[self.code] |
|
55 except IndexError: |
|
56 raise UnkownStatusCode(self.code) |
|
57 |
|
58 def __int__(self): |
|
59 if not self.code in self.statusCodes.keys(): |
|
60 raise UnknownStatusCode(self.code) |
|
61 return self.code |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 class smstrade(anbieter): |
|
67 """ |
|
68 s. auch http://kundencenter.smstrade.de/sites/smstrade.de.kundencenter/__pdf/SMS-Gateway_HTTP_API_v2.pdf |
|
69 """ |
|
70 section="smstrade" |
|
71 url="https://gateway.smstrade.de" |
|
72 def __init__(self): |
|
73 self.domain = "smstrade.de" # website of the sms service |
|
74 self.gateway = "gateway.smstrade.de" # gateway where the request will be sent |
|
75 self.gatewayPort = 80 # port of the gateway |
|
76 self.script = "/" # full path to the script that will handle the request |
|
77 self.method = "POST" # method that will be used. Currently only POST is supported |
59 |
78 |
60 def read_basic_config(self,filename): |
79 def read_basic_config(self,filename): |
61 """Read basic options from the config file""" |
80 """Read basic options from the config file""" |
62 cp = ConfigParser.ConfigParser() |
81 cp = ConfigParser.ConfigParser() |
63 cp.read([filename]) |
82 cp.read([filename]) |
75 from_ = unicode(self.from_) |
94 from_ = unicode(self.from_) |
76 timestamp = None |
95 timestamp = None |
77 for recipient in recipients: |
96 for recipient in recipients: |
78 try: |
97 try: |
79 tel = telnumber(recipient) |
98 tel = telnumber(recipient) |
80 if tel in sended: #only send message once per recipient |
99 if tel in sended: #only send message once per recipient |
81 continue |
100 continue |
82 sended.append(tel) |
101 sended.append(tel) |
83 to = unicode((tel.number)).strip() |
102 to = unicode((tel.number)).strip() |
84 code, smsSendStatus = self.__send(key, route, to, message, from_, timestamp) |
103 smsSendStatus = self.__send(key, route, to, message, from_, timestamp) |
85 if code in(100, 999): |
104 if int(smsSendStatus) in(100, 999): |
86 self.updateStatus(arranged=recipient) |
105 self.updateStatus(arranged=recipient) |
|
106 else: |
|
107 self.updateStatus(failed=recipient) |
87 except (NotATelNumber,NoValidStatusCode,InternetConnectionError): |
108 except (NotATelNumber,NoValidStatusCode,InternetConnectionError): |
88 self.updateStatus(failed=recipient) |
109 self.updateStatus(failed=recipient) |
89 |
110 |
90 def __send(self, key, route, to, message, from_=None, timestamp=None): |
111 def __send(self, key, route, to, message, from_=None, timestamp=None): |
91 """ This function is the main part of the request to the sms service. |
112 """ This function is the main part of the request to the sms service. |
92 The function has to return a unicode formated string that will represent the answer of the sms service |
113 The function has to return a unicode formated string that will represent the answer of the sms service |
93 to the request.""" |
114 to the request.""" |
94 self.parameters["key"] = key |
115 parameters= {"key": key, |
95 self.parameters["route"] = route |
116 "route": route, |
96 self.parameters["to"] = to |
117 "to": to, |
97 self.parameters["message"] = message |
118 "message": message, |
98 self.parameters["debug"] = self.debug |
119 "debug": self.debug, |
|
120 } |
99 |
121 |
100 if from_ is not None: |
122 if from_ is not None: |
101 self.parameters["from"] = from_ |
123 parameters["from"] = from_ |
102 else: |
|
103 if "from" in self.parameters.keys(): |
|
104 del(self.parameters["from"]) |
|
105 |
124 |
106 if timestamp is not None: |
125 if timestamp is not None: |
107 self.parameters["senddate"] = unicode(timestamp) |
126 parameters["senddate"] = unicode(timestamp) |
108 else: |
|
109 if "senddate" in self.parameters.keys(): |
|
110 del(self.parameters["senddate"]) |
|
111 |
127 |
112 self.parameters["concat_sms"] = "1" if len(message) > 160 else "0" |
128 parameters["concat_sms"] = "1" if len(message) > 160 else "0" |
113 |
129 |
114 params = urllib.urlencode(dict([k, v.encode('iso-8859-1')] for k, v in self.parameters.items())) |
130 params = urllib.urlencode(dict([k, v.encode('iso-8859-1')] for k, v in parameters.items())) |
115 headers = {"Content-type": "application/x-www-form-urlencoded", |
131 headers = {"Content-type": "application/x-www-form-urlencoded", |
116 "Accept": "text/plain"} |
132 "Accept": "text/plain"} |
117 conn = httplib.HTTPConnection("%s:%i" % (self.gateway, self.gatewayPort)) |
133 conn = httplib.HTTPConnection("%s:%i" % (self.gateway, self.gatewayPort)) |
118 try: |
134 try: |
119 conn.request(self.method, self.script, params, headers) |
135 conn.request(self.method, self.script, params, headers) |
124 raise InternetConnectionError("%s:%i" % (self.gateway, self.gatewayPort)) |
140 raise InternetConnectionError("%s:%i" % (self.gateway, self.gatewayPort)) |
125 else: |
141 else: |
126 conn.close() |
142 conn.close() |
127 |
143 |
128 try: |
144 try: |
129 return int(data), self.statusCodes[int(data)] |
145 return StatusCode(int(data)) |
130 except ValueError: |
146 except UnknownStatusCode: |
131 # this happens if the sms will be send delayed |
147 # this happens if the sms will be send delayed |
132 return 999, self.statusCodes[999] |
148 return StatusCode(999) |
133 |
149 |
134 def updateStatus(self, arranged=None, failed=None): |
150 def updateStatus(self, arranged=None, failed=None): |
135 """is a function that is called, if a new SMS/FAX was send |
151 """is a function that is called, if a new SMS/FAX was send |
136 -arranged is non None, if SMS/FAX was sended successfully |
152 -arranged is non None, if SMS/FAX was sended successfully |
137 -failed is non None, if SMS/FAX sending failed |
153 -failed is non None, if SMS/FAX sending failed |