|
272
|
1 |
from functools import partial |
|
|
2 |
from twisted.web.xmlrpc import Proxy |
|
|
3 |
import xmlrpclib |
|
|
4 |
from decimal import Decimal |
|
|
5 |
|
|
|
6 |
from .provider import providers, Provider |
|
|
7 |
from ..config import Option |
|
|
8 |
from ..validate import vFloat |
|
|
9 |
from ..model.status import Status |
|
|
10 |
from ..error import NoTyp |
|
|
11 |
from .. import __version__ |
|
|
12 |
|
|
|
13 |
|
|
|
14 |
class Sipgate(Provider): |
|
|
15 |
""" |
|
|
16 |
s. auch http.tuxad.com/sipgate.html |
|
|
17 |
und http://lists.sipgate.net/pipermail/sipgate-developers/2007-September/000016.html |
|
|
18 |
|
|
|
19 |
http://www.sipgate.de/beta/public/static/downloads/basic/api/sipgate_api_documentation.pdf |
|
|
20 |
|
|
|
21 |
See :doc:`provider` for a tutorial, how to create a new provider backend. This turorial implements this provider. |
|
|
22 |
""" |
|
|
23 |
|
|
|
24 |
url="https://%s:%s@samurai.sipgate.net/RPC2" |
|
|
25 |
"""XML-RPC url for sipgate""" |
|
|
26 |
|
|
|
27 |
def __init__(self,name): |
|
|
28 |
options =[("username", Option(lambda x,y: x,long="Loginname for sipgate", must=True)), |
|
|
29 |
("password", Option(lambda x,y: x,long="Password for sipgate", must=True)), |
|
|
30 |
("price_sms", Option(vFloat, long="price for one sms", default="0.079")), |
|
|
31 |
("price_fax", Option(vFloat, long="price for one fax", default="0.03")), |
|
|
32 |
] |
|
|
33 |
Provider.__init__(self, name, {"sms" : [None], "fax":[None]}, options) |
|
|
34 |
|
|
|
35 |
def proxy(self): |
|
|
36 |
"""returns a XML-RPC proxy object to sipgate API.""" |
|
|
37 |
return Proxy(self.url%(self.username, self.password)) |
|
|
38 |
|
|
|
39 |
def load(self,cfg): |
|
|
40 |
"""Loads configuration into object. |
|
|
41 |
|
|
|
42 |
:param dict cfg: The Configuration dict. Normally you use ``configParser.items("section")``. |
|
|
43 |
""" |
|
|
44 |
|
|
|
45 |
Provider.load(self,cfg) |
|
|
46 |
#return self.clientIdentify() |
|
|
47 |
|
|
|
48 |
def clientIdentify(self): |
|
|
49 |
"""identificaton of client to sipgate server.""" |
|
|
50 |
args_identify = { |
|
|
51 |
"ClientName" : "Iro", |
|
|
52 |
"ClientVersion" : __version__, |
|
|
53 |
"ClientVendor" : "netzguerilla.net" |
|
|
54 |
} |
|
|
55 |
|
|
|
56 |
return self.proxy().callRemote("samurai.ClientIdentify", args_identify) |
|
|
57 |
|
|
|
58 |
def sms(self, recipient, sms): |
|
|
59 |
"""send one SMS to recimpient. |
|
|
60 |
|
|
|
61 |
:param `iro.telnumber.Telnumber` recipient: mobilenumber of recipient |
|
|
62 |
:param `iro.model.message.SMS` sms: the sms to send |
|
|
63 |
:return: a deferrer |
|
|
64 |
""" |
|
|
65 |
args={ |
|
|
66 |
"TOS" : "text", |
|
|
67 |
"Content" : sms.getContent(), |
|
|
68 |
"RemoteUri" : "sip:%s%s@sipgate.net"%(recipient.land, recipient.number), |
|
|
69 |
} |
|
|
70 |
return self.proxy().callRemote("samurai.SessionInitiate",args) |
|
|
71 |
|
|
|
72 |
def fax(self, recipient, fax): |
|
|
73 |
"""send one fax to recimpient. |
|
|
74 |
|
|
|
75 |
:param `iro.telnumber.Telnumber` recipient: faxnumber of recipient |
|
|
76 |
:param `iro.model.message.Fax` fax: the fax to send |
|
|
77 |
:return: a deferrer. |
|
|
78 |
""" |
|
|
79 |
|
|
|
80 |
args={ |
|
|
81 |
"TOS" : "fax", |
|
|
82 |
"Content" : xmlrpclib.Binary(fax.getAttachment(0)), |
|
|
83 |
"RemoteUri" : "sip:%s%s@sipgate.net"%(recipient.land, recipient.number), |
|
|
84 |
} |
|
|
85 |
return self.proxy().callRemote("samurai.SessionInitiate",args) |
|
|
86 |
|
|
|
87 |
def _status(self,value,typ): |
|
|
88 |
"""returns a :class:`~iro.model.status.Status` object. |
|
|
89 |
:raises: :exc:`iro.error.NoTyp` |
|
|
90 |
""" |
|
|
91 |
if typ not in self.typs.keys(): |
|
|
92 |
raise NoTyp(typ) |
|
|
93 |
return Status(self, None, Decimal(getattr(self,"price_"+typ)), 1, value["SessionID"]) |
|
|
94 |
|
|
|
95 |
def send(self, typ, recipient, msg): |
|
|
96 |
"""send msg to recipient. |
|
|
97 |
|
|
|
98 |
:param string typ: Typ of message. |
|
|
99 |
:param `iro.telnumber.Telnumber` recipient: telnumber of recipient |
|
|
100 |
:param msg: the msg to send |
|
|
101 |
:type msg: :class:`iro.model.message.Fax` or :class:`iro.model.message.SMS` |
|
|
102 |
:return: a deferrer, that returns a :class:`~iro.model.status.Status` object |
|
|
103 |
:raises: :exc:`iro.error.NoTyp` |
|
|
104 |
""" |
|
|
105 |
if typ not in self.typs.keys(): |
|
|
106 |
raise NoTyp(typ) |
|
|
107 |
d = getattr(self,typ)(recipient, msg) |
|
|
108 |
d.addCallback(self._status, typ) |
|
|
109 |
return d |
|
|
110 |
|
|
|
111 |
def getSendFunc(self, typ, route): |
|
|
112 |
"""returns :meth:`send` method with bound typ, if typ and route is valid.""" |
|
|
113 |
|
|
|
114 |
Provider.getSendFunc(self, typ, route) |
|
|
115 |
return partial(self.send, typ) |
|
|
116 |
|
|
|
117 |
providers["sipgate"] = Sipgate |
|
|
118 |
|