1 # -*- coding: utf-8 -*- |
1 # -*- coding: utf-8 -*- |
2 |
2 |
3 # Copyright (c) 2012 netzguerilla.net <iro@netzguerilla.net> |
3 # Copyright (c) 2012 netzguerilla.net <iro@netzguerilla.net> |
4 # |
4 # |
5 # This file is part of Iro. |
5 # This file is part of Iro. |
6 # |
6 # |
7 # Permission is hereby granted, free of charge, to any person obtaining a copy of |
7 # Permission is hereby granted, free of charge, to any person obtaining a copy of |
8 # this software and associated documentation files (the "Software"), to deal in |
8 # this software and associated documentation files (the "Software"), to deal in |
9 # the Software without restriction, including without limitation the rights to use, |
9 # the Software without restriction, including without limitation the rights to use, |
10 # copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
10 # copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
11 # #Software, and to permit persons to whom the Software is furnished to do so, |
11 # #Software, and to permit persons to whom the Software is furnished to do so, |
12 # subject to the following conditions: |
12 # subject to the following conditions: |
13 # |
13 # |
14 # The above copyright notice and this permission notice shall be included in |
14 # The above copyright notice and this permission notice shall be included in |
15 # all copies or substantial portions of the Software. |
15 # all copies or substantial portions of the Software. |
16 # |
16 # |
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
18 # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
18 # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
19 # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
19 # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
20 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
20 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
55 """An excetion that connects the status code with the excetion string (see :attr:`statusCodes`)""" |
55 """An excetion that connects the status code with the excetion string (see :attr:`statusCodes`)""" |
56 def __init__(self,status): |
56 def __init__(self,status): |
57 ExternalException.__init__(self) |
57 ExternalException.__init__(self) |
58 self.status = status |
58 self.status = status |
59 self.str_=str(status) |
59 self.str_=str(status) |
60 |
60 |
61 def __str__(self): |
61 def __str__(self): |
62 return "%s\n%s"%(ExternalException.__str__(self),self.str_) |
62 return "%s\n%s"%(ExternalException.__str__(self),self.str_) |
63 |
63 |
64 |
64 |
65 class StatusCode: |
65 class StatusCode: |
66 """Class that represents the output of one smstrade request.""" |
66 """Class that represents the output of one smstrade request.""" |
67 def __init__(self,code, exID=None, costs=Decimal("0.0"), count=0): |
67 def __init__(self,code, exID=None, costs=Decimal("0.0"), count=0): |
68 self.code = code |
68 self.code = code |
69 |
69 |
70 self.exID = exID |
70 self.exID = exID |
71 try: |
71 try: |
72 self.costs = Decimal(costs) |
72 self.costs = Decimal(costs) |
73 except: |
73 except: |
74 if not costs.strip(): |
74 if not costs.strip(): |
75 self.costs = Decimal("0.0") |
75 self.costs = Decimal("0.0") |
76 else: |
76 else: |
77 raise |
77 raise |
78 self.count = int(count) |
78 self.count = int(count) |
79 |
79 |
80 def __str__(self): |
80 def __str__(self): |
81 if self.code in statusCodes.keys(): |
81 if self.code in statusCodes.keys(): |
82 return "%i: %s"%(self.code, statusCodes[self.code]) |
82 return "%i: %s"%(self.code, statusCodes[self.code]) |
83 |
83 |
84 return "%i: unknown statuscode."%self.code |
84 return "%i: unknown statuscode."%self.code |
85 |
85 |
86 def __int__(self): |
86 def __int__(self): |
87 return self.code |
87 return self.code |
88 |
88 |
102 "count":('boolean',False), |
102 "count":('boolean',False), |
103 "cost":('boolean',False), |
103 "cost":('boolean',False), |
104 } |
104 } |
105 '''dict for standrd values of the smstrade api, it is used to get the right values to the API.''' |
105 '''dict for standrd values of the smstrade api, it is used to get the right values to the API.''' |
106 |
106 |
107 def __init__(self, name): |
107 def __init__(self, name): |
108 self.url = "https://gateway.smstrade.de" |
108 self.url = "https://gateway.smstrade.de" |
109 options =[("key", Option(lambda x,y:x,long="smstrade Gateway Key https://login.smstrade.de/index.php?gateway", must=True)),] |
109 options =[("key", Option(lambda x,y:x,long="smstrade Gateway Key https://login.smstrade.de/index.php?gateway", must=True)),] |
110 Provider.__init__(self, name, {"sms":["basic","economy","gold","direct"]},options) |
110 Provider.__init__(self, name, {"sms":["basic","economy","gold","direct"]},options) |
111 |
111 |
112 def send(self, route, recipient, sms): |
112 def send(self, route, recipient, sms): |
113 """send one SMS to recipient via route |
113 """send one SMS to recipient via route |
114 |
114 |
115 :param string route: A valid route ``["basic", "economy", "gold", "direct"]`` |
115 :param string route: A valid route ``["basic", "economy", "gold", "direct"]`` |
116 :param `iro.telnumber.Telnumber` recipient: Mobilenumber of recipient |
116 :param `iro.telnumber.Telnumber` recipient: Mobilenumber of recipient |
117 :param `iro.model.message.SMS` sms: the sms to send |
117 :param `iro.model.message.SMS` sms: the sms to send |
118 :return: |
118 :return: |
119 - All went ok -- :class:`iro.model.status.Status` object |
119 - All went ok -- :class:`iro.model.status.Status` object |
123 |
123 |
124 route = unicode(route) |
124 route = unicode(route) |
125 |
125 |
126 if recipient.land != '49' and route == "basic": |
126 if recipient.land != '49' and route == "basic": |
127 raise RejectRecipient(recipient) |
127 raise RejectRecipient(recipient) |
128 |
128 |
129 to ='00'+recipient.land+recipient.number |
129 to ='00'+recipient.land+recipient.number |
130 |
130 |
131 s = self.__send(route, to, sms) |
131 s = self.__send(route, to, sms) |
132 s.costs = Decimal('0.0728') |
132 s.costs = Decimal('0.0728') |
133 if int(s) in (100,): |
133 if int(s) in (100,): |
136 raise RejectRecipient(recipient, status=s) |
136 raise RejectRecipient(recipient, status=s) |
137 else: |
137 else: |
138 raise SmstradeException(s) |
138 raise SmstradeException(s) |
139 |
139 |
140 def __send(self, route, to, sms): |
140 def __send(self, route, to, sms): |
141 """ This is the main function to request to the sms service. |
141 """ This is the main function to request to the sms service. |
142 |
142 |
143 :param string route: A valid route ``["basic", "economy", "gold", "direct"] |
143 :param string route: A valid route ``["basic", "economy", "gold", "direct"] |
144 :param string recipient: Mobilenumber of recipient |
144 :param string recipient: Mobilenumber of recipient |
145 :param `iro.model.message.sms` sms: the sms to send |
145 :param `iro.model.message.sms` sms: the sms to send |
146 :return: a :class:`.StatusCode` object |
146 :return: a :class:`.StatusCode` object |
147 """ |
147 """ |
148 |
148 |
149 #logger.debug('smstrade._send(%s,%s,%s)'%( route, to, sms)) |
149 #logger.debug('smstrade._send(%s,%s,%s)'%( route, to, sms)) |
150 parameters= {"key": self.key, |
150 parameters= {"key": self.key, |
151 "route": route, |
151 "route": route, |
152 "to": to, |
152 "to": to, |
153 "message": sms.content, |
153 "message": sms.content, |
154 "charset":"utf-8", |
154 "charset":"utf-8", |
155 "debug": self.testmode, |
155 "debug": self.testmode, |
156 "message_id":True, |
156 "message_id":True, |
157 "count":True, |
157 "count":True, |
158 "cost":True, |
158 "cost":True, |
159 } |
159 } |
160 |
160 |
161 doubleChar="€[]{}|\\^~" #these charactar need two GSM Chars |
161 doubleChar="€[]{}|\\^~" #these charactar need two GSM Chars |
162 |
162 |
163 if sms.from_ is not None: |
163 if sms.from_ is not None: |
164 parameters["from"] = sms.from_ |
164 parameters["from"] = sms.from_ |
165 |
165 |
166 length=len(sms.content) |
166 length=len(sms.content) |
167 for s in doubleChar: |
167 for s in doubleChar: |
168 length += sms.content.count(s) |
168 length += sms.content.count(s) |
169 parameters["concat_sms"] = True if length > 160 else False |
169 parameters["concat_sms"] = True if length > 160 else False |
170 |
170 |