PageRenderTime 287ms CodeModel.GetById 278ms app.highlight 6ms RepoModel.GetById 2ms app.codeStats 0ms

/circuits/web/dispatchers/xmlrpc.py

https://bitbucket.org/prologic/circuits/
Python | 65 lines | 38 code | 18 blank | 9 comment | 8 complexity | 8af4496f7225e05ac7ba7c5fc5f4b493 MD5 | raw file
 1# Module:   xmlrpc
 2# Date:     13th September 2007
 3# Author:   James Mills, prologic at shortcircuit dot net dot au
 4
 5"""XML RPC
 6
 7This module implements a XML RPC dispatcher that translates incoming
 8RPC calls over XML into RPC events.
 9"""
10
11try:
12    from xmlrpc.client import dumps, loads, Fault
13except ImportError:
14    from xmlrpclib import dumps, loads, Fault  # NOQA
15
16from circuits.six import binary_type
17from circuits import handler, Event, BaseComponent
18
19
20class rpc(Event):
21    """rpc Event"""
22
23
24class XMLRPC(BaseComponent):
25
26    channel = "web"
27
28    def __init__(self, path=None, encoding="utf-8", rpc_channel="*"):
29        super(XMLRPC, self).__init__()
30
31        self.path = path
32        self.encoding = encoding
33        self.rpc_channel = rpc_channel
34
35    @handler("request", priority=0.2)
36    def _on_request(self, event, req, res):
37        if self.path is not None and self.path != req.path.rstrip("/"):
38            return
39
40        res.headers["Content-Type"] = "text/xml"
41
42        try:
43            data = req.body.read()
44            params, method = loads(data)
45
46            if "." in method:
47                channel, name = method.split(".", 1)
48            else:
49                channel, name = self.rpc_channel, method
50
51            name = str(name) if not isinstance(name, binary_type) else name
52
53            value = yield self.call(rpc.create(name, *params), channel)
54            yield self._response(value.value)
55        except Exception as e:
56            yield self._error(1, "%s: %s" % (type(e), e))
57        finally:
58            event.stop()
59
60    def _response(self, result):
61        return dumps((result,), encoding=self.encoding, allow_none=True)
62
63    def _error(self, code, message):
64        fault = Fault(code, message)
65        return dumps(fault, encoding=self.encoding, allow_none=True)