diff src/server/pages.py @ 1113:cdd389ef97bc

server: code style reformatting using black
author Goffi <goffi@goffi.org>
date Fri, 29 Jun 2018 17:45:26 +0200
parents 045e8bdaed4f
children
line wrap: on
line diff
--- a/src/server/pages.py	Sun Jun 24 22:21:25 2018 +0200
+++ b/src/server/pages.py	Fri Jun 29 17:45:26 2018 +0200
@@ -28,6 +28,7 @@
 from sat.tools.common import uri as common_uri
 from sat.tools.common import date_utils
 from sat.core.log import getLogger
+
 log = getLogger(__name__)
 from libervia.server.constants import Const as C
 from libervia.server import session_iface
@@ -41,12 +42,10 @@
 import time
 import hashlib
 
-WebsocketMeta = namedtuple("WebsocketMeta", ('url', 'token', 'debug'))
-
+WebsocketMeta = namedtuple("WebsocketMeta", ("url", "token", "debug"))
 
 
 class CacheBase(object):
-
     def __init__(self):
         self._created = time.time()
         self._last_access = self._created
@@ -65,7 +64,6 @@
 
 
 class CachePage(CacheBase):
-
     def __init__(self, rendered):
         super(CachePage, self).__init__()
         self._created = time.time()
@@ -83,7 +81,6 @@
 
 
 class CacheURL(CacheBase):
-
     def __init__(self, request):
         super(CacheURL, self).__init__()
         try:
@@ -93,7 +90,7 @@
         self._template_data = request.template_data.copy()
         self._prepath = request.prepath[:]
         self._postpath = request.postpath[:]
-        del self._template_data['csrf_token']
+        del self._template_data["csrf_token"]
 
     def use(self, request):
         self.last_access = time.time()
@@ -104,22 +101,36 @@
 
 
 class LiberviaPage(web_resource.Resource):
-    isLeaf = True  # we handle subpages ourself
+    isLeaf = True  #  we handle subpages ourself
     named_pages = {}
     uri_callbacks = {}
     signals_handlers = {}
     pages_redirects = {}
     cache = {}
     cached_urls = {}
-    # Set of tuples (service/node/sub_id) of nodes subscribed for caching
+    #  Set of tuples (service/node/sub_id) of nodes subscribed for caching
     # sub_id can be empty string if not handled by service
     cache_pubsub_sub = set()
     main_menu = None
 
