Ejemplo n.º 1
0
    def transformIterable(self, result, encoding):
        """Apply the transform if required
        """

        result = self.parseTree(result)
        if result is None:
            return None

        DevelopmentMode = Globals.DevelopmentMode
        runtrace = (DevelopmentMode and self.request.get(
            'diazo.debug', '').lower() in ('1', 'y', 'yes', 't', 'true'))

        try:
            etree.clear_error_log()

            settings = self.getSettings()
            if settings.doctype:
                result.doctype = settings.doctype
                if not result.doctype.endswith('\n'):
                    result.doctype += '\n'

            transform = self.setupTransform(runtrace=runtrace)
            if transform is None:
                return None

            cache = None
            if not DevelopmentMode:
                cache = getCache(settings)

            parameterExpressions = settings.parameterExpressions or {}
            params = prepareThemeParameters(findContext(self.request),
                                            self.request, parameterExpressions,
                                            cache)

            transformed = transform(result.tree, **params)
            error_log = transform.error_log
            if transformed is not None:
                # Transformed worked, swap content with result
                result.tree = transformed
        except etree.LxmlError as e:
            if not (DevelopmentMode):
                raise
            error_log = e.error_log
            runtrace = True

        if runtrace:
            from diazo.runtrace import generate_debug_html
            # Add debug information to end of body
            body = result.tree.xpath('/html/body')[0]
            body.insert(
                -1,
                generate_debug_html(
                    findContext(self.request).portal_url() +
                    '/++resource++diazo-debug',
                    rules=settings.rules,
                    rules_parser=getParser('rules', settings.readNetwork),
                    error_log=error_log,
                ))

        return result
Ejemplo n.º 2
0
    def transformIterableWithSettings(self, result, encoding, settings):
        """ """
        result = self.parseTree(result)
        if result is None:
            return None

        if settings.doctype:
            result.doctype = settings.doctype
            if not result.doctype.endswith('\n'):
                result.doctype += '\n'

        transform = compileThemeTransform(settings.rules,
                                          settings.absolutePrefix,
                                          settings.readNetwork,
                                          settings.parameterExpressions)
        if transform is None:
            return None

        cache = _Cache()
        parameterExpressions = settings.parameterExpressions or {}
        params = prepareThemeParameters(findContext(self.request),
                                        self.request,
                                        parameterExpressions,
                                        cache)

        transformed = transform(result.tree, **params)
        error_log = transform.error_log
        if transformed is not None:
            # Transformed worked, swap content with result
            result.tree = transformed

        return result
Ejemplo n.º 3
0
    def transformIterable(self, result, encoding):
        """Apply the transform if required
        """

        result = self.parseTree(result)
        if result is None:
            return None

        transform = self.setupTransform()
        if transform is None:
            return None

        settings = self.getSettings()
        if settings.doctype:
            result.doctype = settings.doctype
            if not result.doctype.endswith('\n'):
                result.doctype += '\n'

        cache = None
        DevelopmentMode = Globals.DevelopmentMode
        if not DevelopmentMode:
            cache = getCache(settings)

        parameterExpressions = settings.parameterExpressions or {}
        params = prepareThemeParameters(findContext(self.request),
                                        self.request, parameterExpressions,
                                        cache)

        transformed = transform(result.tree, **params)
        if transformed is None:
            return None

        result.tree = transformed

        return result
Ejemplo n.º 4
0
    def transformIterableWithSettings(self, result, encoding, settings):
        """ """
        result = self.parseTree(result)
        if result is None:
            return None

        if settings.doctype:
            result.doctype = settings.doctype
            if not result.doctype.endswith('\n'):
                result.doctype += '\n'

        transform = compileThemeTransform(settings.rules,
                                          settings.absolutePrefix,
                                          settings.readNetwork,
                                          settings.parameterExpressions)
        if transform is None:
            return None

        cache = _Cache()
        parameterExpressions = settings.parameterExpressions or {}
        params = prepareThemeParameters(findContext(self.request),
                                        self.request,
                                        parameterExpressions,
                                        cache)

        transformed = transform(result.tree, **params)
        if transformed is not None:
            # Transformed worked, swap content with result
            result.tree = transformed

        return result
