Changeset 2122

Show
Ignore:
Timestamp:
03/24/07 22:17:40 (2 years ago)
Author:
athomas
Message:

XmlRpcPlugin:

First pass at JSON support.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • xmlrpcplugin/0.10/tracrpc/api.py

    r1950 r2122  
    11from trac.core import * 
    2 from trac.perm import IPermissionRequestor 
    32import inspect 
    43import types 
     
    141140class XMLRPCSystem(Component): 
    142141    """ Core of the XML-RPC system. """ 
    143     implements(IPermissionRequestor, IXMLRPCHandler) 
     142    implements(IXMLRPCHandler) 
    144143 
    145144    method_handlers = ExtensionPoint(IXMLRPCHandler) 
    146145 
    147     # IPermissionRequestor methods 
    148     def get_permission_actions(self): 
    149         yield 'XML_RPC' 
    150  
    151     # IXMLRPCHandler methods 
     146    #     # IXMLRPCHandler methods 
    152147    def xmlrpc_namespace(self): 
    153148        return 'system' 
  • xmlrpcplugin/0.10/tracrpc/__init__.py

    r246 r2122  
    44from tracrpc.wiki import * 
    55from tracrpc.search import * 
     6from tracrpc.xml_rpc import * 
     7from tracrpc.json_rpc import * 
  • xmlrpcplugin/0.10/tracrpc/templates/xmlrpclist.cs

    r1519 r2122  
    55 
    66<div id="content" class="wiki"> 
     7 
     8<div id="test"> 
     9Hello world 
     10</div> 
    711 
    812<h2>XML-RPC exported functions</h2> 
     
    2630<tbody> 
    2731<?cs each:function = namespace.methods ?> 
    28 <tr class="color3-<?cs if idx % #2 == 0 ?>even<?cs else ?>odd<?cs /if ?>" style=""> 
    29 <td><nobr><?cs var:function.0?></nobr></td><td><?cs var:function.1?></td><td><?cs var:function.2 ?></td> 
     32<tr class="<?cs if idx % #2 == 0 ?>even<?cs else ?>odd<?cs /if ?>" style=""> 
     33<td><div class="function"><?cs var:function.0?></div></td><td><?cs var:function.1?></td><td><?cs var:function.2 ?></td> 
    3034</tr> 
    3135<?cs set idx = idx + #1 ?> 
     
    3842</div> 
    3943 
    40 <script type="text/javascript"> 
    41 addHeadingLinks(document.getElementById("searchable")); 
     44<script type="text/javascript">//<![CDATA[ 
     45$.fn.addAnchor = function(title) { 
     46  title = title || "Link here"; 
     47  return this.filter("*[@id]").each(function() { 
     48    $("<a class='anchor'> \u00B6</a>").attr("href", "#" + this.id) 
     49      .attr("title", title).appendTo(this); 
     50  }); 
     51
     52 
     53$(document).ready(function(){ 
     54  $("#content").find("h1,h2,h3,h4,h5,h6").addAnchor("Link to this section"); 
     55 
     56  rpc = new $.jsonrpc("http://localhost:8080/stable/jsonrpc"); 
     57  rpc.expose("wiki.getRPCVersionSupported"); 
     58  rpc.expose("wiki.getPage"); 
     59  rpc.expose("wiki.getAllPages"); 
     60  rpc.expose("wiki.getPageHTML"); 
     61  rpc.expose("search.performSearch"); 
     62  rpc.expose("ticket.status.getAll"); 
     63 
     64  $("#test").click(function() { 
     65    //$("#content table tr.color3-even").contains("WIKI_VIEW").toggle(); 
     66 
     67    rpc.server.search.performSearch(function(hits) { 
     68          for (var i in hits) { 
     69                $("#test").after(escape(hits[i][3]) + "<br>\n"); 
     70          } 
     71    }, "alec thomas"); 
     72  }) 
     73}); 
     74//]]> 
    4275</script> 
    4376 
  • xmlrpcplugin/0.10/tracrpc/ticket.py

    r1950 r2122  
    9090                self.log.exception("Failure sending notification on creation " 
    9191                                   "of ticket #%s: %s" % (t.id, e)) 
    92                  
     92 
    9393        return t.id 
    9494 
     
    119119    def changeLog(self, req, id, when=0): 
    120120        t = model.Ticket(self.env, id) 
     121        #return [change for change in 
     122        #        [field is not None and field or '' for field 
     123        #         in t.get_changelog(when)]] 
    121124        return t.get_changelog(when) 
    122125    # Use existing documentation from Ticket model 
  • xmlrpcplugin/0.10/tracrpc/web_ui.py

    r1175 r2122  
    11from trac.core import * 
     2from trac.web.chrome import ITemplateProvider 
     3from pkg_resources import resource_filename 
    24from trac.web.main import IRequestHandler 
    3 from trac.web.chrome import ITemplateProvider, add_stylesheet 
    4 from tracrpc.api import IXMLRPCHandler, XMLRPCSystem 
     5from trac.web.chrome import add_stylesheet, add_script 
     6from tracrpc.api import XMLRPCSystem 
     7from trac.perm import IPermissionRequestor 
    58from trac.wiki.formatter import wiki_to_oneliner 
    6 import xmlrpclib 
    79 
    8 class XMLRPCWeb(Component): 
    9     """ Handle XML-RPC calls from HTTP clients, as well as presenting a list of 
    10         methods available to the currently logged in user. Browsing to 
    11         <trac>/xmlrpc will display this list. """ 
    1210 
    13     implements(IRequestHandler, ITemplateProvider) 
     11class ProcedureList(Component): 
     12    implements(ITemplateProvider, IPermissionRequestor, IRequestHandler) 
     13 
     14    # IPermissionRequestor methods 
     15    def get_permission_actions(self): 
     16        yield 'RPC_VIEW' 
     17 
     18    # ITemplateProvider 
     19    def get_htdocs_dirs(self): 
     20        return [('tracrpc', resource_filename(__name__, 'htdocs'))] 
     21 
     22    def get_templates_dirs(self): 
     23        return [resource_filename(__name__, 'templates')] 
    1424 
    1525    # IRequestHandler methods 
    1626    def match_request(self, req): 
    17         return req.path_info in ('/login/xmlrpc', '/xmlrpc') 
    18  
    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) 
     27        return req.path_info == '/rpc' 
    2528 
    2629    def process_request(self, req): 
    27         # Need at least XML_RPC 
    28         req.perm.assert_permission('XML_RPC') 
     30        req.perm.assert_permission('RPC_VIEW') 
    2931 
    30         # Dump RPC functions 
    31         content_type = req.get_header('Content-Type') 
    32         if content_type is None or 'text/xml' not in content_type: 
    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                         } 
    42                 try: 
    43                     namespaces[namespace]['methods'].append((method.signature, wiki_to_oneliner(method.description, self.env), method.permission)) 
    44                 except Exception, e: 
    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') 
    51             req.hdf['xmlrpc.functions'] = namespaces 
    52             return 'xmlrpclist.cs', None 
     32        namespaces = {} 
    5333 
    54         # Handle XML-RPC call 
    55         args, method = xmlrpclib.loads(req.read(int(req.get_header('Content-Length')))) 
    56         try: 
    57             result = XMLRPCSystem(self.env).get_method(method)(req, args) 
    58             self._send_response(req, xmlrpclib.dumps(result, methodresponse=True)) 
    59         except xmlrpclib.Fault, e: 
    60             self.log.error(e) 
    61             self._send_response(req, xmlrpclib.dumps(e)) 
    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()) 
    69             self._send_response(req, xmlrpclib.dumps(xmlrpclib.Fault(2, "'%s' while executing '%s()'" % (str(e), method)))) 
     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' : 
     39                        wiki_to_oneliner(method.namespace_description, self.env), 
     40                    'methods' : [], 
     41                    'namespace' : method.namespace, 
     42                    } 
     43            try: 
     44                namespaces[namespace]['methods'].append((method.signature, 
     45                    wiki_to_oneliner(method.description, self.env), 
     46                    method.permission)) 
     47            except Exception, e: 
     48                from StringIO import StringIO 
     49                import traceback 
     50                out = StringIO() 
     51                traceback.print_exc(file=out) 
     52                raise Exception('%s: %s\n%s' % (method.name, str(e), 
     53                                                out.getvalue())) 
    7054 
    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')] 
     55        add_stylesheet(req, 'common/css/wiki.css') 
     56        add_stylesheet(req, 'tracrpc/css/rpc.css') 
     57        add_script(req, 'tracrpc/js/jquery.js') 
     58        add_script(req, 'tracrpc/js/json.js') 
     59        add_script(req, 'tracrpc/js/jsonrpc.js') 
     60        req.hdf['xmlrpc.functions'] = namespaces 
     61        return 'xmlrpclist.cs', None 
  • xmlrpcplugin/sandbox/setup.py

    r1278 r2122  
    1212    zip_safe=True, 
    1313    packages=['tracrpc'], 
    14     package_data={'tracrpc': ['templates/*.cs']}, 
    15     entry_points={'trac.plugins': 'TracXMLRPC = tracrpc'}, 
    16     ) 
     14    package_data={ 
     15        'tracrpc': [ 
     16            'templates/*.cs', 
     17            'htdocs/js/*.js' 
     18        ] 
     19    }, 
     20    entry_points={ 
     21        'trac.plugins': [ 
     22            'tracrpc.web_ui = tracrpc.web_ui', 
     23            'tracrpc.json_rpc = tracrpc.json_rpc', 
     24            'tracrpc.xml_rpc = tracrpc.xml_rpc', 
     25            'tracrpc.api = tracrpc.api', 
     26            'tracrpc.search = tracrpc.search', 
     27            'tracrpc.ticket = tracrpc.ticket', 
     28            'tracrpc.util = tracrpc.util', 
     29            'tracrpc.wiki = tracrpc.wiki', 
     30        ] 
     31    } 
     32