11 #You should have received a copy of the GNU General Public License |
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/>. |
12 #along with this program; if not, see <http://www.gnu.org/licenses/>. |
13 |
13 |
14 |
14 |
15 import urllib |
15 import urllib |
16 import copy |
|
17 from functools import partial |
16 from functools import partial |
|
17 from decimal import Decimal |
|
18 #import copy |
18 |
19 |
19 from ..config import Option |
20 from ..config import Option |
20 from ..model.status import Status |
21 from ..model.status import Status |
21 from .provider import Provider, providers |
22 from .provider import Provider, providers |
22 from ..error import RejectRecipient, ExternalException |
23 from ..error import RejectRecipient, ExternalException |
23 |
24 |
24 import logging |
25 #import logging |
25 logger=logging.getLogger("smstrade") |
26 #logger=logging.getLogger("smstrade") |
26 |
27 |
27 statusCodes = {10 : "Empfaengernummer nicht korrekt.", |
28 statusCodes = {10 : "Empfaengernummer nicht korrekt.", |
28 20 : "Absenderkennung nicht korrekt.", |
29 20 : "Absenderkennung nicht korrekt.", |
29 30 : "Nachrichtentext nicht korrekt.", |
30 30 : "Nachrichtentext nicht korrekt.", |
30 31 : "Messagetyp nicht korrekt.", |
31 31 : "Messagetyp nicht korrekt.", |
37 90 : "Versand nicht moeglich.", |
38 90 : "Versand nicht moeglich.", |
38 100 : "SMS wurde versendet.", |
39 100 : "SMS wurde versendet.", |
39 } |
40 } |
40 |
41 |
41 |
42 |
42 class StatusException(ExternalException): |
43 class SmstradeException(ExternalException): |
43 def __init__(self,status): |
44 def __init__(self,status): |
44 ExternalException.__init__(self) |
45 ExternalException.__init__(self) |
45 self.status = status |
46 self.status = status |
46 self.str_ = "%i: unknown statuscode."%status |
47 self.str_=str(status) |
47 try: |
48 |
48 self.str_="%i: %s"%(status, statusCodes[int(status)]) |
|
49 except KeyError: |
|
50 pass |
|
51 def __str__(self): |
49 def __str__(self): |
52 return "%s\n%s"%(ExternalException.__str__(self),self.str_) |
50 return "%s\n%s"%(ExternalException.__str__(self),self.str_) |
53 |
51 |
54 |
52 |
55 class StatusCode: |
53 class StatusCode: |
56 def __init__(self,code, mID=None, cost=None, count=None): |
54 def __init__(self,code, exID=None, costs=Decimal("0.0"), count=0): |
57 if code in statusCodes.keys(): |
55 self.code = code |
58 self.code = code |
56 |
59 else: |
57 self.exID = exID |
60 raise StatusException(code) |
58 self.costs = Decimal(costs) |
61 self.mID=mID |
59 self.count = int(count) |
62 self.cost = cost |
|
63 self.count = count |
|
64 |
60 |
65 def __str__(self): |
61 def __str__(self): |
66 try: |
62 if self.code in statusCodes.keys(): |
67 return "%i: %s"%(self.code, statusCodes[self.code]) |
63 return "%i: %s"%(self.code, statusCodes[self.code]) |
68 except IndexError: |
64 |
69 raise StatusException(self.code) |
65 return "%i: unknown statuscode."%self.code |
70 |
66 |
71 def __int__(self): |
67 def __int__(self): |
72 if not self.code in statusCodes.keys(): |
|
73 raise StatusException(self.code) |
|
74 return self.code |
68 return self.code |
75 |
69 |
76 class Smstrade(Provider): |
70 class Smstrade(Provider): |
77 """ |
71 """ |
78 s. auch http://kundencenter.smstrade.de/sites/smstrade.de.kundencenter/__pdf/SMS-Gateway_HTTP_API_v2.pdf |
72 s. auch http://kundencenter.smstrade.de/sites/smstrade.de.kundencenter/__pdf/SMS-Gateway_HTTP_API_v2.pdf |
90 "key":Option(lambda x,y:x,long="smstrade Gateway Key https://login.smstrade.de/index.php?gateway", must=True) |
84 "key":Option(lambda x,y:x,long="smstrade Gateway Key https://login.smstrade.de/index.php?gateway", must=True) |
91 }) |
85 }) |
92 |
86 |
93 def send(self, route, sms, recipient): |
87 def send(self, route, sms, recipient): |
94 """send SMS with $sms to $recipients""" |
88 """send SMS with $sms to $recipients""" |
95 logger.debug('smstrade.sendSMS(%s,%s)'%(sms, recipient)) |
89 #logger.debug('smstrade.sendSMS(%s,%s)'%(sms, recipient)) |
|
90 |
96 route = unicode(route) |
91 route = unicode(route) |
97 |
92 |
98 if recipient.land != '49' and route == "basic": |
93 if recipient.land != '49' and route == "basic": |
99 raise RejectRecipient(recipient) |
94 raise RejectRecipient(recipient) |
100 |
95 |
101 to ='00'+recipient.land+recipient.number |
96 to ='00'+recipient.land+recipient.number |
102 |
97 |
103 smsSendStatus = self.__send(route, to, sms) |
98 s = self.__send(route, to, sms) |
104 logger.info('smstrade._send(...)=%i(%s)'%(int(smsSendStatus),str(smsSendStatus))) |
99 if int(s) in (100,): |
105 if int(smsSendStatus) in (100,): |
100 return Status(self,route, exID=s.exID, costs=s.costs, count=s.count) |
106 return Status(self,route) |
101 elif int(s) in (70,71,): |
107 elif int(smsSendStatus) in (70,71,): |
102 raise RejectRecipient(recipient, status=s) |
108 raise RejectRecipient(recipient, status=smsSendStatus) |
|
109 else: |
103 else: |
110 raise StatusException(smsSendStatus) |
104 raise SmstradeException(s) |
111 |
105 |
112 def __send(self, route, to, sms): |
106 def __send(self, route, to, sms): |
113 """ This function is the main part of the request to the sms service. |
107 """ This function is the main part of the request to the sms service. |
114 The function has to return a unicode formated string that will represent the answer of the sms service |
108 The function has to return a unicode formated string that will represent the answer of the sms service |
115 to the request.""" |
109 to the request.""" |
116 logger.debug('smstrade._send(%s,%s,%s)'%( route, to, sms)) |
110 #logger.debug('smstrade._send(%s,%s,%s)'%( route, to, sms)) |
117 parameters= {"key": self.key, |
111 parameters= {"key": self.key, |
118 "route": route, |
112 "route": route, |
119 "to": to, |
113 "to": to, |
120 "message": sms.content.encode("utf-8"), |
114 "message": sms.content.encode("utf-8"), |
121 "charset":"utf-8", |
115 "charset":"utf-8", |
138 ps={} |
132 ps={} |
139 for p in parameters: |
133 for p in parameters: |
140 if p in self.params.keys(): |
134 if p in self.params.keys(): |
141 if self.params[p][0] == "boolean": |
135 if self.params[p][0] == "boolean": |
142 if parameters[p] != self.params[p][1]: |
136 if parameters[p] != self.params[p][1]: |
143 ps[p]=int(not self.params[p][1]) |
137 ps[p]=int(bool(parameters[p])) |
144 else: |
138 else: |
145 ps[p] = parameters[p] |
139 ps[p] = parameters[p] |
146 |
140 |
147 params = urllib.urlencode(ps) |
141 params = urllib.urlencode(ps) |
148 dp=copy.deepcopy(ps) |
142 #dp=copy.deepcopy(ps) |
149 dp["key"]="<KEY>" |
143 #dp["key"]="<KEY>" |
150 logger.debug('smstrade._send-parameters:%s\n\t->%s'%(str(dp), urllib.urlencode(dp)) ) |
144 #logger.debug('smstrade._send-parameters:%s\n\t->%s'%(str(dp), urllib.urlencode(dp)) ) |
151 |
145 |
152 response = urllib.urlopen(self.url, params) |
146 response = urllib.urlopen(self.url, params) |
153 data = response.readlines() |
147 data = response.readlines() |
154 if len(data) == 1: |
148 if len(data) == 1: |
155 return StatusCode(int(data[0])) |
149 return StatusCode(int(data[0])) |
156 return StatusCode(int(data[0]),mID=data[1],cost=data[2],count=data[3]) |
150 return StatusCode(int(data[0]),exID=data[1],costs=data[2],count=data[3]) |
157 |
151 |
158 def getSendFunc(self, typ, route): |
152 def getSendFunc(self, typ, route): |
159 Provider.getSendFunc(self, typ, route) |
153 Provider.getSendFunc(self, typ, route) |
160 return partial(self.send,route) |
154 return partial(self.send,route) |
161 |
155 |