Ejemplo n.º 5
0
    def transformIterable(self, result, encoding):
        """Apply the transform if required
        """

        result = self.parseTree(result)
        if result is None:
            return None

        transform = self.setupTransform()
        if transform is None:
            return None
        
        settings = self.getSettings()
        if settings.doctype:
            result.doctype = settings.doctype
            if not result.doctype.endswith('\n'):
                result.doctype += '\n'
        
        cache = None
        DevelopmentMode = Globals.DevelopmentMode
        if not DevelopmentMode:
            cache = getCache(settings)

        parameterExpressions = settings.parameterExpressions or {}
        params = prepareThemeParameters(findContext(self.request), self.request, parameterExpressions, cache) 

        transformed = transform(result.tree, **params)
        if transformed is None:
            return None

        result.tree = transformed

        return result
Ejemplo n.º 6
0
    def transformIterable(self, result, encoding):
        """Apply the transform if required
        """

        result = self.parseTree(result)
        if result is None:
            return None

        DevelopmentMode = Globals.DevelopmentMode
        runtrace = (DevelopmentMode and
            self.request.get('diazo.debug', '').lower() in ('1', 'y', 'yes', 't', 'true'))

        try:
            etree.clear_error_log()

            settings = self.getSettings()
            if settings.doctype:
                result.doctype = settings.doctype
                if not result.doctype.endswith('\n'):
                    result.doctype += '\n'

            transform = self.setupTransform(runtrace=runtrace)
            if transform is None:
                return None

            cache = None
            if not DevelopmentMode:
                cache = getCache(settings)

            parameterExpressions = settings.parameterExpressions or {}
            params = prepareThemeParameters(findContext(self.request), self.request, parameterExpressions, cache)

            transformed = transform(result.tree, **params)
            error_log = transform.error_log
            if transformed is not None:
                # Transformed worked, swap content with result
                result.tree = transformed
        except etree.LxmlError as e:
            if not(DevelopmentMode):
                raise
            error_log = e.error_log
            runtrace = True

        if runtrace:
            from diazo.runtrace import generate_debug_html
            # Add debug information to end of body
            body = result.tree.xpath('/html/body')[0]
            body.insert(-1, generate_debug_html(
                findContext(self.request).portal_url() + '/++resource++diazo-debug',
                rules=settings.rules,
                rules_parser=getParser('rules', settings.readNetwork),
                error_log = error_log,
            ))

        return result
Ejemplo n.º 7
0
    def getFrame(self):
        """AJAX method to load a frame's contents

        Expects two query string parameters: ``path`` - the path to fetch - and
        ``theme``, which can be 'off', to disable the theme and 'apply' to
        apply the current theme to the response.

        Additionally:

        - a query string parameter ``links`` can be set to one of ``disable``
          or ``replace``. The former will disable hyperlinks; the latter will
          replace them with links using the ``@@themeing-controlpanel-getframe``
          view.
        - a query string parameter ``forms`` can be set to one of ``disable``
          or ``replace``. The former will disable forms ; the latter will
          replace them with links using the ``@@themeing-controlpanel-getframe``
          view.
        - a query string parameter ``title`` can be set to give a new page
          title
        """

        processInputs(self.request)

        path = self.request.form.get('path', None)
        theme = self.request.form.get('theme', 'off')
        links = self.request.form.get('links', None)
        forms = self.request.form.get('forms', None)
        title = self.request.form.get('title', None)

        if not path:
            return "<html><head></head><body></body></html>"

        portal = getPortal()
        portal_url = portal.absolute_url()
        response = subrequest(path, root=portal)

        result = response.getBody()
        content_type = response.headers.get('content-type')
        encoding = None
        if content_type is not None and ';' in content_type:
            content_type, encoding = content_type.split(';', 1)
        if encoding is None:
            encoding = 'utf-8'
        else:
            # e.g. charset=utf-8
            encoding = encoding.split('=', 1)[1].strip()

        # Not HTML? Return as-is
        if content_type is None or not content_type.startswith('text/html'):
            if len(result) == 0:
                result = ' '  # Zope does not deal well with empty responses
            return result

        result = result.decode(encoding).encode('ascii', 'xmlcharrefreplace')
        if len(result) == 0:
            result = ' '  # Zope does not deal well with empty responses

        if theme == 'off':
            self.request.response.setHeader('X-Theme-Disabled', '1')
        elif theme == 'apply':
            self.request.response.setHeader('X-Theme-Disabled', '1')
            themeInfo = getThemeFromResourceDirectory(self.context)

            registry = getUtility(IRegistry)
            settings = registry.forInterface(IThemeSettings, False)

            context = self.context
            try:
                context = findContext(portal.restrictedTraverse(path))
            except (KeyError, NotFound,):
                pass

            serializer = getHTMLSerializer([result], pretty_print=False)

            try:
                transform = compileThemeTransform(themeInfo.rules, themeInfo.absolutePrefix, settings.readNetwork, themeInfo.parameterExpressions or {})
            except lxml.etree.XMLSyntaxError, e:
                return self.theme_error_template(error=e.msg)

            params = prepareThemeParameters(context, self.request, themeInfo.parameterExpressions or {})

            # Fix url and path since the request gave us this view
            params['url'] = quote_param("%s%s" % (portal_url, path,))
            params['path'] = quote_param("%s%s" % (portal.absolute_url_path(), path,))

            if themeInfo.doctype:
                serializer.doctype = themeInfo.doctype
                if not serializer.doctype.endswith('\n'):
                    serializer.doctype += '\n'

            serializer.tree = transform(serializer.tree, **params)
            result = ''.join(serializer)
