Esempio n. 1
0
 def apply_rules(self, req, resp, resource_fetcher, log):
     """
     Apply the whatever the appropriate rules are to the request/response.
     """
     extra_headers = parse_meta_headers(resp.body)
     if extra_headers:
         response_headers = HeaderDict(resp.headerlist + extra_headers)
     else:
         response_headers = resp.headers
     try:
         classes = run_matches(self.matchers, req, resp, response_headers, log)
     except AbortTheme:
         return resp
     if 'X-Deliverance-Page-Class' in response_headers:
         classes.extend(response_headers['X-Deliverance-Page-Class'].strip().split())
     if 'deliverance.page_classes' in req.environ:
         classes.extend(req.environ['deliverance.page_classes'])
     if not classes:
         classes = ['default']
     rules = []
     theme = None
     for class_name in classes:
         ## FIXME: handle case of unknown classes
         ## Or do that during compilation?
         for rule in self.rules_by_class.get(class_name, []):
             if rule not in rules:
                 rules.append(rule)
                 if rule.theme:
                     theme = rule.theme
     if theme is None:
         theme = self.default_theme
         ## FIXME: error if not theme still
     if theme is None:
         log.error(self, "No theme has been defined for the request")
         return resp
     try:
         theme_href = theme.resolve_href(req, resp, log)
         theme_doc = self.get_theme(theme_href, resource_fetcher, log)
         content_doc = self.parse_document(resp.body, req.url)
         run_standard = True
         for rule in rules:
             if rule.match is not None:
                 matches = rule.match(req, resp, response_headers, log)
                 if not matches:
                     log.debug(rule, "Skipping <rule>")
                     continue
             rule.apply(content_doc, theme_doc, resource_fetcher, log)
             if rule.suppress_standard:
                 run_standard = False
         if run_standard:
             ## FIXME: should it be possible to put the standard rule in the ruleset?
             standard_rule.apply(content_doc, theme_doc, resource_fetcher, log)
     except AbortTheme:
         return resp
     remove_content_attribs(theme_doc)
     ## FIXME: handle caching?
     resp.body = tostring(theme_doc.getroottree())
     return resp
Esempio n. 2
0
 def clientside_actions(self, req, resp, log):
     extra_headers = parse_meta_headers(resp.body)
     if extra_headers:
         response_headers = ResponseHeaders(resp.headerlist + extra_headers)
     else:
         response_headers = resp.headers
     try:
         classes = run_matches(self.matchers, req, resp, response_headers,
                               log)
     except AbortTheme:
         assert 0, 'no abort should happen'
     if 'X-Deliverance-Page-Class' in response_headers:
         classes.extend(
             resp.headers['X-Deliverance-Page-Class'].strip().split())
     if 'deliverance.page_classes' in req.environ:
         classes.extend(req.environ['deliverance.page_classes'])
     if not classes:
         classes = ['default']
     rules = []
     for class_name in classes:
         ## FIXME: handle case of unknown classes
         ## Or do that during compilation?
         for rule in self.rules_by_class.get(class_name, []):
             if rule not in rules:
                 rules.append(rule)
                 if rule.theme:
                     assert 0, 'no rule themes should be present'
     resp = force_charset(resp)
     content_doc = self.parse_document(resp.unicode_body, req.url)
     actions = []
     run_standard = True
     for rule in rules:
         if rule.match is not None:
             matches = rule.match(req, resp, response_headers, log)
             if not matches:
                 log.debug(rule, "Skipping <rule>")
                 continue
         actions.extend(rule.clientside_actions(content_doc, log))
         if rule.suppress_standard:
             run_standard = False
     if run_standard:
         ## FIXME: should it be possible to put the standard rule in the ruleset?
         actions.extend(standard_rule.clientside_actions(content_doc, log))
     return actions
