def test_internal_resolver(self): compiler_parser = etree.XMLParser() compiler_parser.resolvers.add(InternalResolver()) # We can use a sub-package or a directory since tests is a python package theme = resolvePythonURL(u'python://plone.app.theming.tests/theme.html') rules = resolvePythonURL(u'python://plone.app.theming/tests/rules.xml') compile_theme(rules, theme, compiler_parser=compiler_parser)
def test_python_resolver(self): compiler_parser = etree.XMLParser() compiler_parser.resolvers.add(PythonResolver()) theme = resolvePythonURL( u'python://plone.app.theming.tests/theme.html') rules = resolvePythonURL(u'python://plone.app.theming/tests/rules.xml') compile_theme(rules, theme, compiler_parser=compiler_parser)
def test_python_resolver(self): compiler_parser = etree.XMLParser() compiler_parser.resolvers.add(PythonResolver()) theme = resolvePythonURL( u'python://plone.app.theming.tests/theme.html' ) rules = resolvePythonURL(u'python://plone.app.theming/tests/rules.xml') compile_theme(rules, theme, compiler_parser=compiler_parser)
def transform(self, rules, theme_template, is_html5): if not self.should_transform(): return self.response context_instance = RequestContext(self.request) theme = loader.render_to_string(theme_template, context_instance=context_instance) output_xslt = compile_theme( rules=rules, theme=BytesIO(theme.encode('latin1')), ) transform = etree.XSLT(output_xslt) content = self.response.unicode_content or self.response.content content_doc = etree.fromstring(content, parser=etree.HTMLParser()) self.response.content = transform(content_doc) if is_html5: self.set_html5_doctype() self.reset_headers() return self.response
def transform(self, rules, theme_template, is_html5): if not self.should_transform(): return self.response context_instance = RequestContext(self.request, current_app=None) theme = loader.render_to_string(theme_template, context_instance=context_instance) output_xslt = compile_theme( rules=rules, theme=BytesIO(theme.encode('latin1')), ) transform = etree.XSLT(output_xslt) content_doc = etree.fromstring(self.response.content, parser=etree.HTMLParser()) self.response.content = transform(content_doc) if is_html5: self.set_html5_doctype() self.reset_headers() return self.response
def compileThemeTransform(rules, absolutePrefix=None, readNetwork=False, parameterExpressions=None, runtrace=False): """Prepare the theme transform by compiling the rules with the given options """ if parameterExpressions is None: parameterExpressions = {} accessControl = etree.XSLTAccessControl(read_file=True, write_file=False, create_dir=False, read_network=readNetwork, write_network=False) if absolutePrefix: absolutePrefix = expandAbsolutePrefix(absolutePrefix) params = set(parameterExpressions.keys() + ['url', 'base', 'path', 'scheme', 'host']) xslParams = dict((k, '') for k in params) compiledTheme = compile_theme(rules, absolute_prefix=absolutePrefix, parser=getParser('theme', readNetwork), rules_parser=getParser('rules', readNetwork), compiler_parser=getParser('compiler', readNetwork), read_network=readNetwork, access_control=accessControl, update=True, xsl_params=xslParams, runtrace=runtrace, ) if not compiledTheme: return None return etree.XSLT(compiledTheme, access_control=accessControl, )
def compileThemeTransform(rules, absolutePrefix=None, readNetwork=False, parameterExpressions=None, runtrace=False): """Prepare the theme transform by compiling the rules with the given options """ if parameterExpressions is None: parameterExpressions = {} accessControl = etree.XSLTAccessControl( read_file=True, write_file=False, create_dir=False, read_network=readNetwork, write_network=False ) if absolutePrefix: absolutePrefix = expandAbsolutePrefix(absolutePrefix) params = set(["url", "base", "path", "scheme", "host"]) params.update(parameterExpressions.keys()) xslParams = {k: "" for k in params} compiledTheme = compile_theme( rules, absolute_prefix=absolutePrefix, parser=getParser("theme", readNetwork), rules_parser=getParser("rules", readNetwork), compiler_parser=getParser("compiler", readNetwork), read_network=readNetwork, access_control=accessControl, update=True, xsl_params=xslParams, runtrace=runtrace, ) if not compiledTheme: return None return etree.XSLT(compiledTheme, access_control=accessControl)
def compileThemeTransform(rules, absolutePrefix=None, readNetwork=False, parameterExpressions=None): """Prepare the theme transform by compiling the rules with the given options """ if parameterExpressions is None: parameterExpressions = {} accessControl = etree.XSLTAccessControl(read_file=True, write_file=False, create_dir=False, read_network=readNetwork, write_network=False) if absolutePrefix: absolutePrefix = expandAbsolutePrefix(absolutePrefix) params = set(parameterExpressions.keys() + ['url', 'base', 'path', 'scheme', 'host']) xslParams = dict((k, '') for k in params) internalResolver = InternalResolver() pythonResolver = PythonResolver() if readNetwork: networkResolver = NetworkResolver() rulesParser = etree.XMLParser(recover=False) rulesParser.resolvers.add(internalResolver) rulesParser.resolvers.add(pythonResolver) if readNetwork: rulesParser.resolvers.add(networkResolver) themeParser = etree.HTMLParser() themeParser.resolvers.add(internalResolver) themeParser.resolvers.add(pythonResolver) if readNetwork: themeParser.resolvers.add(networkResolver) compilerParser = etree.XMLParser() compilerParser.resolvers.add(internalResolver) compilerParser.resolvers.add(pythonResolver) if readNetwork: compilerParser.resolvers.add(networkResolver) compiledTheme = compile_theme(rules, absolute_prefix=absolutePrefix, parser=themeParser, rules_parser=rulesParser, compiler_parser=compilerParser, read_network=readNetwork, access_control=accessControl, update=True, xsl_params=xslParams, ) if not compiledTheme: return None return etree.XSLT(compiledTheme, access_control=accessControl, )
def transform(self, rules, theme_template, is_html5, context_data=None): """Method used to make a transformation on the content of the http response based on the rules and theme_templates passed as paremters :param rules: A file with a set of diazo rules to make a transformation over the original response content :param theme_template: A file containing the template used to format the the original response content :param is_html5: A boolean parameter to identify a html5 doctype :returns: A response with a content transformed based on the rules and theme_template """ if not self.should_transform(): self.log.info("Don't need to be transformed") return self.response theme = loader.render_to_string(theme_template, context=context_data, request=self.request) output_xslt = compile_theme( rules=rules, theme=StringIO(theme), ) transform = etree.XSLT(output_xslt) self.log.debug("Transform: %s", transform) charset = get_charset(self.response.get('Content-Type')) try: decoded_response = self.response.content.decode(charset) except UnicodeDecodeError: decoded_response = self.response.content.decode(charset, 'ignore') self.log.warning("Charset is {} and type of encode used in file is\ different. Some unknown characteres might be\ ignored.".format(charset)) content_doc = etree.fromstring(decoded_response, parser=etree.HTMLParser()) self.response.content = transform(content_doc) if is_html5: self.set_html5_doctype() self.reset_headers() self.log.debug("Response transformer: %s", self.response) return self.response
def _transform(self, response, main_response, req, proxy_url, prefix): """Applies xslt transformation to proxied page. @response - response from proxied app @main_response - response from main application, we use it to get main page layout for transformation to apply, as theme for diazo @req - original request made by user from inside our main app @proxy_url - external application url @prefix - path to embedded external application within our main app """ # do not transform non html reponse if not response.content_type or \ not response.content_type.startswith('text/html'): return response # prepare rules file # TODO: get diazo rules from External Application content object rules = StringIO(safe_unicode(DEFAULT_DIAZO_RULES)) # prepare theme file which is our application template theme = StringIO(safe_unicode(main_response.body)) # compile our theme from diazo.compiler import compile_theme compiled_theme = compile_theme(rules, theme, xsl_params={ 'external_app_url': proxy_url, 'app_url': req.host_url + prefix, 'url': req.path_url, 'path': req.path, 'base_url': req.path_url } ) transform = etree.XSLT(compiled_theme) # prepare content page which is external app page content = StringIO(safe_unicode(self._get_response_body(response))) content = etree.parse(content, etree.HTMLParser()) # finally apply transformation transformed = transform(content) output = etree.tostring(transformed) response.body = output return response
def compile_theme(self): """Compile the Diazo theme, returning an lxml tree (containing an XSLT document) """ filesystem_resolver = FilesystemResolver() python_resolver = PythonResolver() wsgi_resolver = WSGIResolver(self.app) network_resolver = NetworkResolver() null_resolver = etree.Resolver() rules_parser = etree.XMLParser(recover=False) resolvers = [filesystem_resolver, wsgi_resolver, python_resolver, null_resolver] shuffle(resolvers) for resolver in resolvers: rules_parser.resolvers.add(resolver) if self.read_network: rules_parser.resolvers.add(network_resolver) theme_parser = etree.HTMLParser() resolvers = [filesystem_resolver, wsgi_resolver, python_resolver, null_resolver] shuffle(resolvers) for resolver in resolvers: theme_parser.resolvers.add(resolver) if self.read_network: theme_parser.resolvers.add(network_resolver) xsl_params = self.params.copy() for value in self.environ_param_map.values(): if value not in xsl_params: xsl_params[value] = None return compile_theme(self.rules, theme=self.theme, absolute_prefix=self.absolute_prefix, includemode=self.includemode, access_control=self.access_control, read_network=self.read_network, parser=theme_parser, rules_parser=rules_parser, xsl_params=xsl_params, )
def transform(self, rules, theme_template, is_html5, context_data=None): """Method used to make a transformation on the content of the http response based on the rules and theme_templates passed as paremters :param rules: A file with a set of diazo rules to make a transformation over the original response content :param theme_template: A file containing the template used to format the the original response content :param is_html5: A boolean parameter to identify a html5 doctype :returns: A response with a content transformed based on the rules and theme_template """ if not self.should_transform(): self.log.info("Don't need to be transformed") return self.response context_instance = RequestContext(self.request, context_data) theme = loader.render_to_string(theme_template, context_instance=context_instance) output_xslt = compile_theme( rules=rules, theme=StringIO(theme), ) transform = etree.XSLT(output_xslt) self.log.debug("Transform: %s", transform) charset = get_charset(self.response.get('Content-Type')) content_doc = etree.fromstring(self.response.content.decode(charset), parser=etree.HTMLParser()) self.response.content = transform(content_doc) if is_html5: self.set_html5_doctype() self.reset_headers() self.log.debug("Response transformer: %s", self.response) return self.response
def compile_theme(self): """Compile the Diazo theme, returning an lxml tree (containing an XSLT document) """ filesystem_resolver = FilesystemResolver(self.app) wsgi_resolver = WSGIResolver(self.app) python_resolver = PythonResolver() network_resolver = NetworkResolver() rules_parser = etree.XMLParser(recover=False) rules_parser.resolvers.add(wsgi_resolver) rules_parser.resolvers.add(filesystem_resolver) rules_parser.resolvers.add(python_resolver) if self.read_network: rules_parser.resolvers.add(network_resolver) theme_parser = etree.HTMLParser() theme_parser.resolvers.add(wsgi_resolver) theme_parser.resolvers.add(filesystem_resolver) theme_parser.resolvers.add(python_resolver) if self.read_network: theme_parser.resolvers.add(network_resolver) xsl_params = self.params.copy() for value in self.environ_param_map.values(): if value not in xsl_params: xsl_params[value] = None return compile_theme( self.rules, theme=self.theme, absolute_prefix=self.absolute_prefix, includemode=self.includemode, access_control=self.access_control, read_network=self.read_network, parser=theme_parser, rules_parser=rules_parser, xsl_params=xsl_params, )
def compileThemeTransform(rules, absolutePrefix=None, readNetwork=False, parameterExpressions=None): """Prepare the theme transform by compiling the rules with the given options """ if parameterExpressions is None: parameterExpressions = {} accessControl = etree.XSLTAccessControl(read_file=True, write_file=False, create_dir=False, read_network=readNetwork, write_network=False) if absolutePrefix: absolutePrefix = expandAbsolutePrefix(absolutePrefix) params = set(parameterExpressions.keys() + ['url', 'base', 'path', 'scheme', 'host']) xslParams = dict((k, '') for k in params) internalResolver = InternalResolver() pythonResolver = PythonResolver() if readNetwork: networkResolver = NetworkResolver() rulesParser = etree.XMLParser(recover=False) rulesParser.resolvers.add(internalResolver) rulesParser.resolvers.add(pythonResolver) if readNetwork: rulesParser.resolvers.add(networkResolver) themeParser = etree.HTMLParser() themeParser.resolvers.add(internalResolver) themeParser.resolvers.add(pythonResolver) if readNetwork: themeParser.resolvers.add(networkResolver) compilerParser = etree.XMLParser() compilerParser.resolvers.add(internalResolver) compilerParser.resolvers.add(pythonResolver) if readNetwork: compilerParser.resolvers.add(networkResolver) compiledTheme = compile_theme( rules, absolute_prefix=absolutePrefix, parser=themeParser, rules_parser=rulesParser, compiler_parser=compilerParser, read_network=readNetwork, access_control=accessControl, update=True, xsl_params=xslParams, ) if not compiledTheme: return None return etree.XSLT( compiledTheme, access_control=accessControl, )
def main(): """Called from console script """ op = _createOptionParser(usage=usage) op.add_option("-x", "--xsl", metavar="transform.xsl", help="XSL transform", dest="xsl", default=None) op.add_option("--path", metavar="PATH", help="URI path", dest="path", default=None) op.add_option( "--parameters", metavar="param1=val1,param2=val2", help="Set the values of arbitrary parameters", dest="parameters", default=None, ) op.add_option( "--runtrace-xml", metavar="runtrace.xml", help="Write an xml format runtrace to file", dest="runtrace_xml", default=None, ) op.add_option( "--runtrace-html", metavar="runtrace.html", help="Write an html format runtrace to file", dest="runtrace_html", default=None, ) (options, args) = op.parse_args() if len(args) > 2: op.error("Wrong number of arguments.") elif len(args) == 2: if options.xsl or options.rules: op.error("Wrong number of arguments.") path, content = args if path.lower().endswith(".xsl"): options.xsl = path else: options.rules = path elif len(args) == 1: content, = args else: op.error("Wrong number of arguments.") if options.rules is None and options.xsl is None: op.error("Must supply either options or rules") if options.trace: logger.setLevel(logging.DEBUG) runtrace = False if options.runtrace_xml or options.runtrace_html: runtrace = True parser = etree.HTMLParser() parser.resolvers.add(RunResolver(os.path.dirname(content))) if options.xsl is not None: output_xslt = etree.parse(options.xsl) else: xsl_params = None if options.xsl_params: xsl_params = split_params(options.xsl_params) output_xslt = compile_theme( rules=options.rules, theme=options.theme, extra=options.extra, parser=parser, read_network=options.read_network, absolute_prefix=options.absolute_prefix, includemode=options.includemode, indent=options.pretty_print, xsl_params=xsl_params, runtrace=runtrace, ) if content == "-": content = sys.stdin if options.read_network: access_control = AC_READ_NET else: access_control = AC_READ_FILE transform = etree.XSLT(output_xslt, access_control=access_control) content_doc = etree.parse(content, parser=parser) params = {} if options.path is not None: params["path"] = "'%s'" % options.path if options.parameters: for key, value in split_params(options.parameters).items(): params[key] = quote_param(value) output_html = transform(content_doc, **params) if isinstance(options.output, basestring): out = open(options.output, "wt") else: out = options.output out.write(str(output_html)) if runtrace: runtrace_doc = diazo.runtrace.generate_runtrace(rules=options.rules, error_log=transform.error_log) if options.runtrace_xml: if options.runtrace_xml == "-": out = sys.stdout else: out = open(options.runtrace_xml, "wt") runtrace_doc.write(out, encoding="utf-8", pretty_print=options.pretty_print) if options.runtrace_html: if options.runtrace_html == "-": out = sys.stdout else: out = open(options.runtrace_html, "wt") out.write(str(diazo.runtrace.runtrace_to_html(runtrace_doc))) for msg in transform.error_log: if not msg.message.startswith("<runtrace "): logger.warn(msg)
def setupTransform(self): request = self.request DevelopmentMode = Globals.DevelopmentMode # Obtain settings. Do nothing if not found toadapt = (getSite(), self.request) settings = getMultiAdapter(toadapt, IThemeSettings) if settings is None: return None if not isThemeEnabled(request, settings): return None cache = getCache(settings) # Apply theme transform = None if not DevelopmentMode: transform = cache.transform if transform is None: rules = settings.rules absolutePrefix = settings.absolutePrefix or None readNetwork = settings.readNetwork accessControl = etree.XSLTAccessControl(read_file=True, write_file=False, create_dir=False, read_network=readNetwork, write_network=False) if absolutePrefix: absolutePrefix = expandAbsolutePrefix(absolutePrefix) params = set(settings.parameterExpressions.keys() + ['url', 'base', 'path', 'scheme', 'host']) xslParams = dict((k, '') for k in params) internalResolver = InternalResolver() pythonResolver = PythonResolver() if readNetwork: networkResolver = NetworkResolver() rulesParser = etree.XMLParser(recover=False) rulesParser.resolvers.add(internalResolver) rulesParser.resolvers.add(pythonResolver) if readNetwork: rulesParser.resolvers.add(networkResolver) themeParser = etree.HTMLParser() themeParser.resolvers.add(internalResolver) themeParser.resolvers.add(pythonResolver) if readNetwork: themeParser.resolvers.add(networkResolver) compilerParser = etree.XMLParser() compilerParser.resolvers.add(internalResolver) compilerParser.resolvers.add(pythonResolver) if readNetwork: compilerParser.resolvers.add(networkResolver) compiledTheme = compile_theme(rules, absolute_prefix=absolutePrefix, parser=themeParser, rules_parser=rulesParser, compiler_parser=compilerParser, read_network=readNetwork, access_control=accessControl, update=True, xsl_params=xslParams, ) if not compiledTheme: return None transform = etree.XSLT(compiledTheme, access_control=accessControl, ) if not DevelopmentMode: cache.updateTransform(transform) return transform
def main(): """Called from console script """ op = _createOptionParser(usage=usage) op.add_option("-x", "--xsl", metavar="transform.xsl", help="XSL transform", dest="xsl", default=None) op.add_option("--path", metavar="PATH", help="URI path", dest="path", default=None) op.add_option("--parameters", metavar="param1=val1,param2=val2", help="Set the values of arbitrary parameters", dest="parameters", default=None) (options, args) = op.parse_args() if len(args) > 2: op.error("Wrong number of arguments.") elif len(args) == 2: if options.xsl or options.rules: op.error("Wrong number of arguments.") path, content = args if path.lower().endswith('.xsl'): options.xsl = path else: options.rules = path elif len(args) == 1: content, = args else: op.error("Wrong number of arguments.") if options.rules is None and options.xsl is None: op.error("Must supply either options or rules") if options.trace: logger.setLevel(logging.DEBUG) parser = etree.HTMLParser() parser.resolvers.add(RunResolver(os.path.dirname(content))) if options.xsl is not None: output_xslt = etree.parse(options.xsl) else: xsl_params = None if options.xsl_params: xsl_params = split_params(options.xsl_params) output_xslt = compile_theme( rules=options.rules, theme=options.theme, extra=options.extra, parser=parser, read_network=options.read_network, absolute_prefix=options.absolute_prefix, includemode=options.includemode, indent=options.pretty_print, xsl_params=xsl_params, ) if content == '-': content = sys.stdin if options.read_network: access_control = AC_READ_NET else: access_control = AC_READ_FILE transform = etree.XSLT(output_xslt, access_control=access_control) content_doc = etree.parse(content, parser=parser) params = {} if options.path is not None: params['path'] = "'%s'" % options.path if options.parameters: for key, value in split_params(options.parameters).items(): params[key] = quote_param(value) output_html = transform(content_doc, **params) if isinstance(options.output, basestring): out = open(options.output, 'wt') else: out = options.output out.write(str(output_html)) for msg in transform.error_log: logger.warn(msg)
def main(): """Called from console script """ op = _createOptionParser(usage=usage) op.add_option("-x", "--xsl", metavar="transform.xsl", help="XSL transform", dest="xsl", default=None) op.add_option("--path", metavar="PATH", help="URI path", dest="path", default=None) op.add_option("--parameters", metavar="param1=val1,param2=val2", help="Set the values of arbitrary parameters", dest="parameters", default=None) (options, args) = op.parse_args() if len(args) > 2: op.error("Wrong number of arguments.") elif len(args) == 2: if options.xsl or options.rules: op.error("Wrong number of arguments.") path, content = args if path.lower().endswith('.xsl'): options.xsl = path else: options.rules = path elif len(args) == 1: content, = args else: op.error("Wrong number of arguments.") if options.rules is None and options.xsl is None: op.error("Must supply either options or rules") if options.trace: logger.setLevel(logging.DEBUG) parser = etree.HTMLParser() parser.resolvers.add(RunResolver(os.path.dirname(content))) if options.xsl is not None: output_xslt = etree.parse(options.xsl) else: xsl_params=None if options.xsl_params: xsl_params = split_params(options.xsl_params) output_xslt = compile_theme( rules=options.rules, theme=options.theme, extra=options.extra, parser=parser, read_network=options.read_network, absolute_prefix=options.absolute_prefix, includemode=options.includemode, indent=options.pretty_print, xsl_params=xsl_params, ) if content == '-': content = sys.stdin if options.read_network: access_control = AC_READ_NET else: access_control = AC_READ_FILE transform = etree.XSLT(output_xslt, access_control=access_control) content_doc = etree.parse(content, parser=parser) params = {} if options.path is not None: params['path'] = "'%s'" % options.path if options.parameters: for key, value in split_params(options.parameters).items(): params[key] = quote_param(value) output_html = transform(content_doc, **params) if isinstance(options.output, basestring): out = open(options.output, 'wt') else: out = options.output out.write(str(output_html)) for msg in transform.error_log: logger.warn(msg)
def main(): """Called from console script """ op = _createOptionParser(usage=usage) op.add_option( '-x', '--xsl', metavar='transform.xsl', help='XSL transform', dest='xsl', default=None, ) op.add_option( '--path', metavar='PATH', help='URI path', dest='path', default=None, ) op.add_option( '--parameters', metavar='param1=val1,param2=val2', help='Set the values of arbitrary parameters', dest='parameters', default=None, ) op.add_option( '--runtrace-xml', metavar='runtrace.xml', help='Write an xml format runtrace to file', dest='runtrace_xml', default=None, ) op.add_option( '--runtrace-html', metavar='runtrace.html', help='Write an html format runtrace to file', dest='runtrace_html', default=None, ) (options, args) = op.parse_args() if len(args) > 2: op.error('Wrong number of arguments.') elif len(args) == 2: if options.xsl or options.rules: op.error('Wrong number of arguments.') path, content = args if path.lower().endswith('.xsl'): options.xsl = path else: options.rules = path elif len(args) == 1: content, = args else: op.error('Wrong number of arguments.') if options.rules is None and options.xsl is None: op.error('Must supply either options or rules') if options.trace: logger.setLevel(logging.DEBUG) runtrace = False if options.runtrace_xml or options.runtrace_html: runtrace = True parser = etree.HTMLParser() parser.resolvers.add(RunResolver(os.path.dirname(content))) if options.xsl is not None: output_xslt = etree.parse(options.xsl) else: xsl_params = None if options.xsl_params: xsl_params = split_params(options.xsl_params) output_xslt = compile_theme( rules=options.rules, theme=options.theme, extra=options.extra, parser=parser, read_network=options.read_network, absolute_prefix=options.absolute_prefix, includemode=options.includemode, indent=options.pretty_print, xsl_params=xsl_params, runtrace=runtrace, ) if content == '-': content = sys.stdin if options.read_network: access_control = AC_READ_NET else: access_control = AC_READ_FILE transform = etree.XSLT(output_xslt, access_control=access_control) content_doc = etree.parse(content, parser=parser) params = {} if options.path is not None: params['path'] = "'{path}'".format(path=options.path) if options.parameters: for key, value in split_params(options.parameters).items(): params[key] = quote_param(value) output_html = transform(content_doc, **params) if isinstance(options.output, string_types): out = open(options.output, 'wt') else: out = options.output out.write(str(output_html)) if runtrace: runtrace_doc = diazo.runtrace.generate_runtrace( rules=options.rules, error_log=transform.error_log, ) if options.runtrace_xml: if options.runtrace_xml == '-': out = sys.stdout else: out = open(options.runtrace_xml, 'wt') runtrace_doc.write( out, encoding='utf-8', pretty_print=options.pretty_print, ) if options.runtrace_html: if options.runtrace_html == '-': out = sys.stdout else: out = open(options.runtrace_html, 'wt') out.write(str(diazo.runtrace.runtrace_to_html(runtrace_doc))) for msg in transform.error_log: if not msg.message.startswith('<runtrace '): logger.warn(msg)