-    def __init__(self, host, root_dir, url, name=None, redirect=None, access=None, dynamic=False, parse_url=None,
-                 prepare_render=None, render=None, template=None,
-                 on_data_post=None, on_data=None, on_signal=None,
-                 url_cache=False):
+    def __init__(
+        self,
+        host,
+        root_dir,
+        url,
+        name=None,
+        redirect=None,
+        access=None,
+        dynamic=False,
+        parse_url=None,
+        prepare_render=None,
+        render=None,
+        template=None,
+        on_data_post=None,
+        on_data=None,
+        on_signal=None,
+        url_cache=False,
+    ):
         """initiate LiberviaPages
 
         LiberviaPages are the main resources of Libervia, using easy to set python files
@@ -169,25 +180,39 @@
         self.name = name
         if name is not None:
             if name in self.named_pages:
-                raise exceptions.ConflictError(_(u'a Libervia page named "{}" already exists'.format(name)))
-            if u'/' in name:
+                raise exceptions.ConflictError(
+                    _(u'a Libervia page named "{}" already exists'.format(name))
+                )
+            if u"/" in name:
                 raise ValueError(_(u'"/" is not allowed in page names'))
             if not name:
                 raise ValueError(_(u"a page name can't be empty"))
             self.named_pages[name] = self
         if access is None:
             access = C.PAGES_ACCESS_PUBLIC
-        if access not in (C.PAGES_ACCESS_PUBLIC, C.PAGES_ACCESS_PROFILE, C.PAGES_ACCESS_NONE):
-            raise NotImplementedError(_(u"{} access is not implemented yet").format(access))
+        if access not in (
+            C.PAGES_ACCESS_PUBLIC,
+            C.PAGES_ACCESS_PROFILE,
+            C.PAGES_ACCESS_NONE,
+        ):
+            raise NotImplementedError(
+                _(u"{} access is not implemented yet").format(access)
+            )
         self.access = access
         self.dynamic = dynamic
         if redirect is not None:
             # only page access and name make sense in case of full redirection
             # so we check that rendering methods/values are not set
-            if not all(lambda x: x is not None
-                for x in (parse_url, prepare_render, render, template)):
-                raise ValueError(_(u"you can't use full page redirection with other rendering method,"
-                                   u"check self.pageRedirect if you need to use them"))
+            if not all(
+                lambda x: x is not None
+                for x in (parse_url, prepare_render, render, template)
+            ):
+                raise ValueError(
+                    _(
+                        u"you can't use full page redirection with other rendering method,"
+                        u"check self.pageRedirect if you need to use them"
+                    )
+                )
             self.redirect = redirect
         else:
             self.redirect = None
@@ -208,17 +233,17 @@
             log.error(_(u"parse_url must be a callable"))
 
         # if not None, next rendering will be cached
-        # it must then contain a list of the the keys to use (without the page instance)
-        # e.g. [C.SERVICE_PROFILE, "pubsub", server@example.tld, pubsub_node] 
+        #  it must then contain a list of the the keys to use (without the page instance)
+        # e.g. [C.SERVICE_PROFILE, "pubsub", server@example.tld, pubsub_node]
         self._do_cache = None
 
     def __unicode__(self):
-        return u'LiberviaPage {name} at {url}'.format(
-            name = self.name or u'<anonymous>',
-            url = self.url)
+        return u"LiberviaPage {name} at {url}".format(
+            name=self.name or u"<anonymous>", url=self.url
+        )
 
     def __str__(self):
-        return self.__unicode__().encode('utf-8')
+        return self.__unicode__().encode("utf-8")
 
     @classmethod
     def importPages(cls, host, parent=None, path=None):
@@ -246,36 +271,39 @@
                 resource = LiberviaPage(
                     host,
                     dir_path,
-                    u'/' + u'/'.join(new_path),
-                    name=page_data.get('name'),
-                    redirect=page_data.get('redirect'),
-                    access=page_data.get('access'),
-                    dynamic=page_data.get('dynamic', False),
-                    parse_url=page_data.get('parse_url'),
-                    prepare_render=page_data.get('prepare_render'),
-                    render=page_data.get('render'),
-                    template=page_data.get('template'),
-                    on_data_post=page_data.get('on_data_post'),
-                    on_data=page_data.get('on_data'),
-                    on_signal=page_data.get('on_signal'),
-                    url_cache=page_data.get('url_cache', False),
-                    )
+                    u"/" + u"/".join(new_path),
+                    name=page_data.get("name"),
+                    redirect=page_data.get("redirect"),
+                    access=page_data.get("access"),
+                    dynamic=page_data.get("dynamic", False),
+                    parse_url=page_data.get("parse_url"),
+                    prepare_render=page_data.get("prepare_render"),
+                    render=page_data.get("render"),
+                    template=page_data.get("template"),
+                    on_data_post=page_data.get("on_data_post"),
+                    on_data=page_data.get("on_data"),
+                    on_signal=page_data.get("on_signal"),
+                    url_cache=page_data.get("url_cache", False),
+                )
                 parent.putChild(d, resource)
-                log.info(u"Added /{path} page".format(path=u'[...]/'.join(new_path)))
-                if 'uri_handlers' in page_data:
+                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'))
+                        log.error(_(u"uri_handlers must be a dict"))
                     else:
-                        for uri_tuple, cb_name in page_data['uri_handlers'].iteritems():
+                        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))
+                            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))
+                                log.error(
+                                    _(u"missing {name} method to handle {1}/{2}").format(
+                                        name=cb_name, *uri_tuple
+                                    )
+                                )
                                 continue
                             else:
                                 resource.registerURI(uri_tuple, cb)
@@ -292,7 +320,9 @@
                 raise ValueError(msg)
             elif isinstance(menu, list):
                 if len(menu) != 2:
-                    msg = _(u"menu item as list must be in the form [page_name, absolue URL]")
+                    msg = _(
+                        u"menu item as list must be in the form [page_name, absolue URL]"
+                    )
                     log.error(msg)
                     raise ValueError(msg)
                 page_name, url = menu
@@ -301,7 +331,11 @@
                 try:
                     url = cls.getPageByName(page_name).url
                 except KeyError as e:
-                    log.error(_(u"Can'find a named page ({msg}), please check menu_json in configuration.").format(msg=e))
+                    log.error(
+                        _(
+                            u"Can'find a named page ({msg}), please check menu_json in configuration."
+                        ).format(msg=e)
+                    )
                     raise e
             main_menu.append((page_name, url))
         cls.main_menu = main_menu
@@ -317,7 +351,11 @@
             can't handle this URL
         """
         if uri_tuple in self.uri_callbacks:
-            log.info(_(u"{}/{} URIs are already handled, replacing by the new handler").format(*uri_tuple))
+            log.info(
+                _(u"{}/{} URIs are already handled, replacing by the new handler").format(
+                    *uri_tuple
+                )
+            )
         self.uri_callbacks[uri_tuple] = (self, get_uri_cb)
 
     def registerSignal(self, request, signal, check_profile=True):
@@ -340,7 +378,11 @@
         if not self.dynamic:
             log.error(_(u"You can't register signal if page is not dynamic"))
             return
-        LiberviaPage.signals_handlers.setdefault(signal, {})[id(request)] = (self, request, check_profile)
+        LiberviaPage.signals_handlers.setdefault(signal, {})[id(request)] = (
+            self,
+            request,
+            check_profile,
+        )
         request._signals_registered.append(signal)
 
     @classmethod
