|
1 # -*- coding: utf-8 -*- |
|
2 #Copyright (C) 2009 Georg Bischoff |
|
3 |
|
4 #This program is free software; you can redistribute it and/or modify it under the terms |
|
5 #of the GNU General Public License as published by the Free Software Foundation; |
|
6 #either version 3 of the License, or any later version. |
|
7 #This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
|
8 #without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
9 #See the GNU General Public License for more details. |
|
10 |
|
11 #You should have received a copy of the GNU General Public License |
|
12 #along with this program; if not, see <http://www.gnu.org/licenses/>. |
|
13 |
|
14 |
|
15 import urllib |
|
16 import copy |
|
17 from functools import partial |
|
18 |
|
19 from ..error import UnknownOption, NeededOption |
|
20 from ..model.status import Status |
|
21 from .provider import Provider |
|
22 from ..offer import providers |
|
23 |
|
24 import logging |
|
25 logger=logging.getLogger("smstrade") |
|
26 |
|
27 class UnknownStatusCode(Exception): |
|
28 def __init__(self,code): |
|
29 self.code=code |
|
30 |
|
31 def __str__(self): |
|
32 return "StatusCode %i is unknown"%self.code |
|
33 |
|
34 |
|
35 class StatusCode: |
|
36 statusCodes = {10 : "Empfaengernummer nicht korrekt", |
|
37 20 : "Absenderkennung nicht korrekt", |
|
38 30 : "Nachrichtentext nicht korrekt", |
|
39 31 : "Messagetyp nicht korrekt", |
|
40 40 : "SMS Route nicht korrekt", |
|
41 50 : "Identifikation fehlgeschlagen", |
|
42 60 : "nicht genuegend Guthaben", |
|
43 70 : "Netz wird von Route nicht abgedeckt", |
|
44 71 : "Feature nicht ueber diese Route moeglich", |
|
45 80 : "Uebergabe an SMS-C fehlgeschlagen", |
|
46 90 : "Versand nicht moeglich", |
|
47 100 : "SMS wurde versendet", |
|
48 } |
|
49 |
|
50 def __init__(self,code, mID=None, cost=None, count=None): |
|
51 if code in self.statusCodes.keys(): |
|
52 self.code=code |
|
53 else: |
|
54 raise UnknownStatusCode(code) |
|
55 self.mID=mID |
|
56 self.cost = cost |
|
57 self.count = count |
|
58 |
|
59 def __str__(self): |
|
60 try: |
|
61 return self.statusCodes[self.code] |
|
62 except IndexError: |
|
63 raise UnknownStatusCode(self.code) |
|
64 |
|
65 def __int__(self): |
|
66 if not self.code in self.statusCodes.keys(): |
|
67 raise UnknownStatusCode(self.code) |
|
68 return self.code |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 class Smstrade(Provider): |
|
74 """ |
|
75 s. auch http://kundencenter.smstrade.de/sites/smstrade.de.kundencenter/__pdf/SMS-Gateway_HTTP_API_v2.pdf |
|
76 """ |
|
77 params= {"debug":("boolean",False), |
|
78 "concat_sms":('boolean',False), |
|
79 "message_id":('boolean',False), |
|
80 "count":('boolean',False), |
|
81 "cost":('boolean',False), |
|
82 } |
|
83 def __init__(self, name, config): |
|
84 self.url = "https://gateway.smstrade.de" |
|
85 Provider.__init__(self,name,config,{"sms":["basic","economy","gold","direct"]}) |
|
86 |
|
87 def loadConfig(self): |
|
88 """Read options from config""" |
|
89 needed=["key"] |
|
90 |
|
91 for n in needed: |
|
92 setattr(self,n,None) |
|
93 |
|
94 for (n, v) in self.config: |
|
95 if n in needed: |
|
96 setattr(self,n,v) |
|
97 else: |
|
98 raise UnknownOption(self.name, n) |
|
99 |
|
100 for n in needed: |
|
101 if getattr(self,n) is None: |
|
102 raise NeededOption(self.name, n) |
|
103 |
|
104 |
|
105 |
|
106 def send(self, route, sms, recipient): |
|
107 """send SMS with $sms to $recipients""" |
|
108 logger.debug('smstrade.sendSMS(%s,%s)'%(sms, recipient)) |
|
109 route = unicode(route) |
|
110 |
|
111 if recipient.land != '49' and route == "basic": |
|
112 return Exception() |
|
113 |
|
114 to ='00'+recipient.land+recipient.number |
|
115 try: |
|
116 smsSendStatus = self.__send(route, to, sms) |
|
117 logger.info('smstrade._send(...)=%i(%s)'%(int(smsSendStatus),str(smsSendStatus))) |
|
118 if int(smsSendStatus) in (100,): |
|
119 return Status(self,route) |
|
120 else: |
|
121 raise Exception() |
|
122 except UnknownStatusCode: |
|
123 raise Exception() |
|
124 |
|
125 def __send(self, route, to, sms): |
|
126 """ This function is the main part of the request to the sms service. |
|
127 The function has to return a unicode formated string that will represent the answer of the sms service |
|
128 to the request.""" |
|
129 logger.debug('smstrade._send(%s,%s,%s)'%( route, to, sms)) |
|
130 parameters= {"key": self.key, |
|
131 "route": route, |
|
132 "to": to, |
|
133 "message": sms.content.encode("utf-8"), |
|
134 "charset":"utf-8", |
|
135 "debug": self.testmode, |
|
136 "message_id":True, |
|
137 "count":True, |
|
138 "cost":True, |
|
139 } |
|
140 |
|
141 doubleChar="€[]{}|\\^~" #these charactar need two GSM Chars |
|
142 |
|
143 if sms.from_ is not None: |
|
144 parameters["from"] = sms.from_ |
|
145 |
|
146 length=len(sms.content) |
|
147 for s in doubleChar: |
|
148 length += sms.content.count(s) |
|
149 parameters["concat_sms"] = True if length > 160 else False |
|
150 |
|
151 ps={} |
|
152 for p in parameters: |
|
153 if p in self.params.keys(): |
|
154 if self.params[p][0] == "boolean": |
|
155 if parameters[p] != self.params[p][1]: |
|
156 ps[p]=int(not self.params[p][1]) |
|
157 else: |
|
158 ps[p] = parameters[p] |
|
159 |
|
160 params = urllib.urlencode(ps) |
|
161 dp=copy.deepcopy(ps) |
|
162 dp["key"]="<KEY>" |
|
163 logger.debug('smstrade._send-parameters:%s\n\t->%s'%(str(dp), urllib.urlencode(dp)) ) |
|
164 |
|
165 response = urllib.urlopen(self.url, params) |
|
166 data = response.readlines() |
|
167 if len(data) == 1: |
|
168 return StatusCode(int(data[0])) |
|
169 return StatusCode(int(data[0]),mID=data[1],cost=data[2],count=data[3]) |
|
170 |
|
171 def getSendFunc(self, typ, route): |
|
172 Provider.getSendFunc(self, typ, route) |
|
173 return partial(self.send,route) |
|
174 |
|
175 providers["smstrade"]=Smstrade |