Esempio n. 3
0
 def clientside_actions(self, req, resp, log):
     extra_headers = parse_meta_headers(resp.body)
     if extra_headers:
         response_headers = HeaderDict(resp.headerlist + extra_headers)
     else:
         response_headers = resp.headers
     try:
         classes = run_matches(self.matchers, req, resp, response_headers, log)
     except AbortTheme:
         assert 0, 'no abort should happen'
     if 'X-Deliverance-Page-Class' in response_headers:
         classes.extend(resp.headers['X-Deliverance-Page-Class'].strip().split())
     if 'deliverance.page_classes' in req.environ:
         classes.extend(req.environ['deliverance.page_classes'])
     if not classes:
         classes = ['default']
     rules = []
     for class_name in classes:
         ## FIXME: handle case of unknown classes
         ## Or do that during compilation?
         for rule in self.rules_by_class.get(class_name, []):
             if rule not in rules:
                 rules.append(rule)
                 if rule.theme:
                     assert 0, 'no rule themes should be present'
     resp = force_charset(resp)
     content_doc = self.parse_document(resp.unicode_body, req.url)
     actions = []
     run_standard = True
     for rule in rules:
         if rule.match is not None:
             matches = rule.match(req, resp, response_headers, log)
             if not matches:
                 log.debug(rule, "Skipping <rule>")
                 continue
         actions.extend(rule.clientside_actions(content_doc, log))
         if rule.suppress_standard:
             run_standard = False
     if run_standard:
         ## FIXME: should it be possible to put the standard rule in the ruleset?
         actions.extend(standard_rule.clientside_actions(content_doc, log))
     return actions
Esempio n. 4
0
    def apply_rules(self, req, resp, resource_fetcher, log, default_theme=None):
        """
        Apply the whatever the appropriate rules are to the request/response.
        """
        extra_headers = parse_meta_headers(resp.body)
        if extra_headers:
            response_headers = HeaderDict(resp.headerlist + extra_headers)
        else:
            response_headers = resp.headers
        try:
            classes = run_matches(self.matchers, req, resp, response_headers, log)
        except AbortTheme:
            return resp
        if 'X-Deliverance-Page-Class' in response_headers:
            log.debug(self, "Found page class %s in headers", response_headers['X-Deliverance-Page-Class'].strip())
            classes.extend(response_headers['X-Deliverance-Page-Class'].strip().split())
        if 'deliverance.page_classes' in req.environ:
            log.debug(self, "Found page class in WSGI environ: %s", ' '.join(req.environ["deliverance.page_classes"]))
            classes.extend(req.environ['deliverance.page_classes'])
        if not classes:
            classes = ['default']
        rules = []
        theme = None
        for class_name in classes:
            ## FIXME: handle case of unknown classes
            ## Or do that during compilation?
            for rule in self.rules_by_class.get(class_name, []):
                if rule not in rules:
                    rules.append(rule)
                    if rule.theme:
                        theme = rule.theme
        if theme is None:
            theme = self.default_theme

        if theme is None and default_theme is not None:
            theme = Theme(href=default_theme, 
                          source_location=self.source_location)
            
        if theme is None:
            log.error(self, "No theme has been defined for the request")
            return resp

        try:
            theme_href = theme.resolve_href(req, resp, log)
            original_theme_resp = self.get_theme_response(
                theme_href, resource_fetcher, log)
            theme_doc = self.get_theme_doc(
                original_theme_resp, theme_href,
                should_escape_cdata=True,
                should_fix_meta_charset_position=True)

            resp = force_charset(resp)
            body = resp.unicode_body
            body = escape_cdata(body)
            body = fix_meta_charset_position(body)
            content_doc = self.parse_document(body, req.url)

            run_standard = True
            for rule in rules:
                if rule.match is not None:
                    matches = rule.match(req, resp, response_headers, log)
                    if not matches:
                        log.debug(rule, "Skipping <rule>")
                        continue
                rule.apply(content_doc, theme_doc, resource_fetcher, log)
                if rule.suppress_standard:
                    run_standard = False
            if run_standard:
                ## FIXME: should it be possible to put the standard rule in the ruleset?
                standard_rule.apply(content_doc, theme_doc, resource_fetcher, log)
        except AbortTheme:
            return resp
        remove_content_attribs(theme_doc)
        ## FIXME: handle caching?

        if original_theme_resp.body.strip().startswith("<!DOCTYPE"):
            tree = theme_doc.getroottree()
        else:
            tree = content_doc.getroottree()

        if "XHTML" in tree.docinfo.doctype:
            method = "xml"
        else:
            method = "html"

        theme_str = tostring(theme_doc, include_meta_content_type=True)
        theme_str = tree.docinfo.doctype + theme_str
        theme_doc = document_fromstring(theme_str)
        tree = theme_doc.getroottree()

        resp.body = tostring(tree, method=method, include_meta_content_type=True)
        resp.body = unescape_cdata(resp.body)

        return resp