@@ -353,7 +395,7 @@
         """
         uri_data = common_uri.parseXMPPUri(uri)
         try:
-            page, cb = cls.uri_callbacks[uri_data['type'], uri_data['sub_type']]
+            page, cb = cls.uri_callbacks[uri_data["type"], uri_data["sub_type"]]
         except KeyError:
             url = None
         else:
@@ -362,7 +404,7 @@
             # no handler found
             # we try to find a more generic one
             try:
-                page, cb = cls.uri_callbacks[uri_data['type'], None]
+                page, cb = cls.uri_callbacks[uri_data["type"], None]
             except KeyError:
                 pass
             else:
@@ -379,7 +421,7 @@
         """
         return cls.named_pages[name]
 
-    def getPageRedirectURL(self, request, page_name=u'login', url=None):
+    def getPageRedirectURL(self, request, page_name=u"login", url=None):
         """generate URL for a page with redirect_url parameter set
 
         mainly used for login page with redirection to current page
@@ -389,9 +431,12 @@
             None to use request path (i.e. current page)
         @return (unicode): URL to use
         """
-        return u'{root_url}?redirect_url={redirect_url}'.format(
-            root_url = self.getPageByName(page_name).url,
-            redirect_url=urllib.quote_plus(request.uri) if url is None else url.encode('utf-8'))
+        return u"{root_url}?redirect_url={redirect_url}".format(
+            root_url=self.getPageByName(page_name).url,
+            redirect_url=urllib.quote_plus(request.uri)
+            if url is None
+            else url.encode("utf-8"),
+        )
 
     def getURL(self, *args):
         """retrieve URL of the page set arguments
@@ -402,16 +447,16 @@
         url_args = [quote(a) for a in args if a]
 
         if self.name is not None and self.name in self.pages_redirects:
-            # we check for redirection
+            #  we check for redirection
             redirect_data = self.pages_redirects[self.name]
             args_hash = tuple(args)
-            for limit in xrange(len(args)+1):
+            for limit in xrange(len(args) + 1):
                 current_hash = args_hash[:limit]
                 if current_hash in redirect_data:
                     url_base = redirect_data[current_hash]
                     remaining = args[limit:]
-                    remaining_url = '/'.join(remaining)
-                    return os.path.join('/', url_base, remaining_url)
+                    remaining_url = "/".join(remaining)
+                    return os.path.join("/", url_base, remaining_url)
 
         return os.path.join(self.url, *url_args)
 
@@ -426,19 +471,19 @@
         # the real request
 
         # we ignore empty path elements (i.e. double '/' or '/' at the end)
-        path_elts = [p for p in request.path.split('/') if p]
+        path_elts = [p for p in request.path.split("/") if p]
 
         if request.postpath:
             if not request.postpath[-1]:
-                # we remove trailing slash
+                #  we remove trailing slash
                 request.postpath = request.postpath[:-1]
             if request.postpath:
-                # getSubPageURL must return subpage from the point where
+                #  getSubPageURL must return subpage from the point where
                 # the it is called, so we have to remove remanining
                 # path elements
-                path_elts = path_elts[:-len(request.postpath)]
+                path_elts = path_elts[: -len(request.postpath)]
 
-        return u'/' + '/'.join(path_elts).decode('utf-8')
+        return u"/" + "/".join(path_elts).decode("utf-8")
 
     def getParamURL(self, request, **kwargs):
         """use URL of current request but modify the parameters in query part
@@ -448,8 +493,10 @@
         """
         current_url = self.getCurrentURL(request)
         if kwargs:
-            encoded = urllib.urlencode({k:v.encode('utf-8') for k,v in kwargs.iteritems()}).decode('utf-8')
-            current_url = current_url + u'?' + encoded
+            encoded = urllib.urlencode(
+                {k: v.encode("utf-8") for k, v in kwargs.iteritems()}
+            ).decode("utf-8")
+            current_url = current_url + u"?" + encoded
         return current_url
 
     def getSubPageByName(self, subpage_name, parent=None):
@@ -468,11 +515,11 @@
             try:
                 child_name = child.name
             except AttributeError:
-                # LiberviaPages have a name, but maybe this is an other Resource
+                #  LiberviaPages have a name, but maybe this is an other Resource
                 continue
             if child_name == subpage_name:
                 return path, child
-        raise exceptions.NotFound(_(u'requested sub page has not been found'))
+        raise exceptions.NotFound(_(u"requested sub page has not been found"))
 
     def getSubPageURL(self, request, page_name, *args):
         """retrieve a page in direct children and build its URL according to request
@@ -496,7 +543,9 @@
         """
         current_url = self.getCurrentURL(request)
         path, child = self.getSubPageByName(page_name)
-        return os.path.join(u'/', current_url, path, *[quote(a) for a in args if a is not None])
+        return os.path.join(
+            u"/", current_url, path, *[quote(a) for a in args if a is not None]
+        )
 
     def getURLByNames(self, named_path):
         """retrieve URL from pages names and arguments
