source: xmlrpcplugin/0.10/tracrpc/web_ui.py

Last change on this file was 1175, checked in by Alec Thomas, 17 years ago

XmlRpcPlugin:

Fixes #623.

File size: 3.2 KB
RevLine 
[218]1from trac.core import *
2from trac.web.main import IRequestHandler
[808]3from trac.web.chrome import ITemplateProvider, add_stylesheet
[219]4from tracrpc.api import IXMLRPCHandler, XMLRPCSystem
5from trac.wiki.formatter import wiki_to_oneliner
[218]6import xmlrpclib
7
8class XMLRPCWeb(Component):
[219]9    """ Handle XML-RPC calls from HTTP clients, as well as presenting a list of
[225]10        methods available to the currently logged in user. Browsing to
[227]11        <trac>/xmlrpc will display this list. """
[219]12
[218]13    implements(IRequestHandler, ITemplateProvider)
14
15    # IRequestHandler methods
16    def match_request(self, req):
[227]17        return req.path_info in ('/login/xmlrpc', '/xmlrpc')
[218]18
[226]19    def _send_response(self, req, response):
20        req.send_response(200)
21        req.send_header('Content-Type', 'text/xml')
22        req.send_header('Content-Length', len(response))
23        req.end_headers()
24        req.write(response)
25
[218]26    def process_request(self, req):
[222]27        # Need at least XML_RPC
28        req.perm.assert_permission('XML_RPC')
29
[219]30        # Dump RPC functions
[1070]31        content_type = req.get_header('Content-Type')
[1175]32        if content_type is None or 'text/xml' not in content_type:
[225]33            namespaces = {}
34            for method in XMLRPCSystem(self.env).all_methods(req):
35                namespace = method.namespace.replace('.', '_')
36                if namespace not in namespaces:
37                    namespaces[namespace] = {
38                        'description' : wiki_to_oneliner(method.namespace_description, self.env),
39                        'methods' : [],
40                        'namespace' : method.namespace,
41                        }
[229]42                try:
43                    namespaces[namespace]['methods'].append((method.signature, wiki_to_oneliner(method.description, self.env), method.permission))
44                except Exception, e:
[808]45                    from StringIO import StringIO
46                    import traceback
47                    out = StringIO()
48                    traceback.print_exc(file=out)
49                    raise Exception('%s: %s\n%s' % (method.name, str(e), out.getvalue()))
50            add_stylesheet(req, 'common/css/wiki.css')
[225]51            req.hdf['xmlrpc.functions'] = namespaces
[218]52            return 'xmlrpclist.cs', None
53
54        # Handle XML-RPC call
[225]55        args, method = xmlrpclib.loads(req.read(int(req.get_header('Content-Length'))))
[224]56        try:
[225]57            result = XMLRPCSystem(self.env).get_method(method)(req, args)
[226]58            self._send_response(req, xmlrpclib.dumps(result, methodresponse=True))
[224]59        except xmlrpclib.Fault, e:
[848]60            self.log.error(e)
[226]61            self._send_response(req, xmlrpclib.dumps(e))
[224]62        except Exception, e:
63            self.log.error(e)
64            import traceback
65            from StringIO import StringIO
66            out = StringIO()
67            traceback.print_exc(file = out)
68            self.log.error(out.getvalue())
[226]69            self._send_response(req, xmlrpclib.dumps(xmlrpclib.Fault(2, "'%s' while executing '%s()'" % (str(e), method))))
[219]70
[218]71    # ITemplateProvider
72    def get_htdocs_dirs(self):
73        return []
74
75    def get_templates_dirs(self):
76        from pkg_resources import resource_filename
77        return [resource_filename(__name__, 'templates')]
Note: See TracBrowser for help on using the repository browser.