[z3-checkins] r34696 - z3/deliverance/trunk/deliverance

ianb at codespeak.net ianb at codespeak.net
Thu Nov 16 23:05:19 CET 2006


Author: ianb
Date: Thu Nov 16 23:05:15 2006
New Revision: 34696

Added:
   z3/deliverance/trunk/deliverance/wsgimiddleware.py
      - copied unchanged from r34683, z3/deliverance/trunk/deliverance/wsgifilter.py
Removed:
   z3/deliverance/trunk/deliverance/wsgifilter.py
Modified:
   z3/deliverance/trunk/deliverance/proxyapp.py
   z3/deliverance/trunk/deliverance/test_wsgi.py
Log:
Renamed wsgifilter module to wsgimiddleware, to avoid name conflict with WSGIFilter

Modified: z3/deliverance/trunk/deliverance/proxyapp.py
==============================================================================
--- z3/deliverance/trunk/deliverance/proxyapp.py	(original)
+++ z3/deliverance/trunk/deliverance/proxyapp.py	Thu Nov 16 23:05:15 2006
@@ -4,7 +4,7 @@
 """
 
 from paste.proxy import TransparentProxy
-from deliverance import wsgifilter
+from deliverance.wsgimiddleware import DeliveranceMiddleware
 from deliverance.relocateresponse import RelocateMiddleware
 
 class ProxyDeliveranceApp(object):
@@ -18,7 +18,7 @@
         self.transparent = transparent
         self.debug_headers = debug_headers
         self.subapp = self.make_app()
-        self.deliverance_app = wsgifilter.DeliveranceMiddleware(
+        self.deliverance_app = DeliveranceMiddleware(
             self.subapp, theme_uri, rule_uri, renderer)
         self.relocate_content = relocate_content
 

Modified: z3/deliverance/trunk/deliverance/test_wsgi.py
==============================================================================
--- z3/deliverance/trunk/deliverance/test_wsgi.py	(original)
+++ z3/deliverance/trunk/deliverance/test_wsgi.py	Thu Nov 16 23:05:15 2006
@@ -3,7 +3,7 @@
 from lxml import etree
 from paste.fixture import TestApp
 from paste.urlparser import StaticURLParser
-from wsgifilter import DeliveranceMiddleware
+from deliverance.wsgimiddleware import DeliveranceMiddleware
 from formencode.doctest_xml_compare import xml_compare
 from htmlserialize import tostring
 

Deleted: /z3/deliverance/trunk/deliverance/wsgifilter.py
==============================================================================
--- /z3/deliverance/trunk/deliverance/wsgifilter.py	Thu Nov 16 23:05:15 2006
+++ (empty file)
@@ -1,294 +0,0 @@
-"""
-Deliverance theming as WSGI middleware
-"""
-
-import re
-import urlparse
-import urllib
-from lxml import etree
-from htmlserialize import decodeAndParseHTML as parseHTML
-from paste.wsgilib import intercept_output
-from paste.request import construct_url
-from paste.response import header_value, replace_header
-from htmlserialize import tostring
-from utils import DeliveranceError
-from utils import DELIVERANCE_ERROR_PAGE
-import sys 
-import datetime
-import threading
-import traceback
-from StringIO import StringIO
-
-DELIVERANCE_BASE_URL = 'deliverance.base-url'
-
-
-class DeliveranceMiddleware(object):
-    """
-    a DeliveranceMiddleware object exposes a single deliverance 
-    tranformation as a WSGI middleware component. 
-    """
-
-    def __init__(self, app, theme_uri, rule_uri, renderer='py'):
-        """
-        initializer
-        
-        app: wsgi application which this middleware wraps. 
-        theme_uri: uri referring the the theme document 
-        rule_uri: uri referring to the deliverance rules document 
-        renderer: selects deliverance render class to utilize when 
-          performing transformations, may be 'py' or 'xslt'
-        """
-        self.app = app
-        self.theme_uri = theme_uri
-        self.rule_uri = rule_uri
-        self._renderer = None
-        self._cache_time = datetime.datetime.now()
-        self._timeout = datetime.timedelta(0,10)
-        self._lock = threading.Lock()
-
-        if renderer == 'py':
-            import interpreter
-            self._rendererType = interpreter.Renderer
-        elif renderer == 'xslt':
-            import xslt
-            self._rendererType = xslt.Renderer
-        else:
-            raise ValueError("Unknown Renderer: %s - Expecting 'py' or 'xslt'" % renderer)
-
-    def get_renderer(self,environ):
-        """
-        retrieve the deliverance Renderer representing the transformation this 
-        middlware represents. Renderer may change according to caching rules. 
-        """
-        try:
-            self._lock.acquire()
-            if not self._renderer or self.cache_expired():
-                self._renderer = self.create_renderer(environ)
-                self._cache_time = datetime.datetime.now()
-            return self._renderer
-        finally:
-            self._lock.release()
-
-    def create_renderer(self,environ):
-        """
-        construct a new deliverance Renderer from the 
-        information passed to the initializer.  A new copy 
-        of the theme and rules is retrieved. 
-        """
-        theme = self.theme(environ)
-        rule = self.rule(environ)
-        full_theme_uri = urlparse.urljoin(
-            construct_url(environ, with_path_info=False),
-            self.theme_uri)
-
-        def reference_resolver(href, parse, encoding=None):
-            text = self.get_resource(environ,href)
-            if parse == "xml":
-                return etree.XML(text)
-            elif encoding:
-                return text.decode(encoding)
-
-        try:
-            parsedTheme = parseHTML(theme)
-        except Exception, message:
-            newmessage = "Unable to parse theme page (" + self.theme_uri + ")"
-            if message:
-                newmessage += ":" + str(message)
-            raise DeliveranceError(newmessage)
-
-        try:
-            parsedRule = etree.XML(rule)
-        except Exception, message:
-            newmessage = "Unable to parse rules (" + self.rule_uri + ")"
-            if message:
-                newmessage += ":" + str(message)
-            raise DeliveranceError(newmessage)
-
-        return self._rendererType(
-            theme=parsedTheme,
-            theme_uri=full_theme_uri,
-            rule=parsedRule, 
-            rule_uri=self.rule_uri,
-            reference_resolver=reference_resolver)
-
-        
-    def cache_expired(self):
-        """
-        returns true if the stored Renderer should be refreshed 
-        """
-        return self._cache_time + self._timeout < datetime.datetime.now()
-
-    def rule(self, environ):
-        """
-        retrieves the data referred to by the rule_uri passed to the 
-        initializer. 
-        """
-        try:
-            return self.get_resource(environ,self.rule_uri)
-        except Exception, message:
-            newmessage = "Unable to retrieve rules from " + self.rule_uri 
-            if message:
-                newmessage += ": " + str(message)
-
-            raise DeliveranceError(newmessage)
-
-    def theme(self, environ):
-        """
-        retrieves the data referred to by the theme_uri passed to the 
-        initializer. 
-        """
-        try:
-            return self.get_resource(environ,self.theme_uri)
-        except Exception, message:
-            newmessage = "Unable to retrieve theme page from " + self.theme_uri 
-            if message:
-                newmessage += ": " + str(message)
-            raise DeliveranceError(newmessage)
-
-
-    def __call__(self, environ, start_response):
-        """
-        WSGI entrypoint, responds to the request in 
-        environ. responses from the wrapped WSGI 
-        application of type text/html are themed 
-        using the transformation specified in the 
-        initializer. 
-        """
-        try:
-            qs = environ.get('QUERY_STRING', '')
-            environ[DELIVERANCE_BASE_URL] = construct_url(environ, with_path_info=False, with_query_string=False)
-            notheme = 'notheme' in qs
-            if notheme:
-                return self.app(environ, start_response)
-            if 'HTTP_ACCEPT_ENCODING' in environ:
-                del environ['HTTP_ACCEPT_ENCODING']
-
-            status, headers, body = intercept_output(
-                environ, self.app,
-                self.should_intercept,
-                start_response)
-
-            # ignore non-html responses 
-            if status is None:
-                return body
-
-            # don't theme html snippets 
-            if self.hasHTMLTag(body):
-                body = self.filter_body(environ, body)
-
-            replace_header(headers, 'content-length', str(len(body)))
-            replace_header(headers, 'content-type', 'text/html; charset=utf-8')
-            start_response(status, headers)
-            return [body]
-        
-        except DeliveranceError, message:            
-            stack = StringIO()
-            traceback.print_exception(sys.exc_info()[0],
-                                      sys.exc_info()[1],
-                                      sys.exc_info()[2],
-                                      file=stack)
-            status = "500 Internal Server Error"
-            headers = [('Content-type','text/html')]
-            start_response(status,headers)
-            errpage = DELIVERANCE_ERROR_PAGE % (message,stack.getvalue())
-            return [ errpage ]
-
-    def should_intercept(self, status, headers):
-        """
-        returns true if the status and headers given 
-        specify a response from the wrapped middleware 
-        which deliverance may need to theme. 
-        """
-        type = header_value(headers, 'content-type')
-        if type is None:
-            return False
-        return type.startswith('text/html') or type.startswith('application/xhtml+xml')
-
-    def filter_body(self, environ, body):
-        """
-        returns the result of the deliverance transformation on the string 'body' 
-        in the context of environ. The result is a string containing HTML. 
-        """
-        content = self.get_renderer(environ).render(parseHTML(body))
-        return tostring(content)
-
-    def get_resource(self, environ, uri):
-        """
-        retrieve the data referred to by the uri given. 
-        """
-        internalBaseURL = environ.get(DELIVERANCE_BASE_URL,None)
-        uri = urlparse.urljoin(internalBaseURL, uri)
-        
-        if  internalBaseURL and uri.startswith(internalBaseURL):
-            return self.get_internal_resource(environ, uri[len(internalBaseURL):])
-        else:
-            return self.get_external_resource(uri)
-
-    def relative_uri(self, uri):
-        """
-        returns true if uri is relative, false if 
-        the uri is absolute. 
-        """
-        if re.search(r'^[a-zA-Z]+:', uri):
-            return False
-        else:
-            return True
-
-    def get_external_resource(self, uri):
-        """
-        get the data referred to by the uri given 
-        using urllib (not through the wrapped app)
-        """
-        f = urllib.urlopen(uri)
-        content = f.read()
-        f.close()
-        return content
-
-    def get_internal_resource(self, environ, uri):
-        """
-        get the data referred to by the uri given 
-        by using the wrapped WSGI application 
-        """
-        environ = environ.copy()
-        if not uri.startswith('/'):
-            uri = '/' + uri
-        environ['PATH_INFO'] = uri
-        environ['SCRIPT_NAME'] = environ[DELIVERANCE_BASE_URL]
-        if environ['QUERY_STRING']:
-            environ['QUERY_STRING'] += '&notheme'
-        else:
-            environ['QUERY_STRING'] = 'notheme'
-
-        path_info = environ['PATH_INFO']
-        status, headers, body = intercept_output(environ, self.app)
-        if not status.startswith('200'):
-            loc = header_value(headers, 'location')
-            if loc:
-                loc = ' location=%r' % loc
-            else:
-                loc = ''
-            raise DeliveranceError(
-                "Request for internal resource at %s (%r) failed with status code %r%s"
-                % (construct_url(environ), path_info, status,
-                   loc))
-        return body
-
-    HTML_DOC_PAT = re.compile(r"^.*<\s*html(\s*|>).*$",re.I|re.M)
-    def hasHTMLTag(self, body):
-        """
-        a quick and dirty check to see if some text contains 
-        anything that looks like an html tag. This could 
-        certainly be improved if needed or there are 
-        ambiguous tags 
-        """
-        return self.HTML_DOC_PAT.search(body) is not None
-
-def make_filter(app, global_conf,
-                theme_uri=None, rule_uri=None):
-    assert theme_uri is not None, (
-        "You must give a theme_uri")
-    assert rule_uri is not None, (
-        "You must give a rule_uri")
-    return DeliveranceMiddleware(
-        app, theme_uri, rule_uri)
-


More information about the z3-checkins mailing list