@@ -515,11 +564,13 @@
                 current_page = self.getPageByName(page_name)
                 path.append(current_page.getURL(*page_args))
             else:
-                sub_path, current_page = self.getSubPageByName(page_name, parent=current_page)
+                sub_path, current_page = self.getSubPageByName(
+                    page_name, parent=current_page
+                )
                 path.append(sub_path)
                 if page_args:
                     path.extend([quote(a) for a in page_args])
-        return self.host.checkRedirection(u'/'.join(path))
+        return self.host.checkRedirection(u"/".join(path))
 
     def getURLByPath(self, *args):
         """generate URL by path
@@ -533,7 +584,7 @@
         """
         args = list(args)
         if not args:
-            raise ValueError('You must specify path elements')
+            raise ValueError("You must specify path elements")
         # root page is the one needed to construct the base of the URL
         # if first arg is not a SubPage instance, we use current page
         if not isinstance(args[0], SubPage):
@@ -556,11 +607,13 @@
             else:
                 path, current_page = current_page.getSubPageByName(args.pop(0))
                 arguments = [path]
-        return self.host.checkRedirection(u'/'.join(url_elts))
+        return self.host.checkRedirection(u"/".join(url_elts))
 
     def getChildWithDefault(self, path, request):
         # we handle children ourselves
-        raise exceptions.InternalError(u"this method should not be used with LiberviaPage")
+        raise exceptions.InternalError(
+            u"this method should not be used with LiberviaPage"
+        )
 
     def nextPath(self, request):
         """get next URL path segment, and update request accordingly
@@ -572,25 +625,25 @@
         """
         pathElement = request.postpath.pop(0)
         request.prepath.append(pathElement)
-        return urllib.unquote(pathElement).decode('utf-8')
+        return urllib.unquote(pathElement).decode("utf-8")
 
     def _filterPathValue(self, value, handler, name, request):
         """Modify a path value according to handler (see [getPathArgs])"""
-        if handler in (u'@', u'@jid') and value == u'@':
+        if handler in (u"@", u"@jid") and value == u"@":
             value = None
 
-        if handler in (u'', u'@'):
+        if handler in (u"", u"@"):
             if value is None:
-                return u''
-        elif handler in (u'jid', u'@jid'):
+                return u""
+        elif handler in (u"jid", u"@jid"):
             if value:
                 try:
                     return jid.JID(value)
                 except RuntimeError:
-                    log.warning(_(u'invalid jid argument: {value}').format(value=value))
+                    log.warning(_(u"invalid jid argument: {value}").format(value=value))
                     self.pageError(request, C.HTTP_BAD_REQUEST)
             else:
-                return u''
+                return u""
         else:
             return handler(self, value, name, request)
 
@@ -615,59 +668,63 @@
         data = self.getRData(request)
 
         for idx, name in enumerate(names):
-            if name[0] == u'*':
+            if name[0] == u"*":
                 value = data[name[1:]] = []
                 while True:
                     try:
                         value.append(self.nextPath(request))
                     except IndexError:
-                        idx-=1
+                        idx -= 1
                         break
                     else:
-                        idx+=1
+                        idx += 1
             else:
                 try:
                     value = data[name] = self.nextPath(request)
                 except IndexError:
                     data[name] = None
-                    idx-=1
+                    idx -= 1
                     break
 
-        values_count = idx+1
+        values_count = idx + 1
         if values_count < min_args:
-            log.warning(_(u"Missing arguments in URL (got {count}, expected at least {min_args})").format(
-                count = values_count, min_args = min_args))
+            log.warning(
+                _(
+                    u"Missing arguments in URL (got {count}, expected at least {min_args})"
+                ).format(count=values_count, min_args=min_args)
+            )
             self.pageError(request, C.HTTP_BAD_REQUEST)
 
         for name in names[values_count:]:
             data[name] = None
 
         for name, handler in kwargs.iteritems():
-            if name[0] == '*':
-                data[name] = [self._filterPathValue(v, handler, name, request) for v in data[name]]
+            if name[0] == "*":
+                data[name] = [
+                    self._filterPathValue(v, handler, name, request) for v in data[name]
+                ]
             else:
                 data[name] = self._filterPathValue(data[name], handler, name, request)
 
-
     ## Cache handling ##
 
     def _setCacheHeaders(self, request, cache):
         """Set ETag and Last-Modified HTTP headers, used for caching"""
-        request.setHeader('ETag', cache.hash)
+        request.setHeader("ETag", cache.hash)
         last_modified = self.host.getHTTPDate(cache.created)
-        request.setHeader('Last-Modified', last_modified)
+        request.setHeader("Last-Modified", last_modified)
 
     def _checkCacheHeaders(self, request, cache):
         """Check if a cache condition is set on the request
 
         if condition is valid, C.HTTP_NOT_MODIFIED is returned
         """