Ejemplo n.º 8
0
    def transformIterable(self, result, encoding):
        """Apply the transform if required
        """
        # Obtain settings. Do nothing if not found
        policy = theming_policy(self.request)
        settings = policy.getSettings()
        if settings is None:
            return None
        if not policy.isThemeEnabled():
            return None
        result = self.parseTree(result)
        if result is None:
            return None

        debug_mode = getConfiguration().debug_mode
        runtrace = self.debug_theme()

        try:
            etree.clear_error_log()

            if settings.doctype:
                result.doctype = settings.doctype
                if not result.doctype.endswith('\n'):
                    result.doctype += '\n'

            transform = self.setupTransform(runtrace=runtrace)
            if transform is None:
                return None

            cache = None
            if not debug_mode:
                cache = policy.getCache()

            parameterExpressions = settings.parameterExpressions or {}
            params = prepareThemeParameters(findContext(self.request),
                                            self.request, parameterExpressions,
                                            cache)

            transformed = transform(result.tree, **params)
            error_log = transform.error_log
            if transformed is not None:
                # Transformed worked, swap content with result
                result.tree = transformed
        except etree.LxmlError as e:
            if not (debug_mode):
                raise
            error_log = e.error_log
            runtrace = True

        if runtrace:
            from diazo.runtrace import generate_debug_html
            # Add debug information to end of body
            body = result.tree.xpath('/html/body')[0]
            debug_url = findContext(
                self.request).portal_url() + '/++resource++diazo-debug'
            body.insert(
                -1,
                generate_debug_html(
                    debug_url,
                    rules=settings.rules,
                    rules_parser=getParser('rules', settings.readNetwork),
                    error_log=error_log,
                ))
        return result