Esempio n. 5
0
    def apply_rules(self, req, resp, resource_fetcher, log, default_theme=None):
        """
        Apply the whatever the appropriate rules are to the request/response.
        """
        extra_headers = parse_meta_headers(resp.body)
        if extra_headers:
            response_headers = ResponseHeaders(resp.headerlist + extra_headers)
        else:
            response_headers = resp.headers
        try:
            classes = run_matches(self.matchers, req, resp, response_headers, log)
        except AbortTheme:
            return resp
        if 'X-Deliverance-Page-Class' in response_headers:
            log.debug(self, "Found page class %s in headers", response_headers['X-Deliverance-Page-Class'].strip())
            classes.extend(response_headers['X-Deliverance-Page-Class'].strip().split())
        if 'deliverance.page_classes' in req.environ:
            log.debug(self, "Found page class in WSGI environ: %s", ' '.join(req.environ["deliverance.page_classes"]))
            classes.extend(req.environ['deliverance.page_classes'])
        if not classes:
            classes = ['default']
        rules = []
        theme = None
        for class_name in classes:
            ## FIXME: handle case of unknown classes
            ## Or do that during compilation?
            for rule in self.rules_by_class.get(class_name, []):
                if rule not in rules:
                    rules.append(rule)
                    if rule.theme:
                        theme = rule.theme
        if theme is None:
            theme = self.default_theme

        if theme is None and default_theme is not None:
            theme = Theme(href=default_theme, 
                          source_location=self.source_location)
            
        if theme is None:
            log.error(self, "No theme has been defined for the request")
            return resp

        try:
            theme_href = theme.resolve_href(req, resp, log)
            original_theme_resp = self.get_theme_response(
                theme_href, resource_fetcher, log)
            theme_doc = self.get_theme_doc(
                original_theme_resp, theme_href,
                should_escape_cdata=True,
                should_fix_meta_charset_position=True)

            resp = force_charset(resp)
            body = resp.unicode_body
            body = escape_cdata(body)
            body = fix_meta_charset_position(body)
            content_doc = self.parse_document(body, req.url)

            run_standard = True
            for rule in rules:
                if rule.match is not None:
                    matches = rule.match(req, resp, response_headers, log)
                    if not matches:
                        log.debug(rule, "Skipping <rule>")
                        continue
                rule.apply(content_doc, theme_doc, resource_fetcher, log)
                if rule.suppress_standard:
                    run_standard = False
            if run_standard:
                ## FIXME: should it be possible to put the standard rule in the ruleset?
                standard_rule.apply(content_doc, theme_doc, resource_fetcher, log)
        except AbortTheme:
            return resp
        remove_content_attribs(theme_doc)
        ## FIXME: handle caching?

        if original_theme_resp.body.strip().startswith("<!DOCTYPE"):
            tree = theme_doc.getroottree()
        else:
            tree = content_doc.getroottree()

        if "XHTML" in tree.docinfo.doctype:
            method = "xml"
        else:
            method = "html"

        theme_str = tostring(theme_doc, include_meta_content_type=True)
        theme_str = tree.docinfo.doctype + theme_str
        theme_doc = document_fromstring(theme_str)
        tree = theme_doc.getroottree()

        resp.body = tostring(tree, method=method, include_meta_content_type=True)
        resp.body = unescape_cdata(resp.body)

        return resp