/circuits/web/dispatchers/xmlrpc.py

https://bitbucket.org/prologic/circuits/ · Python · 65 lines · 38 code · 18 blank · 9 comment · 11 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. """XML RPC
  5. This module implements a XML RPC dispatcher that translates incoming
  6. RPC calls over XML into RPC events.
  7. """
  8. try:
  9. from xmlrpc.client import dumps, loads, Fault
  10. except ImportError:
  11. from xmlrpclib import dumps, loads, Fault # NOQA
  12. from circuits.six import binary_type
  13. from circuits import handler, Event, BaseComponent
  14. class rpc(Event):
  15. """rpc Event"""
  16. class XMLRPC(BaseComponent):
  17. channel = "web"
  18. def __init__(self, path=None, encoding="utf-8", rpc_channel="*"):
  19. super(XMLRPC, self).__init__()
  20. self.path = path
  21. self.encoding = encoding
  22. self.rpc_channel = rpc_channel
  23. @handler("request", priority=0.2)
  24. def _on_request(self, event, req, res):
  25. if self.path is not None and self.path != req.path.rstrip("/"):
  26. return
  27. res.headers["Content-Type"] = "text/xml"
  28. try:
  29. data = req.body.read()
  30. params, method = loads(data)
  31. if "." in method:
  32. channel, name = method.split(".", 1)
  33. else:
  34. channel, name = self.rpc_channel, method
  35. name = str(name) if not isinstance(name, binary_type) else name
  36. value = yield self.call(rpc.create(name, *params), channel)
  37. yield self._response(value.value)
  38. except Exception as e:
  39. yield self._error(1, "%s: %s" % (type(e), e))
  40. finally:
  41. event.stop()
  42. def _response(self, result):
  43. return dumps((result,), encoding=self.encoding, allow_none=True)
  44. def _error(self, code, message):
  45. fault = Fault(code, message)
  46. return dumps(fault, encoding=self.encoding, allow_none=True)