-        etag_match = request.getHeader('If-None-Match')
+        etag_match = request.getHeader("If-None-Match")
         if etag_match is not None:
             if cache.hash == etag_match:
                 self.pageError(request, C.HTTP_NOT_MODIFIED, no_body=True)
         else:
-            modified_match = request.getHeader('If-Modified-Since')
+            modified_match = request.getHeader("If-Modified-Since")
             if modified_match is not None:
                 modified = date_utils.date_parse(modified_match)
                 if modified >= int(cache.created):
@@ -698,46 +755,52 @@
 
         """
         if request.postpath:
-            # we are not on the final page, no need to go further
+            #  we are not on the final page, no need to go further
             return
 
         profile = self.getProfile(request) or C.SERVICE_PROFILE
 
         if cache_type == C.CACHE_PUBSUB:
-            service, node = kwargs['service'], kwargs['node']
+            service, node = kwargs["service"], kwargs["node"]
             if not node:
                 try:
-                    short = kwargs['short']
+                    short = kwargs["short"]
                     node = self.host.ns_map[short]
                 except KeyError:
-                    log.warning(_(u"Can't use cache for empty node without namespace set, please ensure to set \"short\" and that it is registered"))
+                    log.warning(
+                        _(
+                            u'Can\'t use cache for empty node without namespace set, please ensure to set "short" and that it is registered'
+                        )
+                    )
                     return
             if profile != C.SERVICE_PROFILE:
-                # only service profile is cache for now
+                #  only service profile is cache for now
                 return
             try:
                 cache = self.cache[profile][cache_type][service][node][request.uri][self]
             except KeyError:
                 # no cache yet, let's subscribe to the pubsub node
-                d1 = self.host.bridgeCall('psSubscribe', service.full(), node, {}, profile)
+                d1 = self.host.bridgeCall(
+                    "psSubscribe", service.full(), node, {}, profile
+                )
                 d1.addCallback(self.checkCacheSubscribeCb, service, node)
                 d1.addErrback(self.checkCacheSubscribeEb, service, node)
-                d2 = self.host.bridgeCall('psNodeWatchAdd', service.full(), node, profile)
+                d2 = self.host.bridgeCall("psNodeWatchAdd", service.full(), node, profile)
                 d2.addErrback(self.psNodeWatchAddEb, service, node)
                 self._do_cache = [self, profile, cache_type, service, node, request.uri]
-                # we don't return the Deferreds as it is not needed to wait for
+                #  we don't return the Deferreds as it is not needed to wait for
                 # the subscription to continue with page rendering
                 return
 
         else:
-            raise exceptions.InternalError(u'Unknown cache_type')
-        log.debug(u'using cache for {page}'.format(page=self))
+            raise exceptions.InternalError(u"Unknown cache_type")
+        log.debug(u"using cache for {page}".format(page=self))
         cache.last_access = time.time()
         self._setCacheHeaders(request, cache)
         self._checkCacheHeaders(request, cache)
         request.write(cache.rendered)
         request.finish()
-        raise failure.Failure(exceptions.CancelError(u'cache is used'))
+        raise failure.Failure(exceptions.CancelError(u"cache is used"))
 
     def _cacheURL(self, dummy, request, profile):
         self.cached_urls.setdefault(profile, {})[request.uri] = CacheURL(request)
@@ -748,17 +811,29 @@
         try:
             cache = cls.cache[profile][C.CACHE_PUBSUB][jid.JID(service)][node]
         except KeyError:
-            log.info(_(u'Removing subscription for {service}/{node}: '
-                       u'the page is not cached').format(service=service, node=node))
-            d1 = host.bridgeCall('psUnsubscribe', service, node, profile)
-            d1.addErrback(lambda failure_:
-                log.warning(_(u"Can't unsubscribe from {service}/{node}: {msg}").format(
-                    service=service, node=node, msg=failure_)))
-            d2 = host.bridgeCall('psNodeWatchAdd', service, node, profile)
+            log.info(
+                _(
+                    u"Removing subscription for {service}/{node}: "
+                    u"the page is not cached"
+                ).format(service=service, node=node)
+            )
+            d1 = host.bridgeCall("psUnsubscribe", service, node, profile)
+            d1.addErrback(
+                lambda failure_: log.warning(
+                    _(u"Can't unsubscribe from {service}/{node}: {msg}").format(
+                        service=service, node=node, msg=failure_
+                    )
+                )
+            )
+            d2 = host.bridgeCall("psNodeWatchAdd", service, node, profile)
             # TODO: check why the page is not in cache, remove subscription?
-            d2.addErrback(lambda failure_:
-                log.warning(_(u"Can't remove watch for {service}/{node}: {msg}").format(
-                    service=service, node=node, msg=failure_)))
+            d2.addErrback(
+                lambda failure_: log.warning(
+                    _(u"Can't remove watch for {service}/{node}: {msg}").format(
+                        service=service, node=node, msg=failure_
+                    )
+                )
+            )
         else:
             cache.clear()
 
@@ -771,7 +846,9 @@
         @param signal(unicode): name of the signal
         @param *args: args of the signals
         """
