|
1 # Copyright (c) 2012 netzguerilla.net <iro@netzguerilla.net> |
|
2 # |
|
3 # This file is part of Iro. |
|
4 # |
|
5 # Permission is hereby granted, free of charge, to any person obtaining a copy of |
|
6 # this software and associated documentation files (the "Software"), to deal in |
|
7 # the Software without restriction, including without limitation the rights to use, |
|
8 # copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the |
|
9 # #Software, and to permit persons to whom the Software is furnished to do so, |
|
10 # subject to the following conditions: |
|
11 # |
|
12 # The above copyright notice and this permission notice shall be included in |
|
13 # all copies or substantial portions of the Software. |
|
14 # |
|
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
|
16 # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
|
17 # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
18 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|
19 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
|
20 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
21 |
|
22 from functools import partial |
|
23 from twisted.web.xmlrpc import Proxy |
|
24 import xmlrpclib |
|
25 from decimal import Decimal |
|
26 |
|
27 from .provider import providers, Provider |
|
28 from ..config import Option |
|
29 from ..validate import vFloat |
|
30 from ..model.status import Status |
|
31 from ..error import NoTyp |
|
32 from .. import __version__ |
|
33 |
|
34 |
|
35 class Sipgate(Provider): |
|
36 """ |
|
37 s. auch http.tuxad.com/sipgate.html |
|
38 und http://lists.sipgate.net/pipermail/sipgate-developers/2007-September/000016.html |
|
39 |
|
40 http://www.sipgate.de/beta/public/static/downloads/basic/api/sipgate_api_documentation.pdf |
|
41 |
|
42 See :doc:`provider` for a tutorial, how to create a new provider backend. This turorial implements this provider. |
|
43 """ |
|
44 |
|
45 url="https://%s:%s@samurai.sipgate.net/RPC2" |
|
46 """XML-RPC url for sipgate""" |
|
47 |
|
48 def __init__(self,name): |
|
49 options =[("username", Option(lambda x,y: x,long="Loginname for sipgate", must=True)), |
|
50 ("password", Option(lambda x,y: x,long="Password for sipgate", must=True)), |
|
51 ("price_sms", Option(vFloat, long="price for one sms", default="0.079")), |
|
52 ("price_fax", Option(vFloat, long="price for one fax", default="0.03")), |
|
53 ] |
|
54 Provider.__init__(self, name, {"sms" : [None], "fax":[None]}, options) |
|
55 |
|
56 def proxy(self): |
|
57 """returns a XML-RPC proxy object to sipgate API.""" |
|
58 return Proxy(self.url%(self.username, self.password)) |
|
59 |
|
60 def load(self,cfg): |
|
61 """Loads configuration into object. |
|
62 |
|
63 :param dict cfg: The Configuration dict. Normally you use ``configParser.items("section")``. |
|
64 """ |
|
65 |
|
66 Provider.load(self,cfg) |
|
67 #return self.clientIdentify() |
|
68 |
|
69 def clientIdentify(self): |
|
70 """identificaton of client to sipgate server.""" |
|
71 args_identify = { |
|
72 "ClientName" : "Iro", |
|
73 "ClientVersion" : __version__, |
|
74 "ClientVendor" : "netzguerilla.net" |
|
75 } |
|
76 |
|
77 return self.proxy().callRemote("samurai.ClientIdentify", args_identify) |
|
78 |
|
79 def sms(self, recipient, sms): |
|
80 """send one SMS to recimpient. |
|
81 |
|
82 :param `iro.telnumber.Telnumber` recipient: mobilenumber of recipient |
|
83 :param `iro.model.message.SMS` sms: the sms to send |
|
84 :return: a deferrer |
|
85 """ |
|
86 args={ |
|
87 "TOS" : "text", |
|
88 "Content" : sms.getContent(), |
|
89 "RemoteUri" : "sip:%s%s@sipgate.net"%(recipient.land, recipient.number), |
|
90 } |
|
91 return self.proxy().callRemote("samurai.SessionInitiate",args) |
|
92 |
|
93 def fax(self, recipient, fax): |
|
94 """send one fax to recimpient. |
|
95 |
|
96 :param `iro.telnumber.Telnumber` recipient: faxnumber of recipient |
|
97 :param `iro.model.message.Fax` fax: the fax to send |
|
98 :return: a deferrer. |
|
99 """ |
|
100 |
|
101 args={ |
|
102 "TOS" : "fax", |
|
103 "Content" : xmlrpclib.Binary(fax.getAttachment(0)), |
|
104 "RemoteUri" : "sip:%s%s@sipgate.net"%(recipient.land, recipient.number), |
|
105 } |
|
106 return self.proxy().callRemote("samurai.SessionInitiate",args) |
|
107 |
|
108 def _status(self,value,typ): |
|
109 """returns a :class:`~iro.model.status.Status` object. |
|
110 :raises: :exc:`iro.error.NoTyp` |
|
111 """ |
|
112 if typ not in self.typs.keys(): |
|
113 raise NoTyp(typ) |
|
114 return Status(self, None, Decimal(getattr(self,"price_"+typ)), 1, value["SessionID"]) |
|
115 |
|
116 def send(self, typ, recipient, msg): |
|
117 """send msg to recipient. |
|
118 |
|
119 :param string typ: Typ of message. |
|
120 :param `iro.telnumber.Telnumber` recipient: telnumber of recipient |
|
121 :param msg: the msg to send |
|
122 :type msg: :class:`iro.model.message.Fax` or :class:`iro.model.message.SMS` |
|
123 :return: a deferrer, that returns a :class:`~iro.model.status.Status` object |
|
124 :raises: :exc:`iro.error.NoTyp` |
|
125 """ |
|
126 if typ not in self.typs.keys(): |
|
127 raise NoTyp(typ) |
|
128 d = getattr(self,typ)(recipient, msg) |
|
129 d.addCallback(self._status, typ) |
|
130 return d |
|
131 |
|
132 def getSendFunc(self, typ, route): |
|
133 """returns :meth:`send` method with bound typ, if typ and route is valid.""" |
|
134 |
|
135 Provider.getSendFunc(self, typ, route) |
|
136 return partial(self.send, typ) |
|
137 |
|
138 providers["sipgate"] = Sipgate |
|
139 |