iro/offer/sipgate.py
changeset 302 3f4bdea2abbf
parent 294 0e75bd39767d
child 312 42fd5075a5d1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/iro/offer/sipgate.py	Thu Sep 27 17:15:46 2012 +0200
@@ -0,0 +1,139 @@
+# Copyright (c) 2012 netzguerilla.net <iro@netzguerilla.net>
+# 
+# This file is part of Iro.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+# #Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+from functools import partial
+from twisted.web.xmlrpc import Proxy
+import xmlrpclib
+from decimal import Decimal
+
+from .provider import providers, Provider
+from ..config import Option
+from ..validate import vFloat
+from ..model.status import Status
+from ..error import NoTyp
+from .. import __version__
+
+
+class Sipgate(Provider):
+    """
+        s. auch http.tuxad.com/sipgate.html
+        und http://lists.sipgate.net/pipermail/sipgate-developers/2007-September/000016.html
+
+        http://www.sipgate.de/beta/public/static/downloads/basic/api/sipgate_api_documentation.pdf
+
+        See :doc:`provider` for a tutorial, how to create a new provider backend. This turorial implements this provider.
+    """
+
+    url="https://%s:%s@samurai.sipgate.net/RPC2"
+    """XML-RPC url for sipgate"""
+
+    def __init__(self,name):
+        options =[("username", Option(lambda x,y: x,long="Loginname for sipgate", must=True)),
+                  ("password", Option(lambda x,y: x,long="Password for sipgate", must=True)),
+                  ("price_sms", Option(vFloat, long="price for one sms", default="0.079")),
+                  ("price_fax", Option(vFloat, long="price for one fax", default="0.03")),
+                  ]
+        Provider.__init__(self, name, {"sms" : [None], "fax":[None]}, options)
+
+    def proxy(self):
+        """returns a XML-RPC proxy object to sipgate API."""
+        return Proxy(self.url%(self.username, self.password))
+
+    def load(self,cfg):
+        """Loads configuration into object.
+
+        :param dict cfg: The Configuration dict. Normally you use ``configParser.items("section")``.
+        """
+
+        Provider.load(self,cfg)
+        #return self.clientIdentify()
+
+    def clientIdentify(self):
+        """identificaton of client to sipgate server."""
+        args_identify = {
+                "ClientName"    : "Iro",
+                "ClientVersion" : __version__,
+                "ClientVendor"  : "netzguerilla.net"
+                }
+
+        return self.proxy().callRemote("samurai.ClientIdentify", args_identify)
+
+    def sms(self, recipient, sms):
+        """send one SMS to recimpient.
+
+        :param `iro.telnumber.Telnumber` recipient: mobilenumber of recipient
+        :param `iro.model.message.SMS` sms: the sms to send
+        :return: a deferrer
+        """
+        args={
+                "TOS" : "text",
+                "Content" : sms.getContent(),
+                "RemoteUri" : "sip:%s%s@sipgate.net"%(recipient.land, recipient.number),
+                }
+        return self.proxy().callRemote("samurai.SessionInitiate",args)
+
+    def fax(self, recipient, fax):
+        """send one fax to recimpient.
+
+        :param `iro.telnumber.Telnumber` recipient: faxnumber of recipient
+        :param `iro.model.message.Fax` fax: the fax to send
+        :return: a deferrer.
+        """
+
+        args={
+            "TOS" : "fax",
+            "Content" : xmlrpclib.Binary(fax.getAttachment(0)),
+            "RemoteUri" : "sip:%s%s@sipgate.net"%(recipient.land, recipient.number),
+            }
+        return self.proxy().callRemote("samurai.SessionInitiate",args)
+
+    def _status(self,value,typ):
+        """returns a :class:`~iro.model.status.Status` object.
+        :raises: :exc:`iro.error.NoTyp`
+        """
+        if typ not  in self.typs.keys():
+            raise NoTyp(typ)
+        return Status(self, None, Decimal(getattr(self,"price_"+typ)), 1, value["SessionID"])
+
+    def send(self, typ, recipient, msg):
+        """send msg to recipient.
+
+        :param string typ: Typ of message.
+        :param `iro.telnumber.Telnumber` recipient: telnumber of recipient
+        :param msg: the msg to send
+        :type msg: :class:`iro.model.message.Fax` or :class:`iro.model.message.SMS`
+        :return: a deferrer, that returns a :class:`~iro.model.status.Status` object
+        :raises: :exc:`iro.error.NoTyp`
+        """
+        if typ not  in self.typs.keys():
+            raise NoTyp(typ)
+        d = getattr(self,typ)(recipient, msg)
+        d.addCallback(self._status, typ)
+        return d
+
+    def getSendFunc(self, typ, route):
+        """returns :meth:`send` method with bound typ, if typ and route is valid."""
+
+        Provider.getSendFunc(self, typ, route)
+        return partial(self.send, typ)
+
+providers["sipgate"] = Sipgate
+