-        for page, request, check_profile in cls.signals_handlers.get(signal, {}).itervalues():
+        for page, request, check_profile in cls.signals_handlers.get(
+            signal, {}
+        ).itervalues():
             if check_profile:
                 signal_profile = args[-1]
                 request_profile = page.getProfile(request)
@@ -781,14 +858,14 @@
                     log.error(_(u"no session started, signal can't be checked"))
                     continue
                 if signal_profile != request_profile:
-                    # we ignore the signal, it's not for our profile
+                    #  we ignore the signal, it's not for our profile
                     continue
             if request._signals_cache is not None:
                 # socket is not yet opened, we cache the signal
                 request._signals_cache.append((request, signal, args))
-                log.debug(u"signal [{signal}] cached: {args}".format(
-                    signal = signal,
-                    args = args))
+                log.debug(
+                    u"signal [{signal}] cached: {args}".format(signal=signal, args=args)
+                )
             else:
                 page.on_signal(page, request, signal, *args)
 
@@ -812,8 +889,11 @@
             try:
                 del LiberviaPage.signals_handlers[signal][id(request)]
             except KeyError:
-                log.error(_(u"Can't find signal handler for [{signal}], this should not happen").format(
-                    signal = signal))
+                log.error(
+                    _(
+                        u"Can't find signal handler for [{signal}], this should not happen"
+                    ).format(signal=signal)
+                )
             else:
                 log.debug(_(u"Removed signal handler"))
 
@@ -825,7 +905,7 @@
         else:
             request.write(buf)
             request.finish()
-        raise failure.Failure(exceptions.CancelError(u'resource delegation'))
+        raise failure.Failure(exceptions.CancelError(u"resource delegation"))
 
     def HTTPRedirect(self, request, url):
         """redirect to an URL using HTTP redirection
@@ -833,11 +913,11 @@
         @param request(server.Request): current HTTP request
         @param url(unicode): url to redirect to
         """
-        web_util.redirectTo(url.encode('utf-8'), request)
+        web_util.redirectTo(url.encode("utf-8"), request)
         request.finish()
-        raise failure.Failure(exceptions.CancelError(u'HTTP redirection is used'))
+        raise failure.Failure(exceptions.CancelError(u"HTTP redirection is used"))
 
-    def redirectOrContinue(self, request, redirect_arg=u'redirect_url'):
+    def redirectOrContinue(self, request, redirect_arg=u"redirect_url"):
         """helper method to redirect a page to an url given as arg
 
         if the arg is not present, the page will continue normal workflow
@@ -847,12 +927,12 @@
         @interrupt pageError(C.HTTP_BAD_REQUEST): empty or non local URL is used
         """
         try:
-            url = request.args['redirect_url'][0]
+            url = request.args["redirect_url"][0]
         except (KeyError, IndexError):
             pass
         else:
-            # a redirection is requested
-            if not url or url[0] != u'/':
+            #  a redirection is requested
+            if not url or url[0] != u"/":
                 # we only want local urls
                 self.pageError(request, C.HTTP_BAD_REQUEST)
             else:
@@ -879,7 +959,7 @@
         @raise KeyError: there is no known page with this name
         """
         # FIXME: render non LiberviaPage resources
-        path = page_path.rstrip(u'/').split(u'/')
+        path = page_path.rstrip(u"/").split(u"/")
         if not path[0]:
             redirect_page = self.host.root
         else:
@@ -901,7 +981,7 @@
             self._do_cache = None
 
         redirect_page.renderPage(request, skip_parse_url=skip_parse_url)
-        raise failure.Failure(exceptions.CancelError(u'page redirection is used'))
+        raise failure.Failure(exceptions.CancelError(u"page redirection is used"))
 
     def pageError(self, request, code=C.HTTP_NOT_FOUND, no_body=False):
         """generate an error page and terminate the request
@@ -914,31 +994,34 @@
         if no_body:
             request.finish()
         else:
-            template = u'error/' + unicode(code) + '.html'
+            template = u"error/" + unicode(code) + ".html"
 
             rendered = self.host.renderer.render(
                 template,
-                root_path = '/templates/',
-                error_code = code,
-                **request.template_data)
+                root_path="/templates/",
+                error_code=code,
+                **request.template_data
+            )
 
             self.writeData(rendered, request)
-        raise failure.Failure(exceptions.CancelError(u'error page is used'))
+        raise failure.Failure(exceptions.CancelError(u"error page is used"))
 
     def writeData(self, data, request):
         """write data to transport and finish the request"""
         if data is None:
             self.pageError(request)