Ejemplo n.º 9
0
    def getFrame(self):
        """AJAX method to load a frame's contents

        Expects two query string parameters: ``path`` - the path to fetch - and
        ``theme``, which can be 'off', to disable the theme and 'apply' to
        apply the current theme to the response.

        Additionally:

        - a query string parameter ``links`` can be set to one of ``disable``
          or ``replace``. The former will disable hyperlinks; the latter will
          replace them with links using the
          ``@@themeing-controlpanel-getframe`` view.
        - a query string parameter ``forms`` can be set to one of ``disable``
          or ``replace``. The former will disable forms ; the latter will
          replace them with links using the
          ``@@themeing-controlpanel-getframe`` view.
        - a query string parameter ``title`` can be set to give a new page
          title
        """

        processInputs(self.request)

        path = self.request.form.get('path', None)
        theme = self.request.form.get('theme', 'off')
        links = self.request.form.get('links', None)
        forms = self.request.form.get('forms', None)
        title = self.request.form.get('title', None)

        if not path:
            return "<html><head></head><body></body></html>"

        portal = getPortal()
        portal_url = portal.absolute_url()
        response = subrequest(path, root=portal)

        result = response.getBody()
        content_type = response.headers.get('content-type')
        encoding = None
        if content_type is not None and ';' in content_type:
            content_type, encoding = content_type.split(';', 1)
        if encoding is None:
            encoding = 'utf-8'
        else:
            # e.g. charset=utf-8
            encoding = encoding.split('=', 1)[1].strip()

        # Not HTML? Return as-is
        if content_type is None or not content_type.startswith('text/html'):
            if len(result) == 0:
                result = ' '  # Zope does not deal well with empty responses
            return result

        result = result.decode(encoding).encode('ascii', 'xmlcharrefreplace')
        if len(result) == 0:
            result = ' '  # Zope does not deal well with empty responses

        if theme == 'off':
            self.request.response.setHeader('X-Theme-Disabled', '1')
        elif theme == 'apply':
            self.request.response.setHeader('X-Theme-Disabled', '1')
            themeInfo = getThemeFromResourceDirectory(self.context)

            policy = theming_policy(self.request)
            settings = policy.getSettings()

            context = self.context
            try:
                context = findContext(portal.restrictedTraverse(path))
            except (KeyError, NotFound,):
                pass

            serializer = getHTMLSerializer([result], pretty_print=False)

            try:
                transform = compileThemeTransform(
                    themeInfo.rules, themeInfo.absolutePrefix,
                    settings.readNetwork, themeInfo.parameterExpressions or {})
            except lxml.etree.XMLSyntaxError as e:
                return self.theme_error_template(error=e.msg)

            params = prepareThemeParameters(
                context, self.request, themeInfo.parameterExpressions or {})

            # Fix url and path since the request gave us this view
            params['url'] = quote_param(''.join((portal_url, path,)))
            params['path'] = quote_param(
                ''.join((portal.absolute_url_path(), path,))
            )

            if themeInfo.doctype:
                serializer.doctype = themeInfo.doctype
                if not serializer.doctype.endswith('\n'):
                    serializer.doctype += '\n'

            serializer.tree = transform(serializer.tree, **params)
            result = ''.join(serializer)

        if title or links or forms:
            tree = lxml.html.fromstring(result)

            def encodeUrl(orig):
                origUrl = urllib.parse.urlparse(orig)
                newPath = origUrl.path
                newQuery = urllib.parse.parse_qs(origUrl.query)

                # relative?
                if not origUrl.netloc:
                    newPath = urllib.parse.urljoin(
                        path.rstrip("/") + "/", newPath.lstrip("/"))
                elif not orig.lower().startswith(portal_url.lower()):
                    # Not an internal URL - ignore
                    return orig

                newQuery['path'] = newPath
                newQuery['theme'] = theme
                if links:
                    newQuery['links'] = links
                if forms:
                    newQuery['forms'] = forms
                if title:
                    if isinstance(title, six.text_type):
                        newQuery['title'] = title.encode('utf-8', 'replace')
                    else:
                        newQuery['title'] = title

                return self.request.getURL() + '?' + urllib.parse.urlencode(newQuery)

            if title:
                titleElement = tree.cssselect("html head title")
                if titleElement:
                    titleElement[0].text = title
                else:
                    headElement = tree.cssselect("html head")
                    if headElement:
                        headElement[0].append(lxml.html.builder.TITLE(title))

            if links:
                for n in tree.cssselect("a[href]"):
                    if links == 'disable':
                        n.attrib['href'] = '#'
                    elif links == 'replace':
                        n.attrib['href'] = encodeUrl(n.attrib['href'])

            if forms:
                for n in tree.cssselect("form[action]"):
                    if forms == 'disable':
                        n.attrib['action'] = '#'
                        n.attrib['onsubmit'] = 'javascript:return false;'
                    elif forms == 'replace':
                        n.attrib['action'] = encodeUrl(n.attrib['action'])

            result = lxml.html.tostring(tree)

        return result
Ejemplo n.º 10
0
    def transformIterable(self, result, encoding):
        """Apply the transform if required
        """
        # Obtain settings. Do nothing if not found
        policy = theming_policy(self.request)
        settings = policy.getSettings()
        if settings is None:
            return None
        if not policy.isThemeEnabled():
            return None
        result = self.parseTree(result)
        if result is None:
            return None

        debug_mode = getConfiguration().debug_mode
        runtrace = self.debug_theme()

        try:
            etree.clear_error_log()

            if settings.doctype:
                result.doctype = settings.doctype
                if not result.doctype.endswith('\n'):
                    result.doctype += '\n'

            transform = self.setupTransform(runtrace=runtrace)
            if transform is None:
                return None

            cache = None
            if not debug_mode:
                cache = policy.getCache()

            parameterExpressions = settings.parameterExpressions or {}
            params = prepareThemeParameters(
                findContext(self.request),
                self.request,
                parameterExpressions,
                cache
            )

            transformed = transform(result.tree, **params)
            error_log = transform.error_log
            if transformed is not None:
                # Transformed worked, swap content with result
                result.tree = transformed
        except etree.LxmlError as e:
            if not(debug_mode):
                raise
            error_log = e.error_log
            runtrace = True

        if runtrace:
            from diazo.runtrace import generate_debug_html
            # Add debug information to end of body
            body = result.tree.xpath('/html/body')[0]
            debug_url = findContext(
                self.request
            ).portal_url() + '/++resource++diazo-debug'
            body.insert(
                -1,
                generate_debug_html(
                    debug_url,
                    rules=settings.rules,
                    rules_parser=getParser('rules', settings.readNetwork),
                    error_log=error_log,
                )
            )
        return result
Ejemplo n.º 11
0
    def getFrame(self):
        """AJAX method to load a frame's contents

        Expects two query string parameters: ``path`` - the path to fetch - and
        ``theme``, which can be 'off', to disable the theme and 'apply' to
        apply the current theme to the response.

        Additionally:

        - a query string parameter ``links`` can be set to one of ``disable``
          or ``replace``. The former will disable hyperlinks; the latter will
          replace them with links using the
          ``@@themeing-controlpanel-getframe`` view.
        - a query string parameter ``forms`` can be set to one of ``disable``
          or ``replace``. The former will disable forms ; the latter will
          replace them with links using the
          ``@@themeing-controlpanel-getframe`` view.
        - a query string parameter ``title`` can be set to give a new page
          title
        """

        processInputs(self.request)

        path = self.request.form.get('path', None)
        theme = self.request.form.get('theme', 'off')
        links = self.request.form.get('links', None)
        forms = self.request.form.get('forms', None)
        title = self.request.form.get('title', None)

        if not path:
            return "<html><head></head><body></body></html>"

        portal = getPortal()
        portal_url = portal.absolute_url()
        response = subrequest(path, root=portal)

        result = response.getBody()
        content_type = response.headers.get('content-type')
        encoding = None
        if content_type is not None and ';' in content_type:
            content_type, encoding = content_type.split(';', 1)
        if encoding is None:
            encoding = 'utf-8'
        else:
            # e.g. charset=utf-8
            encoding = encoding.split('=', 1)[1].strip()

        # Not HTML? Return as-is
        if content_type is None or not content_type.startswith('text/html'):
            if len(result) == 0:
                result = ' '  # Zope does not deal well with empty responses
            return result

        result = result.decode(encoding).encode('ascii', 'xmlcharrefreplace')
        if len(result) == 0:
            result = ' '  # Zope does not deal well with empty responses

        if theme == 'off':
            self.request.response.setHeader('X-Theme-Disabled', '1')
        elif theme == 'apply':
            self.request.response.setHeader('X-Theme-Disabled', '1')
            themeInfo = getThemeFromResourceDirectory(self.context)

            policy = theming_policy(self.request)
            settings = policy.getSettings()

            context = self.context
            try:
                context = findContext(portal.restrictedTraverse(path))
            except (KeyError, NotFound,):
                pass

            serializer = getHTMLSerializer([result], pretty_print=False)

            try:
                transform = compileThemeTransform(
                    themeInfo.rules, themeInfo.absolutePrefix,
                    settings.readNetwork, themeInfo.parameterExpressions or {})
            except lxml.etree.XMLSyntaxError as e:
                return self.theme_error_template(error=e.msg)

            params = prepareThemeParameters(
                context, self.request, themeInfo.parameterExpressions or {})

            # Fix url and path since the request gave us this view
            params['url'] = quote_param(''.join((portal_url, path,)))
            params['path'] = quote_param(
                ''.join((portal.absolute_url_path(), path,))
            )

            if themeInfo.doctype:
                serializer.doctype = themeInfo.doctype
                if not serializer.doctype.endswith('\n'):
                    serializer.doctype += '\n'

            serializer.tree = transform(serializer.tree, **params)
            result = ''.join(serializer)

        if title or links or forms:
            tree = lxml.html.fromstring(result)

            def encodeUrl(orig):
                origUrl = urllib.parse.urlparse(orig)
                newPath = origUrl.path
                newQuery = urllib.parse.parse_qs(origUrl.query)

                # relative?
                if not origUrl.netloc:
                    newPath = urllib.parse.urljoin(
                        path.rstrip("/") + "/", newPath.lstrip("/"))
                elif not orig.lower().startswith(portal_url.lower()):
                    # Not an internal URL - ignore
                    return orig

                newQuery['path'] = newPath
                newQuery['theme'] = theme
                if links:
                    newQuery['links'] = links
                if forms:
                    newQuery['forms'] = forms
                if title:
                    if isinstance(title, six.text_type):
                        newQuery['title'] = title.encode('utf-8', 'replace')
                    else:
                        newQuery['title'] = title

                return self.request.getURL() + '?' + urllib.parse.urlencode(newQuery)

            if title:
                titleElement = tree.cssselect("html head title")
                if titleElement:
                    titleElement[0].text = title
                else:
                    headElement = tree.cssselect("html head")
                    if headElement:
                        headElement[0].append(lxml.html.builder.TITLE(title))

            if links:
                for n in tree.cssselect("a[href]"):
                    if links == 'disable':
                        n.attrib['href'] = '#'
                    elif links == 'replace':
                        n.attrib['href'] = encodeUrl(n.attrib['href'])

            if forms:
                for n in tree.cssselect("form[action]"):
                    if forms == 'disable':
                        n.attrib['action'] = '#'
                        n.attrib['onsubmit'] = 'javascript:return false;'
                    elif forms == 'replace':
                        n.attrib['action'] = encodeUrl(n.attrib['action'])

            result = lxml.html.tostring(tree)

        return result
