diff -r b218238e76b9 -r 97826c8248f9 iro/offer/sipgate.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iro/offer/sipgate.py Tue Apr 24 23:59:00 2012 +0200 @@ -0,0 +1,118 @@ +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 +