-        data_encoded = data.encode('utf-8')
+        data_encoded = data.encode("utf-8")
 
         if self._do_cache is not None:
             redirected_page = self._do_cache.pop(0)
             cache = reduce(lambda d, k: d.setdefault(k, {}), self._do_cache, self.cache)
             page_cache = cache[redirected_page] = CachePage(data_encoded)
             self._setCacheHeaders(request, page_cache)
-            log.debug(_(u'{page} put in cache for [{profile}]').format(
-                page=self,
-                profile=self._do_cache[0]))
+            log.debug(
+                _(u"{page} put in cache for [{profile}]").format(
+                    page=self, profile=self._do_cache[0]
+                )
+            )
             self._do_cache = None
             self._checkCacheHeaders(request, page_cache)
 
@@ -961,7 +1044,7 @@
                 self.pageError(request)
             else:
                 child.render(request)
-                raise failure.Failure(exceptions.CancelError(u'subpage page is used'))
+                raise failure.Failure(exceptions.CancelError(u"subpage page is used"))
 
     def _prepare_dynamic(self, dummy, request):
         # we need to activate dynamic page
@@ -969,7 +1052,9 @@
         socket_token = unicode(uuid.uuid4())
         socket_url = self.host.getWebsocketURL(request)
         socket_debug = C.boolConst(self.host.debug)
-        request.template_data['websocket'] = WebsocketMeta(socket_url, socket_token, socket_debug)
+        request.template_data["websocket"] = WebsocketMeta(
+            socket_url, socket_token, socket_debug
+        )
         self.host.registerWSToken(socket_token, self, request)
         # we will keep track of handlers to remove
         request._signals_registered = []
@@ -988,15 +1073,16 @@
         # if confirm variable is set in case of successfuly data post
         session_data = self.host.getSessionData(request, session_iface.ISATSession)
         if session_data.popPageFlag(self, C.FLAG_CONFIRM):
-            template_data[u'confirm'] = True
+            template_data[u"confirm"] = True
 
         return self.host.renderer.render(
             self.template,
-            root_path = '/templates/',
-            media_path = '/' + C.MEDIA_DIR,
-            cache_path = session_data.cache_dir,
-            main_menu = LiberviaPage.main_menu,
-            **template_data)
+            root_path="/templates/",
+            media_path="/" + C.MEDIA_DIR,
+            cache_path=session_data.cache_dir,
+            main_menu=LiberviaPage.main_menu,
+            **template_data
+        )
 
     def _renderEb(self, failure_, request):
         """don't raise error on CancelError"""
@@ -1004,9 +1090,11 @@
 
     def _internalError(self, failure_, request):
         """called if an error is not catched"""
-        log.error(_(u"Uncatched error for HTTP request on {url}: {msg}").format(
-            url = request.URLPath(),
-            msg = failure_))
+        log.error(
+            _(u"Uncatched error for HTTP request on {url}: {msg}").format(
+                url=request.URLPath(), msg=failure_
+            )
+        )
         self.pageError(request, C.HTTP_INTERNAL_ERROR)
 
     def _on_data_post_redirect(self, ret, request):
@@ -1026,11 +1114,13 @@
             ret = (ret,)
         else:
             ret = tuple(ret)
-            raise NotImplementedError(_(u'iterable in on_data_post return value is not used yet'))
+            raise NotImplementedError(
+                _(u"iterable in on_data_post return value is not used yet")
+            )
         session_data = self.host.getSessionData(request, session_iface.ISATSession)
         request_data = self.getRData(request)
-        if 'post_redirect_page' in request_data:
-            redirect_page_data = request_data['post_redirect_page']
+        if "post_redirect_page" in request_data:
+            redirect_page_data = request_data["post_redirect_page"]
             if isinstance(redirect_page_data, tuple):
                 redirect_page = redirect_page_data[0]
                 redirect_page_args = redirect_page_data[1:]
@@ -1047,18 +1137,22 @@
         request.setResponseCode(C.HTTP_SEE_OTHER)
         request.setHeader("location", redirect_uri)
         request.finish()
-        raise failure.Failure(exceptions.CancelError(u'Post/Redirect/Get is used'))
+        raise failure.Failure(exceptions.CancelError(u"Post/Redirect/Get is used"))
 
     def _on_data_post(self, dummy, request):
-        csrf_token = self.host.getSessionData(request, session_iface.ISATSession).csrf_token
+        csrf_token = self.host.getSessionData(
+            request, session_iface.ISATSession
+        ).csrf_token
         try:
-            given_csrf = self.getPostedData(request, u'csrf_token')
+            given_csrf = self.getPostedData(request, u"csrf_token")
         except KeyError:
             given_csrf = None
         if given_csrf is None or given_csrf != csrf_token:
-            log.warning(_(u"invalid CSRF token, hack attempt? URL: {url}, IP: {ip}").format(
-                url=request.uri,
-                ip=request.getClientIP()))
+            log.warning(
+                _(u"invalid CSRF token, hack attempt? URL: {url}, IP: {ip}").format(
+                    url=request.uri, ip=request.getClientIP()
+                )
+            )
             self.pageError(request, C.HTTP_UNAUTHORIZED)
         d = defer.maybeDeferred(self.on_data_post, self, request)
         d.addCallback(self._on_data_post_redirect, request)