Ejemplo n.º 12
0
    def transformIterable(self, result, encoding):
        """Apply the transform if required
        """
        # Obtain settings. Do nothing if not found
        settings = self.getSettings()
        if settings is None:
            return None
        if not isThemeEnabled(self.request, settings):
            return None
        result = self.parseTree(result)
        if result is None:
            return None

        DevelopmentMode = Globals.DevelopmentMode
        diazo_debug = self.request.get("diazo.debug", "").lower()
        runtrace = DevelopmentMode and diazo_debug in ("1", "y", "yes", "t", "true")

        try:
            etree.clear_error_log()

            if settings.doctype:
                result.doctype = settings.doctype
                if not result.doctype.endswith("\n"):
                    result.doctype += "\n"

            transform = self.setupTransform(runtrace=runtrace)
            if transform is None:
                return None

            cache = None
            if not DevelopmentMode:
                cache = getCache(settings)

            parameterExpressions = settings.parameterExpressions or {}
            params = prepareThemeParameters(findContext(self.request), self.request, parameterExpressions, cache)

            transformed = transform(result.tree, **params)
            error_log = transform.error_log
            if transformed is not None:
                # Transformed worked, swap content with result
                result.tree = transformed
        except etree.LxmlError as e:
            if not (DevelopmentMode):
                raise
            error_log = e.error_log
            runtrace = True

        if runtrace:
            from diazo.runtrace import generate_debug_html

            # Add debug information to end of body
            body = result.tree.xpath("/html/body")[0]
            debug_url = findContext(self.request).portal_url() + "/++resource++diazo-debug"
            body.insert(
                -1,
                generate_debug_html(
                    debug_url,
                    rules=settings.rules,
                    rules_parser=getParser("rules", settings.readNetwork),
                    error_log=error_log,
                ),
            )
        return result