def getXMLSerializer(iterable, parser=etree.XMLParser, serializer=etree.tostring, pretty_print=False, encoding=None, doctype=None): """Turn the given iterable into an XMLSerializer. If it is already an XMLSerializer, return as-is. Otherwise, parse the input using with the given parser in feed-parser mode and initalize an XMLSerializer with the appropriate serializer function and pretty printing flag. """ if isinstance(iterable, XMLSerializer): return iterable p = parser(encoding=encoding) for chunk in iterable: if not isinstance(chunk, bytes): p.feed(bytes(chunk, 'utf-8')) # print("O ooh! Mosaic str/bytes encoding ", type(chunk)) else: p.feed(chunk) root = p.close() return XMLSerializer(root.getroottree(), serializer, pretty_print, doctype=doctype)
def process_response(self, request, response): """ Transform the response with Diazo if transformable """ content = response if check_themes_enabled(request): theme = get_active_theme(request) if theme: rules_file = os.path.join(theme.theme_path(), 'rules.xml') if theme.id != self.theme_id or not os.path.exists( rules_file) or theme.debug: if not theme.builtin: if theme.rules: fp = open(rules_file, 'w') try: fp.write(theme.rules.serialize()) finally: fp.close() self.theme_id = theme.id self.diazo = DiazoMiddleware( app=self.app, global_conf=None, rules=rules_file, prefix=theme.theme_url(), doctype=DOCTYPE, ) compiled_theme = self.diazo.compile_theme() self.transform = etree.XSLT( compiled_theme, access_control=self.diazo.access_control) self.params = {} for key, value in self.diazo.environ_param_map.items(): if key in request.environ: if value in self.diazo.unquoted_params: self.params[value] = request.environ[key] else: self.params[value] = quote_param( request.environ[key]) try: if isinstance(response, etree._Element): response = HttpResponse() else: parser = etree.HTMLParser(remove_blank_text=True, remove_comments=True) content = etree.fromstring(response.content, parser) result = self.transform(content.decode('utf-8'), **self.params) response.content = XMLSerializer( result, doctype=DOCTYPE).serialize() except Exception, e: getLogger('django_diazo').error(e)
def decorator(*args, **kwargs): result = function(*args, **kwargs) return XMLSerializer(result, serializer, doctype=doctype)
def __call__(self, environ, start_response): request = Request(environ) if self.should_ignore(request): return self.app(environ, start_response) if self.remove_conditional_headers: request.remove_conditional_headers() else: # Always remove Range and Accept-Encoding headers request.remove_conditional_headers( remove_encoding=True, remove_range=False, remove_match=False, remove_modified=True, ) response = request.get_response(self.app) if not self.should_transform(response): return response(environ, start_response) try: input_encoding = response.charset # Note, the Content-Length header will not be set if request.method == 'HEAD': self.reset_headers(response) return response(environ, start_response) # Prepare the serializer try: serializer = getHTMLSerializer(response.app_iter, encoding=input_encoding) except etree.XMLSyntaxError: # Abort transform on syntax error for empty response # Headers should be left intact return response(environ, start_response) finally: if hasattr(response.app_iter, 'close'): response.app_iter.close() self.reset_headers(response) # Set up parameters params = {} for key, value in self.environ_param_map.items(): if key in environ: if value in self.unquoted_params: params[value] = environ[key] else: params[value] = quote_param(environ[key]) for key, value in self.params.items(): if key in self.unquoted_params: params[key] = value else: params[key] = quote_param(value) # Apply the transformation tree = self.transform(serializer.tree, **params) # Set content type (normally inferred from stylesheet) # Unfortunately lxml does not expose docinfo.mediaType if self.content_type is None: if tree.getroot().tag == 'html': response.content_type = 'text/html' else: response.content_type = 'text/xml' response.charset = tree.docinfo.encoding or self.charset # Return a repoze.xmliter XMLSerializer, which helps avoid re-parsing # the content tree in later middleware stages. response.app_iter = XMLSerializer(tree, doctype=self.doctype) # Calculate the content length - we still return the parsed tree # so that other middleware could avoid having to re-parse, even if # we take a hit on serialising here if self.update_content_length: response.content_length = len(str(response.app_iter)) return response(environ, start_response)