diff src/server/server.py @ 925:e00151140f77

server (pages): URIs handling: a page can now handle specific URIs by using uri_handlers variable: it's a dict mapping URIs (type/subtype) tuples to a callback. The callback must generate the URI path (relative to the page) including the needed URI data
author Goffi <goffi@goffi.org>
date Mon, 03 Apr 2017 01:00:29 +0200
parents 94f88277c2e7
children 612e33fd32a8
line wrap: on
line diff
--- a/src/server/server.py	Mon Apr 03 01:00:29 2017 +0200
+++ b/src/server/server.py	Mon Apr 03 01:00:29 2017 +0200
@@ -1422,6 +1422,7 @@
 class LiberviaPage(web_resource.Resource):
     isLeaf = True  # we handle subpages ourself
     named_pages = {}
+    uri_callbacks = {}
 
     def __init__(self, host, root_dir, name=None, redirect=None, access=None, parse_url=None,
                  prepare_render=None, render=None, template=None):
@@ -1497,8 +1498,8 @@
         if parse_url is not None and not callable(parse_url):
             log.error(_(u"parse_url must be a callable"))
 
-    @staticmethod
-    def importPages(host, parent=None, path=None):
+    @classmethod
+    def importPages(cls, host, parent=None, path=None):
         if path is None:
             path = []
         if parent is None:
@@ -1531,8 +1532,41 @@
                 parent.putChild(d, resource)
                 new_path = path + [d]
                 log.info(u"Added /{path} page".format(path=u'[...]/'.join(new_path)))
+                if 'uri_handlers' in page_data:
+                    if not isinstance(page_data, dict):
+                        log.error(_(u'uri_handlers must be a dict'))
+                    else:
+                        for uri_tuple, cb_name in page_data['uri_handlers'].iteritems():
+                            if len(uri_tuple) != 2 or not isinstance(cb_name, basestring):
+                                log.error(_(u"invalid uri_tuple"))
+                                continue
+                            log.info(_(u'setting {}/{} URIs handler').format(*uri_tuple))
+                            try:
+                                cb = page_data[cb_name]
+                            except KeyError:
+                                log.error(_(u'missing {name} method to handle {1}/{2}').format(
+                                    name = cb_name, *uri_tuple))
+                                continue
+                            else:
+                                cls.registerURI(uri_tuple, cb, new_path)
+
                 LiberviaPage.importPages(host, resource, new_path)
 
+    @classmethod
+    def registerURI(cls, uri_tuple, get_uri_cb, pre_path):
+        """register a URI handler
+
+        @param uri_tuple(tuple[unicode, unicode]): type or URIs handler
+            type/subtype as returned by tools/common/parseXMPPUri
+        @param get_uri_cb(callable): method which take uri_data dict as only argument
+            and return path with correct arguments relative to page itself
+        @param pre_path(list[unicode]): prefix path to reference the handler page
+        """
+        if uri_tuple in cls.uri_callbacks:
+            log.info(_(u"{}/{} URIs are already handled, replacing by the new handler").format(*uri_tuple))
+        cls.uri_callbacks[uri_tuple] = {u'callback': get_uri_cb,
+                                        u'pre_path': pre_path}
+
     def getChildWithDefault(self, path, request):
         # we handle children ourselves
         raise exceptions.InternalError(u"this method should not be used with LiberviaPage")