@@ -1076,7 +1170,7 @@
         @return (iterator[unicode], list[iterator[unicode], unicode, list[unicode]): values received for this(these) key(s)
         @raise KeyError: one specific key has been requested, and it is missing
         """
-        # FIXME: request.args is already unquoting the value, it seems we are doing double unquote
+        #  FIXME: request.args is already unquoting the value, it seems we are doing double unquote
         if isinstance(keys, basestring):
             keys = [keys]
             get_first = True
@@ -1085,7 +1179,7 @@
 
         ret = []
         for key in keys:
-            gen = (urllib.unquote(v).decode('utf-8') for v in request.args.get(key,[]))
+            gen = (urllib.unquote(v).decode("utf-8") for v in request.args.get(key, []))
             if multiple:
                 ret.append(gen)
             else:
@@ -1105,16 +1199,16 @@
         @param multiple(bool): if False, only the first values are returned
         @return (dict[unicode, list[unicode]]): post values
         """
-        except_ = tuple(except_) + (u'csrf_token',)
+        except_ = tuple(except_) + (u"csrf_token",)
         ret = {}
         for key, values in request.args.iteritems():
-            key = urllib.unquote(key).decode('utf-8')
+            key = urllib.unquote(key).decode("utf-8")
             if key in except_:
                 continue
             if not multiple:
-                ret[key] = urllib.unquote(values[0]).decode('utf-8')
+                ret[key] = urllib.unquote(values[0]).decode("utf-8")
             else:
-                ret[key] = [urllib.unquote(v).decode('utf-8') for v in values]
+                ret[key] = [urllib.unquote(v).decode("utf-8") for v in values]
         return ret
 
     def getProfile(self, request):
@@ -1170,18 +1264,23 @@
         @param template_data(dict): template_data to use
         """
         if not self.dynamic:
-            raise exceptions.InternalError(_(u"renderPartial must only be used with dynamic pages"))
+            raise exceptions.InternalError(
+                _(u"renderPartial must only be used with dynamic pages")
+            )
         session_data = self.host.getSessionData(request, session_iface.ISATSession)
 
         return self.host.renderer.render(
             template,
-            root_path = '/templates/',
-            media_path = '/' + C.MEDIA_DIR,
-            cache_path = session_data.cache_dir,
-            main_menu = LiberviaPage.main_menu,
-            **template_data)
+            root_path="/templates/",
+            media_path="/" + C.MEDIA_DIR,
+            cache_path=session_data.cache_dir,
+            main_menu=LiberviaPage.main_menu,
+            **template_data
+        )
 
-    def renderAndUpdate(self, request, template, selectors, template_data_update, update_type="append"):
+    def renderAndUpdate(
+        self, request, template, selectors, template_data_update, update_type="append"
+    ):
         """Helper method to render a partial page element and update the page
 
         this is NOT the normal page rendering method, it is used only to update
@@ -1198,20 +1297,19 @@
         template_data = request.template_data.copy()
         template_data.update(template_data_update)
         html = self.renderPartial(request, template, template_data)
-        request.sendData(u'dom',
-                        selectors=selectors,
-                        update_type=update_type,
-                        html=html)
+        request.sendData(u"dom", selectors=selectors, update_type=update_type, html=html)
 
     def renderPage(self, request, skip_parse_url=False):
         """Main method to handle the workflow of a LiberviaPage"""
 
         # template_data are the variables passed to template
-        if not hasattr(request, 'template_data'):
+        if not hasattr(request, "template_data"):
             session_data = self.host.getSessionData(request, session_iface.ISATSession)
             csrf_token = session_data.csrf_token
-            request.template_data = {u'profile': session_data.profile,
-                                     u'csrf_token': csrf_token}
+            request.template_data = {
+                u"profile": session_data.profile,
+                u"csrf_token": csrf_token,
+            }
 
             # XXX: here is the code which need to be executed once
             #      at the beginning of the request hanling
@@ -1223,7 +1321,11 @@
         d.addCallback(self._checkAccess, request)
 
         if self.redirect is not None:
-            d.addCallback(lambda dummy: self.pageRedirect(self.redirect, request, skip_parse_url=False))
+            d.addCallback(
+                lambda dummy: self.pageRedirect(
+                    self.redirect, request, skip_parse_url=False
+                )
+            )
 
         if self.parse_url is not None and not skip_parse_url:
             if self.url_cache:
@@ -1232,7 +1334,7 @@
                     cache_url = self.cached_urls[profile][request.uri]
                 except KeyError:
                     # no cache for this URI yet
-                    # we do normal URL parsing, and then the cache
+                    #  we do normal URL parsing, and then the cache
                     d.addCallback(self.parse_url, request)
                     d.addCallback(self._cacheURL, request, profile)
                 else: