[Checkins] SVN: Sandbox/shane/republish/zope reorg
Shane Hathaway
shane at hathawaymix.org
Sat Feb 14 15:51:18 EST 2009
Log message for revision 96547:
reorg
Changed:
D Sandbox/shane/republish/zope/pipeline/
D Sandbox/shane/republish/zope/publisher/
A Sandbox/shane/republish/zope.pipeline/src/zope/
A Sandbox/shane/republish/zope.pipeline/src/zope/__init__.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/authenticate.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/authenticate.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/event.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/event.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/fixrel.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/fixrel.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/openroot.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/openroot.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/requestsetup.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/requestsetup.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/retry.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/retry.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/switch.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/switch.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/traversal.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/traversal.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/txnctl.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/txnctl.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/configure.zcml
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/configure.zcml
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/entry.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/entry.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/interfaces.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/interfaces.py
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/meta.zcml
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/meta.zcml
D Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/zcml.py
A Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/zcml.py
A Sandbox/shane/republish/zope.publisher/
A Sandbox/shane/republish/zope.publisher/src/
A Sandbox/shane/republish/zope.publisher/src/zope/
A Sandbox/shane/republish/zope.publisher/src/zope/__init__.py
A Sandbox/shane/republish/zope.publisher/src/zope/publisher/
-=-
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/__init__.py (from rev 96490, Sandbox/shane/republish/zope/__init__.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/__init__.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/__init__.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,7 @@
+# this is a namespace package
+try:
+ import pkg_resources
+ pkg_resources.declare_namespace(__name__)
+except ImportError:
+ import pkgutil
+ __path__ = pkgutil.extend_path(__path__, __name__)
Property changes on: Sandbox/shane/republish/zope.pipeline/src/zope/__init__.py
___________________________________________________________________
Added: svn:mergeinfo
+
Property changes on: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline
___________________________________________________________________
Added: svn:mergeinfo
+
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/authenticate.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/apps/authenticate.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/authenticate.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,86 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-from zope.component import getGlobalSiteManager
-from zope.interface import adapts
-from zope.interface import implements
-from zope.publisher.interfaces import IWSGIApplication
-from zope.security.management import newInteraction
-from zope.security.management import endInteraction
-
-from zope.app.security.interfaces import IAuthentication
-from zope.app.security.interfaces import IFallbackUnauthenticatedPrincipal
-
-
-class Authenticator(object):
- """WSGI app that hooks into Zope-based authentication.
-
- The WSGI environment must contain 'zope.request'.
- """
- implements(IWSGIApplication)
- adapts(IWSGIApplication, IRequest)
-
- def __init__(self, app, marker_request=None):
- self.app = app
-
- def __call__(self, environ, start_response):
- request = environ['zope.request']
- auth = getGlobalSiteManager().getUtility(IAuthentication)
- principal = auth.authenticate(request)
- if principal is None:
- request.traversal_hooks.append(placeful_auth)
- principal = auth.unauthenticatedPrincipal()
- if principal is None:
- # Get the fallback unauthenticated principal
- principal = getUtility(IFallbackUnauthenticatedPrincipal)
- request.principal = principal
-
- newInteraction(request)
- try:
- return self.app(environ, start_response)
- finally:
- endInteraction()
-
- def __repr__(self):
- return '%s(%s)' % (self.__class__.__name__, repr(self.app))
-
-
-def placeful_auth(request, ob):
- """Traversal hook that tries to authenticate in a context"""
-
- if not IUnauthenticatedPrincipal.providedBy(request.principal):
- # We've already got an authenticated user. There's nothing to do.
- # Note that beforeTraversal guarentees that user is not None.
- return
-
- if not ISite.providedBy(ob):
- # We won't find an authentication utility here, so give up.
- return
-
- sm = removeSecurityProxy(ob).getSiteManager()
-
- auth = sm.queryUtility(IAuthentication)
- if auth is None:
- # No auth utility here
- return
-
- # Try to authenticate against the auth utility
- principal = auth.authenticate(request)
- if principal is None:
- principal = auth.unauthenticatedPrincipal()
- if principal is None:
- # nothing to do here
- return
-
- request.setPrincipal(principal)
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/authenticate.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/apps/authenticate.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/authenticate.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/authenticate.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,84 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+from zope.component import getGlobalSiteManager
+from zope.interface import implements
+from zope.publisher.interfaces import IWSGIApplication
+from zope.security.management import newInteraction
+from zope.security.management import endInteraction
+
+from zope.app.security.interfaces import IAuthentication
+from zope.app.security.interfaces import IFallbackUnauthenticatedPrincipal
+
+
+class Authenticator(object):
+ """WSGI app that hooks into Zope-based authentication.
+
+ The WSGI environment must contain 'zope.request'.
+ """
+ implements(IWSGIApplication)
+
+ def __init__(self, next_app):
+ self.next_app = next_app
+
+ def __call__(self, environ, start_response):
+ request = environ['zope.request']
+ auth = getGlobalSiteManager().getUtility(IAuthentication)
+ principal = auth.authenticate(request)
+ if principal is None:
+ request.traversal_hooks.append(placeful_auth)
+ principal = auth.unauthenticatedPrincipal()
+ if principal is None:
+ # Get the fallback unauthenticated principal
+ principal = getUtility(IFallbackUnauthenticatedPrincipal)
+ request.principal = principal
+
+ newInteraction(request)
+ try:
+ return self.next_app(environ, start_response)
+ finally:
+ endInteraction()
+
+ def __repr__(self):
+ return '%s(%s)' % (self.__class__.__name__, repr(self.next_app))
+
+
+def placeful_auth(request, ob):
+ """Traversal hook that tries to authenticate in a context"""
+
+ if not IUnauthenticatedPrincipal.providedBy(request.principal):
+ # We've already got an authenticated user. There's nothing to do.
+ # Note that beforeTraversal guarentees that user is not None.
+ return
+
+ if not ISite.providedBy(ob):
+ # We won't find an authentication utility here, so give up.
+ return
+
+ sm = removeSecurityProxy(ob).getSiteManager()
+
+ auth = sm.queryUtility(IAuthentication)
+ if auth is None:
+ # No auth utility here
+ return
+
+ # Try to authenticate against the auth utility
+ principal = auth.authenticate(request)
+ if principal is None:
+ principal = auth.unauthenticatedPrincipal()
+ if principal is None:
+ # nothing to do here
+ return
+
+ request.setPrincipal(principal)
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/event.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/apps/event.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/event.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,48 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-from zope.event import notify
-from zope.interface import adapts
-from zope.interface import implements
-from zope.publisher.interfaces import IWSGIApplication
-from zope.publisher.interfaces.event import BeforeTraverseEvent
-from zope.publisher.interfaces.event import EndRequestEvent
-
-
-class EventNotifier(object):
- """Fires request-related events.
-
- Fires BeforeTraverseEvent and EndRequestEvent at the appropriate
- times.
- """
- implements(IWSGIApplication)
- adapts(IWSGIApplication)
-
- def __init__(self, app):
- self.app = app
-
- def __call__(self, environ, start_response):
- request = environ['zope.request']
- request.traversal_hooks.append(fireBeforeTraverse)
- try:
- return self.app(environ, start_response)
- finally:
- if request.traversed:
- name, ob = request.traversed[-1]
- else:
- ob = None
- notify(EndRequestEvent(ob, request))
-
-def fireBeforeTraverse(request, ob):
- notify(BeforeTraverseEvent(ob, request))
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/event.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/apps/event.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/event.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/event.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+from zope.event import notify
+from zope.interface import implements
+from zope.publisher.interfaces import IWSGIApplication
+from zope.publisher.interfaces.event import BeforeTraverseEvent
+from zope.publisher.interfaces.event import EndRequestEvent
+
+
+class EventNotifier(object):
+ """Fires request-related events.
+
+ Fires BeforeTraverseEvent and EndRequestEvent at the appropriate
+ times.
+ """
+ implements(IWSGIApplication)
+
+ def __init__(self, next_app):
+ self.next_app = next_app
+
+ def __call__(self, environ, start_response):
+ request = environ['zope.request']
+ request.traversal_hooks.append(fireBeforeTraverse)
+ try:
+ return self.next_app(environ, start_response)
+ finally:
+ if request.traversed:
+ name, ob = request.traversed[-1]
+ else:
+ ob = None
+ notify(EndRequestEvent(ob, request))
+
+def fireBeforeTraverse(request, ob):
+ notify(BeforeTraverseEvent(ob, request))
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/fixrel.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/apps/fixrel.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/fixrel.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,72 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-
-class FixRelativeLinks(object):
- """WSGI middleware that fixes relative links.
-
- This application deals with request URLs that are problematic
- for relative links in HTML because the requested URL is too different
- from the traversed object's canonical URL. It fixes the problem by
- either redirecting (before calling the app) or adding a base tag
- to the response text (after calling the app).
- """
- implements(IWSGIApplication)
- adapts(IWSGIApplication)
-
- allow_redirect = True
-
- def __init__(self, app):
- self.app = app
-
- def __call__(self, environ, start_response):
- request = environ['zope.request']
-
- need_fix = False
- allow_redirect = False
-
- if request.form_action:
- # When there is a :method or :action form variable, we need to
- # fix relative URLs, but not by redirecting.
- need_fix = True
- else:
- # If the URL ends with a slash, the URL specified one default
- # traversal step, otherwise the URL specified zero.
- # Compare the number of default traversal steps
- # specified by the URL with the number of default traversal
- # steps actually performed. Set need_fix to True if
- # the specified number does not match the actual.
- if environ['PATH_INFO'].endswith('/'):
- specified = 1
- else:
- specified = 0
- actual = request.traversed_default
- if actual != specified:
- need_fix = True
- allow_redirect = (
- self.allow_redirect and request.method == 'GET')
-
- if not need_fix:
- # No fix required
- return self.app(environ, start_response)
-
- if redirect:
- # Redirect, then end the pipeline early
- request.response.redirect(request.getURL())
- start_response(response.getStatusString(), response.getHeaders())
- return response.consumeBodyIter()
-
- # TODO: Call the app. Buffer and alter the response
- # if the result is HTML.
-
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/fixrel.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/apps/fixrel.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/fixrel.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/fixrel.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,71 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+
+class FixRelativeLinks(object):
+ """WSGI middleware that fixes relative links.
+
+ This application deals with request URLs that are problematic
+ for relative links in HTML because the requested URL is too different
+ from the traversed object's canonical URL. It fixes the problem by
+ either redirecting (before calling the app) or adding a base tag
+ to the response text (after calling the app).
+ """
+ implements(IWSGIApplication)
+
+ allow_redirect = True
+
+ def __init__(self, next_app):
+ self.next_app = next_app
+
+ def __call__(self, environ, start_response):
+ request = environ['zope.request']
+
+ need_fix = False
+ allow_redirect = False
+
+ if request.form_action:
+ # When there is a :method or :action form variable, we need to
+ # fix relative URLs, but not by redirecting.
+ need_fix = True
+ else:
+ # If the URL ends with a slash, the URL specified one default
+ # traversal step, otherwise the URL specified zero.
+ # Compare the number of default traversal steps
+ # specified by the URL with the number of default traversal
+ # steps actually performed. Set need_fix to True if
+ # the specified number does not match the actual.
+ if environ['PATH_INFO'].endswith('/'):
+ specified = 1
+ else:
+ specified = 0
+ actual = request.traversed_default
+ if actual != specified:
+ need_fix = True
+ allow_redirect = (
+ self.allow_redirect and request.method == 'GET')
+
+ if not need_fix:
+ # No fix required
+ return self.next_app(environ, start_response)
+
+ if redirect:
+ # Redirect, then end the pipeline early
+ request.response.redirect(request.getURL())
+ start_response(response.getStatusString(), response.getHeaders())
+ return response.consumeBodyIter()
+
+ # TODO: Call the app. Buffer and alter the response
+ # if the result is HTML.
+
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/openroot.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/apps/openroot.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/openroot.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,69 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-from zope.component import getUtility
-from zope.interface import adapts
-from zope.interface import implements
-from zope.publisher.interfaces import IWSGIApplication
-from zope.security.checker import ProxyFactory
-
-
-class RootOpener(object):
- """Puts a root object in 'zope.request' of the WSGI environment.
-
- Requires the environment to contain 'zope.database',
- which is normally a ZODB.DB.DB object.
- Sets request.traversed to a list with one element.
- Also closes the database connection on the way out.
-
- Special case: if the traversal stack contains "++etc++process",
- instead of opening the database, this uses the utility by that
- name as the root object.
- """
- implements(IWSGIApplication)
- adapts(IWSGIApplication)
-
- root_name = 'Application'
- app_controller_name = '++etc++process'
-
- def __init__(self, app):
- self.app = app
-
- def __call__(self, environ, start_response):
- request = environ['zope.request']
-
- # If the traversal stack contains self.app_controller_name,
- # then we should get the app controller rather than look
- # in the database.
- if self.app_controller_name in request.traversal_stack:
- root = getUtility(name=self.app_controller_name)
- request.traversed = [(self.app_controller_name, root)]
- return self.app(environ, start_response)
-
- # Open the database.
- db = environ['zope.database']
- conn = db.open()
-
- request.annotations['ZODB.interfaces.IConnection'] = conn
- root = conn.root()
- app = root.get(self.root_name, None)
- if app is None:
- raise SystemError("Zope Application Not Found")
-
- request.traversed = [(self.root_name, ProxyFactory(app))]
-
- try:
- return self.app(environ, start_response)
- finally:
- conn.close()
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/openroot.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/apps/openroot.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/openroot.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/openroot.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,65 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+from zope.component import getUtility
+from zope.interface import implements
+from zope.publisher.interfaces import IWSGIApplication
+from zope.security.checker import ProxyFactory
+
+
+class RootOpener(object):
+ """Puts a root object in 'zope.request' of the WSGI environment.
+
+ Requires the environment to contain 'zope.database',
+ which is normally a ZODB.DB.DB object.
+ Sets request.traversed to a list with one element.
+ Also closes the database connection on the way out.
+
+ Special case: if the traversal stack contains "++etc++process",
+ instead of opening the database, this uses the utility by that
+ name as the root object.
+ """
+ implements(IWSGIApplication)
+
+ root_name = 'Application'
+ app_controller_name = '++etc++process'
+
+ def __init__(self, next_app, database):
+ self.next_app = next_app
+ self.database = database
+
+ def __call__(self, environ, start_response):
+ request = environ['zope.request']
+
+ # If the traversal stack contains self.app_controller_name,
+ # then we should get the app controller rather than look
+ # in the database.
+ if self.app_controller_name in request.traversal_stack:
+ root = getUtility(name=self.app_controller_name)
+ request.traversed = [(self.app_controller_name, root)]
+ return self.app(environ, start_response)
+
+ # Open the database.
+ conn = self.database.open()
+ try:
+ request.annotations['ZODB.interfaces.IConnection'] = conn
+ root = conn.root()
+ app = root.get(self.root_name, None)
+ if app is None:
+ raise SystemError("Zope Application Not Found")
+ request.traversed = [(self.root_name, ProxyFactory(app))]
+
+ return self.next_app(environ, start_response)
+ finally:
+ conn.close()
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/requestsetup.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/apps/requestsetup.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/requestsetup.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,206 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""The request setup WSGI app and the registry for IRequest factories.
-"""
-__docformat__ = 'restructuredtext'
-
-from zope.configuration.exceptions import ConfigurationError
-from zope.httpform import FormParser
-from zope.i18n.interfaces import IUserPreferredCharsets
-from zope.interface import adapts
-from zope.interface import implements
-from zope.publisher.interfaces import IWSGIApplication
-from zope.testing import cleanup
-
-from zope.pipeline.interfaces import IRequestFactoryRegistry
-
-
-class CreateRequest(object):
- """WSGI middleware that creates a request and puts it in the environment.
-
- Chooses the type of request based on the content of the WSGI
- environment.
-
- Also sets the request locale and skin.
- """
- implements(IWSGIApplication)
- adapts(IWSGIApplication)
-
- def __init__(self, app):
- self.app = app
-
- def __call__(self, environ, start_response):
- scheme = environ.get('wsgi.url_scheme', 'http').lower()
- method = environ.get('REQUEST_METHOD', 'GET').upper()
- mimetype = environ.get('CONTENT_TYPE', '')
- request = factoryRegistry.make_request(
- scheme, method, mimetype, environ)
- environ['zope.request'] = request
-
- self.set_locale(request)
- self.set_skin(request)
-
- return self.app(environ, start_response)
-
- def set_locale(self, request):
- envadapter = IUserPreferredLanguages(request, None)
- if envadapter is None:
- return
-
- langs = envadapter.getPreferredLanguages()
- for httplang in langs:
- parts = (httplang.split('-') + [None, None])[:3]
- try:
- request.locale = locales.getLocale(*parts)
- return
- except LoadLocaleError:
- # Just try the next combination
- pass
- else:
- # No combination gave us an existing locale, so use the default,
- # which is guaranteed to exist
- request.locale = locales.getLocale(None, None, None)
-
- def set_skin(self, request):
- if IBrowserRequest.providedBy(request):
- # only browser requests have skins
- setDefaultSkin(request)
-
-
-class ProcessForm(object):
- """WSGI middleware that processes HTML form data.
-
- This step is separate from request creation so that the
- error handling step can catch form data errors.
-
- Requires the environment to contain a 'zope.request' that
- is an IHTTPRequest, not just an IRequest.
- """
- implements(IWSGIApplication)
- adapts(IWSGIApplication)
- request_type = IHTTPRequest
-
- def __init__(self, app):
- self.app = app
-
- def __call__(self, environ, start_response):
- request = environ['zope.request']
-
- charsets = []
- def to_unicode(text):
- if not charsets:
- envadapter = IUserPreferredCharsets(request)
- charsets.extend(
- envadapter.getPreferredCharsets() or ['utf-8'])
- for charset in charsets:
- try:
- return unicode(text, charset)
- except UnicodeError:
- pass
- raise UnicodeError(
- "Unable to decode %s using any available character set"
- % repr(text))
-
- parser = FormParser(environ, to_unicode=to_unicode)
- request.form = parser.parse()
- if parser.action:
- request.traversal_stack.insert(0, parser.action)
-
- return self.app(environ, start_response)
-
-
-class RequestFactoryRegistry(object):
- """This registry implements a four stage lookup for request factories::
-
- {scheme -> {method > { mimetype ->
- [
- {'priority' : some_int,
- 'factory' : factory,
- 'name' : some_name }, ...
- ]
- }}}
-
- The `priority` is used to define a lookup-order when multiple factories
- are registered for the same scheme, method, and mime-type.
- """
- implements(IRequestFactoryRegistry)
-
- def __init__(self):
- self._d = {} # {scheme->{method->{mimetype->{factories_data}}}}
-
- def register(self, scheme, method, mimetype, name, priority, factory):
- """Register a factory for scheme + method + mimetype """
-
- # initialize the three-level deep nested datastructure if necessary
- m = self._d.setdefault(scheme, {})
- m = m.setdefault(method, {})
- l = m.setdefault(mimetype, [])
-
- # Check if there is already a registered request factory (check by
- # name). If yes then it will be removed and replaced by a new
- # factory.
- for pos, d in enumerate(l):
- if d['name'] == name:
- del l[pos]
- break
- # add the publisher factory + additional informations
- l.append({'name' : name, 'factory' : factory, 'priority' : priority})
-
- # order by descending priority
- l.sort(lambda x,y: -cmp(x['priority'], y['priority']))
-
- # check if the priorities are unique
- priorities = [item['priority'] for item in l]
- if len(set(priorities)) != len(l):
- raise ConfigurationError('All registered publishers for a given '
- 'method+mimetype must have distinct '
- 'priorities. Please check your ZCML '
- 'configuration')
-
- def get_factories_for(self, scheme, method, mimetype):
- if ';' in mimetype:
- # `mimetype` might be something like 'text/xml; charset=utf8'. In
- # this case we are only interested in the first part.
- mimetype = mimetype.split(';', 1)[0]
-
- try:
- return self._d[scheme][method][mimetype.strip()]
- except KeyError:
- return None
-
- def make_request(self, scheme, method, mimetype, environment):
- """Get a factory given scheme+method+mimetype and an environment."""
-
- variations = [
- (scheme, method, mimetype),
- (scheme, method, '*'),
- (scheme, '*', '*')
- ]
- for s, m, mt in variations:
- factory_lst = self.get_factories_for(s, m, mt)
- if factory_lst:
- # Try to call each factory. If the factory can't or
- # doesn't want to handle the given environment, it should
- # return None.
- for d in factory_lst:
- factory = d['factory']
- request = factory(environment)
- if request is not None:
- return request
- raise ConfigurationError('No registered request factory found '
- 'for (%s/%s/%s)' % (scheme, method, mimetype))
-
-factoryRegistry = RequestFactoryRegistry()
-
-cleanup.addCleanUp(lambda : factoryRegistry.__init__())
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/requestsetup.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/apps/requestsetup.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/requestsetup.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/requestsetup.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,202 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""The request setup WSGI app and the registry for IRequest factories.
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.configuration.exceptions import ConfigurationError
+from zope.httpform import FormParser
+from zope.i18n.interfaces import IUserPreferredCharsets
+from zope.interface import implements
+from zope.publisher.interfaces import IWSGIApplication
+from zope.testing import cleanup
+
+from zope.pipeline.interfaces import IRequestFactoryRegistry
+
+
+class CreateRequest(object):
+ """WSGI middleware that creates a request and puts it in the environment.
+
+ Chooses the type of request based on the content of the WSGI
+ environment.
+
+ Also sets the request locale and skin.
+ """
+ implements(IWSGIApplication)
+
+ def __init__(self, next_app):
+ self.next_app = next_app
+
+ def __call__(self, environ, start_response):
+ scheme = environ.get('wsgi.url_scheme', 'http').lower()
+ method = environ.get('REQUEST_METHOD', 'GET').upper()
+ mimetype = environ.get('CONTENT_TYPE', '')
+ request = factoryRegistry.make_request(
+ scheme, method, mimetype, environ)
+ environ['zope.request'] = request
+
+ self.set_locale(request)
+ self.set_skin(request)
+
+ return self.next_app(environ, start_response)
+
+ def set_locale(self, request):
+ envadapter = IUserPreferredLanguages(request, None)
+ if envadapter is None:
+ return
+
+ langs = envadapter.getPreferredLanguages()
+ for httplang in langs:
+ parts = (httplang.split('-') + [None, None])[:3]
+ try:
+ request.locale = locales.getLocale(*parts)
+ return
+ except LoadLocaleError:
+ # Just try the next combination
+ pass
+ else:
+ # No combination gave us an existing locale, so use the default,
+ # which is guaranteed to exist
+ request.locale = locales.getLocale(None, None, None)
+
+ def set_skin(self, request):
+ if IBrowserRequest.providedBy(request):
+ # only browser requests have skins
+ setDefaultSkin(request)
+
+
+class ProcessForm(object):
+ """WSGI middleware that processes HTML form data.
+
+ This step is separate from request creation so that the
+ error handling step can catch form data errors.
+
+ Requires the environment to contain a 'zope.request' that
+ is an IHTTPRequest, not just an IRequest.
+ """
+ implements(IWSGIApplication)
+
+ def __init__(self, next_app):
+ self.next_app = next_app
+
+ def __call__(self, environ, start_response):
+ request = environ['zope.request']
+
+ charsets = []
+ def to_unicode(text):
+ if not charsets:
+ envadapter = IUserPreferredCharsets(request)
+ charsets.extend(
+ envadapter.getPreferredCharsets() or ['utf-8'])
+ for charset in charsets:
+ try:
+ return unicode(text, charset)
+ except UnicodeError:
+ pass
+ raise UnicodeError(
+ "Unable to decode %s using any available character set"
+ % repr(text))
+
+ parser = FormParser(environ, to_unicode=to_unicode)
+ request.form = parser.parse()
+ if parser.action:
+ request.traversal_stack.insert(0, parser.action)
+
+ return self.next_app(environ, start_response)
+
+
+class RequestFactoryRegistry(object):
+ """This registry implements a four stage lookup for request factories::
+
+ {scheme -> {method > { mimetype ->
+ [
+ {'priority' : some_int,
+ 'factory' : factory,
+ 'name' : some_name }, ...
+ ]
+ }}}
+
+ The `priority` is used to define a lookup-order when multiple factories
+ are registered for the same scheme, method, and mime-type.
+ """
+ implements(IRequestFactoryRegistry)
+
+ def __init__(self):
+ self._d = {} # {scheme->{method->{mimetype->{factories_data}}}}
+
+ def register(self, scheme, method, mimetype, name, priority, factory):
+ """Register a factory for scheme + method + mimetype """
+
+ # initialize the three-level deep nested datastructure if necessary
+ m = self._d.setdefault(scheme, {})
+ m = m.setdefault(method, {})
+ l = m.setdefault(mimetype, [])
+
+ # Check if there is already a registered request factory (check by
+ # name). If yes then it will be removed and replaced by a new
+ # factory.
+ for pos, d in enumerate(l):
+ if d['name'] == name:
+ del l[pos]
+ break
+ # add the publisher factory + additional informations
+ l.append({'name' : name, 'factory' : factory, 'priority' : priority})
+
+ # order by descending priority
+ l.sort(lambda x,y: -cmp(x['priority'], y['priority']))
+
+ # check if the priorities are unique
+ priorities = [item['priority'] for item in l]
+ if len(set(priorities)) != len(l):
+ raise ConfigurationError('All registered publishers for a given '
+ 'method+mimetype must have distinct '
+ 'priorities. Please check your ZCML '
+ 'configuration')
+
+ def get_factories_for(self, scheme, method, mimetype):
+ if ';' in mimetype:
+ # `mimetype` might be something like 'text/xml; charset=utf8'. In
+ # this case we are only interested in the first part.
+ mimetype = mimetype.split(';', 1)[0]
+
+ try:
+ return self._d[scheme][method][mimetype.strip()]
+ except KeyError:
+ return None
+
+ def make_request(self, scheme, method, mimetype, environment):
+ """Get a factory given scheme+method+mimetype and an environment."""
+
+ variations = [
+ (scheme, method, mimetype),
+ (scheme, method, '*'),
+ (scheme, '*', '*')
+ ]
+ for s, m, mt in variations:
+ factory_lst = self.get_factories_for(s, m, mt)
+ if factory_lst:
+ # Try to call each factory. If the factory can't or
+ # doesn't want to handle the given environment, it should
+ # return None.
+ for d in factory_lst:
+ factory = d['factory']
+ request = factory(environment)
+ if request is not None:
+ return request
+ raise ConfigurationError('No registered request factory found '
+ 'for (%s/%s/%s)' % (scheme, method, mimetype))
+
+factoryRegistry = RequestFactoryRegistry()
+
+cleanup.addCleanUp(lambda : factoryRegistry.__init__())
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/retry.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/apps/retry.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/retry.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,79 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-from zope.interface import adapts
-from zope.interface import implements
-from zope.publisher.interfaces import IWSGIApplication
-from zope.publisher.interfaces.exceptions import Retry
-from ZODB.POSException import ConflictError
-
-from zope.pipeline.autotemp import AutoTemporaryFile
-
-
-class Retry(object):
- """Retries requests when a Retry or ConflictError propagates.
-
- This middleware app should enclose the app that creates zope.request.
- It sets an environment variable named 'zope.can_retry'. Error handlers
- should propagate Retry or ConflictError when 'zope.can_retry' is
- true.
- """
- implements(IWSGIApplication)
- adapts(IWSGIApplication)
-
- def __init__(self, app, max_attempts=3):
- self.app = app
- self.max_attempts = max_attempts
-
- def __call__(self, environ, start_response):
- wsgi_input = environ.get('wsgi.input')
- if wsgi_input is not None:
- if not hasattr(wsgi_input, 'seek'):
- # make the input stream rewindable
- f = AutoTemporaryFile()
- f.copyfrom(wsgi_input)
- f.seek(0)
- environ['wsgi.input'] = wsgi_input = f
-
- def retryable_start_response(status, response_headers, exc_info=None):
- start_response_params[:] = [status, response_headers, exc_info]
- tmp = AutoTemporaryFile()
- output_file[:] = [tmp]
- return tmp
-
- attempt = 1
- while attempt < self.max_attempts:
- start_response_params = []
- output_file = []
- environ['zope.can_retry'] = True
- try:
- res = self.app(environ, retryable_start_response)
- except (Retry, ConflictError):
- if 'zope.request' in environ:
- del environ['zope.request']
- if wsgi_input is not None:
- wsgi_input.seek(0)
- attempt += 1
- else:
- if start_response_params:
- dest = start_response(*tuple(start_response_params))
- src = output_file[0]
- src.seek(0)
- src.copyto(dest)
- src.close()
- return res
-
- # try once more, this time without retry support
- environ['zope.can_retry'] = False
- return self.app(environ, start_response)
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/retry.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/apps/retry.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/retry.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/retry.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,77 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+from zope.interface import implements
+from zope.publisher.interfaces import IWSGIApplication
+from zope.publisher.interfaces.exceptions import Retry
+from ZODB.POSException import ConflictError
+
+from zope.pipeline.autotemp import AutoTemporaryFile
+
+
+class Retry(object):
+ """Retries requests when a Retry or ConflictError propagates.
+
+ This middleware app should enclose the app that creates zope.request.
+ It sets an environment variable named 'zope.can_retry'. Error handlers
+ should propagate Retry or ConflictError when 'zope.can_retry' is
+ true.
+ """
+ implements(IWSGIApplication)
+
+ def __init__(self, next_app, max_attempts=3):
+ self.next_app = next_app
+ self.max_attempts = max_attempts
+
+ def __call__(self, environ, start_response):
+ wsgi_input = environ.get('wsgi.input')
+ if wsgi_input is not None:
+ if not hasattr(wsgi_input, 'seek'):
+ # make the input stream rewindable
+ f = AutoTemporaryFile()
+ f.copyfrom(wsgi_input)
+ f.seek(0)
+ environ['wsgi.input'] = wsgi_input = f
+
+ def retryable_start_response(status, response_headers, exc_info=None):
+ start_response_params[:] = [status, response_headers, exc_info]
+ tmp = AutoTemporaryFile()
+ output_file[:] = [tmp]
+ return tmp
+
+ attempt = 1
+ while attempt < self.max_attempts:
+ start_response_params = []
+ output_file = []
+ environ['zope.can_retry'] = True
+ try:
+ res = self.next_app(environ, retryable_start_response)
+ except (Retry, ConflictError):
+ if 'zope.request' in environ:
+ del environ['zope.request']
+ if wsgi_input is not None:
+ wsgi_input.seek(0)
+ attempt += 1
+ else:
+ if start_response_params:
+ dest = start_response(*tuple(start_response_params))
+ src = output_file[0]
+ src.seek(0)
+ src.copyto(dest)
+ src.close()
+ return res
+
+ # try once more, this time without retry support
+ environ['zope.can_retry'] = False
+ return self.next_app(environ, start_response)
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/switch.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/apps/switch.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/switch.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,34 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-
-from zope.interface import implements
-from zope.publisher.interfaces import IWSGIApplication
-
-from zope.pipeline.entry import get_pipeline
-
-class SwitchPipeline(object):
- """WSGI application that switches to a pipeline based on the request type.
-
- Requires 'zope.request' in the environment.
- """
- implements(IWSGIApplication)
-
- def __call__(self, environ, start_response):
- request = environ['zope.request']
- app = get_pipeline(request=request)
- return app(environ, start_response)
-
- def __repr__(self):
- return '%s()' % self.__class__.__name__
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/switch.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/apps/switch.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/switch.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/switch.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,49 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+
+from zope.interface import implements
+from zope.interface import providedBy
+from zope.publisher.interfaces import IWSGIApplication
+
+from zope.pipeline.entry import create_pipeline
+from zope.pipeline.interfaces import IPipelineParticipant
+
+
+class SwitchPipeline(object):
+ """WSGI application that switches to a pipeline based on the request type.
+
+ This should be placed at the end of the INoRequest pipeline.
+ Requires 'zope.request' in the environment.
+ """
+ implements(IWSGIApplication, IPipelineParticipant)
+
+ def __init__(self):
+ # _cache: {(interfaces provided by the request) -> pipeline}
+ self._cache = {}
+
+ def set_pipeline_params(self, name, pipeline_params):
+ self.pipeline_params = pipeline_params
+
+ def __call__(self, environ, start_response):
+ request = environ['zope.request']
+ provided = tuple(providedBy(request))
+ pipeline = self._cache.get(provided)
+ if pipeline is None:
+ pipeline = create_pipeline(self.pipeline_params, provided)
+ self._cache[provided] = pipeline
+ return pipeline(environ, start_response)
+
+ def __repr__(self):
+ return '%s()' % self.__class__.__name__
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/traversal.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/apps/traversal.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/traversal.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,68 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-from zope.interface import adapts
-from zope.interface import implements
-from zope.publisher.interfaces import IWSGIApplication
-
-
-class Traverser(object):
- """Traverses the object graph based on the traversal stack.
-
- Requires 'zope.request' in the WSGI environment.
- """
- implements(IWSGIApplication)
- adapts(IWSGIApplication)
-
- def __init__(self, app):
- self.app = app
-
- def __call__(self, environ, start_response):
- request = environ['zope.request']
- self.traverse(request)
- return self.app(environ, start_response)
-
- def traverse(self, request):
- traversal_stack = request.traversal_stack
- traversal_hooks = request.traversal_hooks
- traversed = request.traversed
-
- root_name, obj = traversed[-1]
- prev_object = None
-
- while True:
- if obj is not prev_object:
- # Call hooks (but not more than once).
- for hook in traversal_hooks:
- hook(request, obj)
-
- if not traversal_stack:
- break
-
- prev_object = obj
-
- # Traverse to the next step.
- name = traversal_stack.pop()
- obj = self.traverse_name(obj, name)
- traversed.append((name, obj))
-
- def traverse_name(self, obj, name):
- pass
-
-
-class HTTPTraverser(Traverser):
- implements(IWSGIApplication)
- adapts(IWSGIApplication)
- request_type = IHTTPRequest
-
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/traversal.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/apps/traversal.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/traversal.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/traversal.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,64 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+from zope.interface import implements
+from zope.publisher.interfaces import IWSGIApplication
+
+
+class Traverser(object):
+ """Traverses the object graph based on the traversal stack.
+
+ Requires 'zope.request' in the WSGI environment.
+ """
+ implements(IWSGIApplication)
+
+ def __init__(self, next_app):
+ self.next_app = next_app
+
+ def __call__(self, environ, start_response):
+ request = environ['zope.request']
+ self.traverse(request)
+ return self.next_app(environ, start_response)
+
+ def traverse(self, request):
+ traversal_stack = request.traversal_stack
+ traversal_hooks = request.traversal_hooks
+ traversed = request.traversed
+
+ root_name, obj = traversed[-1]
+ prev_object = None
+
+ while True:
+ if obj is not prev_object:
+ # Call hooks (but not more than once).
+ for hook in traversal_hooks:
+ hook(request, obj)
+
+ if not traversal_stack:
+ break
+
+ prev_object = obj
+
+ # Traverse to the next step.
+ name = traversal_stack.pop()
+ obj = self.traverse_name(obj, name)
+ traversed.append((name, obj))
+
+ def traverse_name(self, obj, name):
+ pass
+
+
+class HTTPTraverser(Traverser):
+ implements(IWSGIApplication)
+
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/txnctl.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/apps/txnctl.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/txnctl.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,105 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-
-import transaction
-from zope.location.interfaces import ILocationInfo
-from zope.interface import adapts
-from zope.interface import implements
-from zope.interface import providedBy
-from zope.publisher.interfaces import IRequest
-from zope.publisher.interfaces import IWSGIApplication
-from zope.security.proxy import removeSecurityProxy
-
-
-class TransactionController(object):
- """WSGI middleware that begins and commits/aborts transactions.
- """
- implements(IWSGIApplication)
- adapts(IWSGIApplication)
-
- def __init__(self, app):
- self.app = app
-
- def __call__(self, environ, start_response):
- transaction.begin()
- try:
- res = self.app(environ, start_response)
- except:
- transaction.abort()
- raise
- txn = transaction.get()
- if txn.isDoomed():
- txn.abort()
- else:
- txn.commit()
- return res
-
-
-class TransactionAnnotator(object):
- """WSGI middleware that annotates transactions.
-
- Requires 'zope.request' in the environment.
- """
- implements(IWSGIApplication)
- adapts(IWSGIApplication)
-
- def __init__(self, app):
- self.app = app
-
- def __call__(self, environ, start_response):
- res = self.app(environ, start_response)
- txn = transaction.get()
- if not txn.isDoomed():
- request = environ['zope.request']
- name, ob = request.traversed[-1]
- self.annotate(txn, request, ob)
- return res
-
- def annotate(self, txn, request, ob):
- """Set some useful meta-information on the transaction.
-
- This information is used by the undo framework, for example.
- """
- if request.principal is not None:
- txn.setUser(request.principal.id)
-
- # Work around methods that are usually used for views
- bare = removeSecurityProxy(ob)
- if isinstance(bare, instancemethod):
- ob = bare.im_self
-
- # set the location path
- path = None
- location = ILocationInfo(ob, None)
- if location is not None:
- # Views are made children of their contexts, but that
- # doesn't necessarily mean that we can fully resolve the
- # path. E.g. the family tree of a resource cannot be
- # resolved completely, as the site manager is a dead end.
- try:
- path = location.getPath()
- except (AttributeError, TypeError):
- pass
- if path is not None:
- txn.setExtendedInfo('location', path)
-
- # set the request type
- iface = IRequest
- for iface in providedBy(request):
- if iface.extends(IRequest):
- break
- iface_dotted = '%s.%s' % (iface.__module__, iface.getName())
- txn.setExtendedInfo('request_type', iface_dotted)
- return txn
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/txnctl.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/apps/txnctl.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/txnctl.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/apps/txnctl.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,102 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+
+import transaction
+from zope.location.interfaces import ILocationInfo
+from zope.interface import implements
+from zope.interface import providedBy
+from zope.publisher.interfaces import IRequest
+from zope.publisher.interfaces import IWSGIApplication
+from zope.security.proxy import removeSecurityProxy
+
+
+class TransactionController(object):
+ """WSGI middleware that begins and commits/aborts transactions.
+ """
+ implements(IWSGIApplication)
+
+ def __init__(self, next_app):
+ self.next_app = next_app
+
+ def __call__(self, environ, start_response):
+ transaction.begin()
+ try:
+ res = self.next_app(environ, start_response)
+ except:
+ transaction.abort()
+ raise
+ txn = transaction.get()
+ if txn.isDoomed():
+ txn.abort()
+ else:
+ txn.commit()
+ return res
+
+
+class TransactionAnnotator(object):
+ """WSGI middleware that annotates transactions.
+
+ Requires 'zope.request' in the environment.
+ """
+ implements(IWSGIApplication)
+
+ def __init__(self, next_app):
+ self.next_app = next_app
+
+ def __call__(self, environ, start_response):
+ res = self.app(environ, start_response)
+ txn = transaction.get()
+ if not txn.isDoomed():
+ request = environ['zope.request']
+ name, ob = request.traversed[-1]
+ self.annotate(txn, request, ob)
+ return res
+
+ def annotate(self, txn, request, ob):
+ """Set some useful meta-information on the transaction.
+
+ This information is used by the undo framework, for example.
+ """
+ if request.principal is not None:
+ txn.setUser(request.principal.id)
+
+ # Work around methods that are usually used for views
+ bare = removeSecurityProxy(ob)
+ if isinstance(bare, instancemethod):
+ ob = bare.im_self
+
+ # set the location path
+ path = None
+ location = ILocationInfo(ob, None)
+ if location is not None:
+ # Views are made children of their contexts, but that
+ # doesn't necessarily mean that we can fully resolve the
+ # path. E.g. the family tree of a resource cannot be
+ # resolved completely, as the site manager is a dead end.
+ try:
+ path = location.getPath()
+ except (AttributeError, TypeError):
+ pass
+ if path is not None:
+ txn.setExtendedInfo('location', path)
+
+ # set the request type
+ iface = IRequest
+ for iface in providedBy(request):
+ if iface.extends(IRequest):
+ break
+ iface_dotted = '%s.%s' % (iface.__module__, iface.getName())
+ txn.setExtendedInfo('request_type', iface_dotted)
+ return txn
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/configure.zcml
===================================================================
--- Sandbox/shane/republish/zope/pipeline/configure.zcml 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/configure.zcml 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,133 +0,0 @@
-<configure xmlns="http://namespaces.zope.org/zope"
- xmlns:wsgi="http://namespaces.zope.org/wsgi">
-
-<!-- a wsgi:pipeline directive specifies the names of
- applications to use in a pipeline. Its implementation
- registers a bound PipelineApplicationList.adapt() method as an
- unnamed adapter from the request type to IPipelineApplicationList. -->
-
-<wsgi:pipeline for=".interfaces.IUndecidedRequest" names="
- virtual_host
- retry
- create_request
- switch_pipeline
- " />
-
-<wsgi:pipeline for="zope.publisher.interfaces.IRequest" names="
- log
- open_root
- control_transaction
- event
- handle_error
- process_form
- authenticate
- traverse
- annotate_transaction
- fix_relative_links
- call
- " />
-
-<!-- a wsgi:middleware directive registers an application for use
- as middleware in a pipeline. It is like an adapter directive,
- except that the adapter is registered as requiring
- two parameters, 'app' and 'request', while only the 'app' parameter is
- provided to the middleware factory; the factory is wrapped
- to make that happen. If neither the directive nor the factory
- says what kind of request is required, assume IRequest. -->
-
-<wsgi:middleware
- factory=".apps.retry.Retry"
- name="retry"
- for=".interfaces.INoRequest" />
-
-<wsgi:middleware
- factory=".apps.requestsetup.CreateRequest"
- name="create_request"
- for=".interfaces.INoRequest" />
-
-<!-- a wsgi:application directive registers an application for use
- as the final application in a pipeline. It is like an adapter
- directive, except that the adapter is registered as requiring
- one parameter, 'request', while no parameters are passed to the
- application factory; the factory is wrapped
- to make that happen. If neither the directive nor the factory
- says what kind of request is required, assume IRequest. -->
-
-<wsgi:application
- factory=".apps.switch.SwitchPipeline"
- name="switch_pipeline"
- for=".interfaces.INoRequest" />
-
-
-<wsgi:middleware
- factory="..."
- name="log" />
-
-<wsgi:middleware
- factory=".apps.openroot.RootOpener"
- name="open_root" />
-
-<wsgi:middleware
- factory=".apps.txnctl.TransactionController"
- name="control_transaction" />
-
-<wsgi:middleware
- factory=".apps.notify.EventNotifier"
- name="event" />
-
-<wsgi:middleware
- factory="..."
- name="handle_error" />
-
-<!-- no form processing for non-browser requests -->
-<wsgi:middleware
- factory=".apps.passthrough"
- name="process_form"
- for="zope.publisher.interfaces.IRequest" />
-
-<!-- process forms for browser requests -->
-<wsgi:middleware
- factory=".apps.requestsetup.ProcessForm"
- name="process_form"
- for="zope.publisher.interfaces.browser.IBrowserRequest" />
-
-<wsgi:middleware
- factory=".apps.authenticate.Authenticator"
- name="authenticate" />
-
-<wsgi:middleware
- factory=".apps.traversal.Traverser"
- name="traverse" />
-
-<wsgi:middleware
- factory=".apps.txnctl.TransactionAnnotator"
- name="annotate_transaction" />
-
-<wsgi:application
- factory=".apps.mapply.Caller"
- name="call" />
-
-</configure>
-
-
-
-<!--
- # other possible stages:
- # RequestProfiler
- # CodeFreshnessChecker
- # Multiprocessor
- # ComponentConfigurator
- # DetailedTracebackGenerator
-
- # stages we're using:
- 'logger',
- 'retry',
- 'request_factory', # also sets locale (?)
- 'root_opener',
- 'transaction_controller',
- 'error_handler',
- 'global_authenticator',
- 'traverser',
- 'transaction_annotator',
- 'caller',
--->
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/configure.zcml (from rev 96519, Sandbox/shane/republish/zope/pipeline/configure.zcml)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/configure.zcml (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/configure.zcml 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,128 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+ xmlns:wsgi="http://namespaces.zope.org/wsgi">
+
+<!-- A wsgi:pipeline directive specifies the names of
+ applications to use in a pipeline. Its implementation
+ registers a bound PipelineApplicationList.adapt() method as an
+ unnamed adapter from the request type to IPipelineApplicationList. -->
+
+<wsgi:pipeline for=".interfaces.INoRequest" names="
+ virtual_host
+ retry
+ create_request
+ switch_pipeline
+ " />
+
+<wsgi:pipeline for="zope.publisher.interfaces.IRequest" names="
+ log
+ open_root
+ control_transaction
+ event
+ handle_error
+ process_form
+ authenticate
+ traverse
+ annotate_transaction
+ fix_relative_links
+ call
+ " />
+
+<!-- A wsgi:application directive registers an application for use
+ as an application in a pipeline. If the application is the last
+ element of the pipeline, the factory will be passed no positional
+ parameters. Otherwise, the application will be passed the next
+ application in the pipeline as the only positional parameter.
+
+ The implementation of this directive registers a new
+ WSGIApplicationFactory as an adapter from a marker request to
+ IWSGIApplicationFactory. If neither the directive nor the factory
+ says what kind of request is required, assume IRequest. -->
+
+<wsgi:application
+ name="retry"
+ factory=".apps.retry.Retry"
+ for=".interfaces.INoRequest" />
+
+<wsgi:application
+ name="create_request"
+ factory=".apps.requestsetup.CreateRequest"
+ for=".interfaces.INoRequest" />
+
+<wsgi:application
+ name="switch_pipeline"
+ factory=".apps.switch.SwitchPipeline"
+ for=".interfaces.INoRequest" />
+
+
+<wsgi:application
+ name="log"
+ factory="..." />
+
+<wsgi:application
+ name="open_root"
+ factory=".apps.openroot.RootOpener" />
+
+<wsgi:application
+ name="control_transaction"
+ factory=".apps.txnctl.TransactionController" />
+
+<wsgi:application
+ name="event"
+ factory=".apps.notify.EventNotifier" />
+
+<wsgi:application
+ name="handle_error"
+ factory="..." />
+
+<!-- no form processing for non-browser requests -->
+<wsgi:application
+ name="process_form"
+ factory=".apps.passthrough"
+ for="zope.publisher.interfaces.IRequest" />
+
+<!-- process forms for browser requests -->
+<wsgi:application
+ name="process_form"
+ factory=".apps.requestsetup.ProcessForm"
+ for="zope.publisher.interfaces.browser.IBrowserRequest" />
+
+<wsgi:application
+ name="authenticate"
+ factory=".apps.authenticate.Authenticator" />
+
+<wsgi:application
+ name="traverse"
+ factory=".apps.traversal.Traverser" />
+
+<wsgi:application
+ name="annotate_transaction"
+ factory=".apps.txnctl.TransactionAnnotator" />
+
+<wsgi:application
+ name="call"
+ factory=".apps.mapply.Caller" />
+
+</configure>
+
+
+
+<!--
+ # other possible stages:
+ # RequestProfiler
+ # CodeFreshnessChecker
+ # Multiprocessor
+ # ComponentConfigurator
+ # DetailedTracebackGenerator
+
+ # stages we're using:
+ 'logger',
+ 'retry',
+ 'request_factory', # also sets locale (?)
+ 'root_opener',
+ 'transaction_controller',
+ 'error_handler',
+ 'global_authenticator',
+ 'traverser',
+ 'transaction_annotator',
+ 'caller',
+-->
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/entry.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/entry.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/entry.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,90 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""The main entry point for the zope.pipeline package.
-
-Use get_database_pipeline() or get_pipeline() to get a WSGI
-application built from a pipeline.
-"""
-
-from zope.component import getMultiAdapter
-from zope.interface import directlyProvides
-from zope.interface import providedBy
-from zope.pipeline.interfaces import IPipelineApplicationList
-from zope.pipeline.interfaces import IUndecidedRequest
-from zope.publisher import IWSGIApplication
-from zope.testing import cleanup
-
-# _pipeline_cache: {(interfaces provided by the request) -> WSGI application}
-_pipeline_cache = {}
-cleanup.addCleanUp(_pipeline_cache.clear)
-
-def get_database_pipeline(database, global_environ=None):
- """Get a pipeline that will connect to the given database.
-
- The returned pipeline can be used for many requests, even
- concurrently.
- """
- d = {}
- if global_environ is not None:
- d.update(global_environ)
- d['zope.database'] = database
- return get_pipeline(global_environ=global_environ)
-
-def get_pipeline(request=None, global_environ=None):
- """Get a pipeline.
-
- The returned pipeline can be used for many requests, even
- concurrently.
- """
- if request is None:
- provided = (IUndecidedRequest,)
- else:
- provided = tuple(providedBy(request))
- pipeline = _pipeline_cache.get(provided)
- if pipeline is None:
- pipeline = make_pipeline(provided, global_environ)
- _pipeline_cache[provided] = pipeline
- return pipeline
-
-def make_pipeline(provided, global_environ=None):
- marker_req = MarkerRequest(provided)
- app_list = IPipelineApplicationList(marker_req)
- names = list(app_list.names) # make a copy
- # The last name in the list is an application.
- name = names.pop()
- app = IWSGIApplication(marker_req, name=name)
- while names:
- # The rest of the names are middleware.
- name = names.pop()
- app = getMultiAdapter(
- (app, marker_req), IWSGIApplication, name=name)
- if global_environ:
- # augment the WSGI environment with some data
- def add_global_environ(environ, start_response):
- environ.update(global_environ)
- return inner_app(environ, start_response)
- directlyProvides(add_global_environ, IWSGIApplication)
- return add_global_environ
- else:
- return app
-
-class MarkerRequest(object):
- """A marker object that claims to provide a request type.
-
- This is used for adapter lookup.
- """
- __slots__ = ('__provides__',)
-
- def __init__(self, request_type):
- directlyProvides(self, request_type)
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/entry.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/entry.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/entry.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/entry.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,60 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""The main entry point for the zope.pipeline package.
+"""
+
+from zope.interface import directlyProvides
+from zope.pipeline.interfaces import INoRequest
+from zope.pipeline.interfaces import IPipelineApplicationList
+from zope.pipeline.interfaces import IPipelineParticipant
+from zope.pipeline.interfaces import IWSGIApplicationFactory
+
+
+def create_pipeline(params, request_provides=None):
+ """Return a pipeline as a WSGI application.
+
+ The `params` contains a mapping of application name to
+ factory keyword parameter map. An example `params` would be
+ ``{'open_root': {'database': zodb_db_object}}``.
+
+ The `request_provides` parameter varies the pipeline according
+ to the type of the `zope.request` in the WSGI environment.
+ If the WSGI environment to process has no `zope.request`, the
+ `request.provides` parameter should be None (the default).
+ """
+ if request_provides is None:
+ request_provides = (INoRequest,)
+ marker_request = MarkerRequest(request_provides)
+ app_list = IPipelineApplicationList(marker_request)
+ app = None
+ for name in reversed(app_list.names):
+ factory = IWSGIApplicationFactory(marker_request, name=name)
+ app = factory.create(name, params, app)
+ # If the app or some adapter needs to know the parameters
+ # for the whole pipeline, tell it.
+ participant = IPipelineParticipant(app, None)
+ if participant is not None:
+ participant.set_pipeline_params(app_name, params)
+ return app
+
+
+class MarkerRequest(object):
+ """A marker object that claims to provide a request type.
+
+ This is used for adapter lookup.
+ """
+ __slots__ = ('__provides__',)
+
+ def __init__(self, request_type):
+ directlyProvides(self, request_type)
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/interfaces.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/interfaces.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/interfaces.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,61 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Interfaces specific to zope.pipeline.
-
-$Id: metadirectives.py 96177 2009-02-06 07:50:13Z shane $
-"""
-
-from zope.interface import Attribute
-from zope.interface import Interface
-
-class IUndecidedRequest(Interface):
- """Indicates that no request has been created yet.
-
- Use this interface to register WSGI applications in the
- pipeline that executes before the request creation step.
- """
-
-class IPipelineApplicationList(Interface):
- """Container of a list of pipeline application names.
-
- The wsgi:pipeline directive creates an object that
- provides this interface and registers it as an adapter.
- """
- names = Attribute("Application names to use in a pipeline")
-
-class IRequestFactoryRegistry(Interface):
- """A registry of request factories.
-
- Chooses factories based on the wsgi.url_scheme, the
- REQUEST_METHOD, and the CONTENT_TYPE. Multiple factories
- can be configured schema, method, and content type.
- The factory itself can introspect the environment to decide
- if it can handle the request as given by the environment or not.
- Factories are sorted in descending order of priority, so a
- factory with priority 10 will be used before a factory with
- priority 5.
- """
-
- def register(scheme, method, mimetype, name, priority, factory):
- """Registers a factory for scheme + method + mimetype."""
-
- def get_factories_for(scheme, method, mimetype):
- """Return the internal datastructure representing the configured
- factories (basically for testing, not for introspection).
- """
-
- def lookup(method, mimetype, environment):
- """Lookup a factory for a given method+mimetype and a
- environment.
- """
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/interfaces.py (from rev 96519, Sandbox/shane/republish/zope/pipeline/interfaces.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/interfaces.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/interfaces.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,87 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Interfaces specific to zope.pipeline.
+
+$Id: metadirectives.py 96177 2009-02-06 07:50:13Z shane $
+"""
+
+from zope.interface import Attribute
+from zope.interface import Interface
+
+class INoRequest(Interface):
+ """Indicates that no Zope request has been created yet.
+
+ Use this interface to register WSGI applications in the
+ pipeline that executes before the request creation step.
+ """
+
+class IPipelineApplicationList(Interface):
+ """Container of a list of pipeline application names.
+
+ The wsgi:pipeline directive creates an object that
+ provides this interface and registers it as an adapter.
+ """
+ names = Attribute("Application names to use in a pipeline")
+
+class IWSGIApplicationFactory(Interface):
+ """Creates a WSGI application.
+
+ The two-step WSGI application creation process makes it
+ possible to pass parameters to the application constructor.
+ """
+ def create(app_name, pipeline_params, next_app=None):
+ """Create and return the application.
+
+ name is the name assigned to the application in this pipeline.
+
+ pipeline_params is a mapping of application name to parameter map.
+ In other words: {app_name: {param_name: param_value}}.
+
+ 'next_app' is the next WSGI application in the pipeline. It is
+ None when the application is the last in the pipeline.
+ """
+
+class IPipelineParticipant(Interface):
+ """Provides info for a WSGI app that needs to know about its pipeline.
+ """
+ def set_pipeline_params(app_name, pipeline_params):
+ """Tells the app about its name in the pipeline and all parameters.
+ """
+
+
+class IRequestFactoryRegistry(Interface):
+ """A registry of request factories.
+
+ Chooses factories based on the wsgi.url_scheme, the
+ REQUEST_METHOD, and the CONTENT_TYPE. Multiple factories
+ can be configured schema, method, and content type.
+ The factory itself can introspect the environment to decide
+ if it can handle the request as given by the environment or not.
+ Factories are sorted in descending order of priority, so a
+ factory with priority 10 will be used before a factory with
+ priority 5.
+ """
+
+ def register(scheme, method, mimetype, name, priority, factory):
+ """Registers a factory for scheme + method + mimetype."""
+
+ def get_factories_for(scheme, method, mimetype):
+ """Return the internal datastructure representing the configured
+ factories (basically for testing, not for introspection).
+ """
+
+ def lookup(method, mimetype, environment):
+ """Lookup a factory for a given method+mimetype and a
+ environment.
+ """
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/meta.zcml
===================================================================
--- Sandbox/shane/republish/zope/pipeline/meta.zcml 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/meta.zcml 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,31 +0,0 @@
-<configure xmlns:meta="http://namespaces.zope.org/meta">
-
-<meta:directive
- namespace="http://namespaces.zope.org/wsgi"
- name="pipeline"
- schema=".zcml.IPipelineDirective"
- handler=".zcml.pipeline"
- />
-
-<meta:directive
- namespace="http://namespaces.zope.org/wsgi"
- name="application"
- schema=".zcml.IApplicationDirective"
- handler=".zcml.application"
- />
-
-<meta:directive
- namespace="http://namespaces.zope.org/wsgi"
- name="middleware"
- schema=".zcml.IMiddlewareDirective"
- handler=".zcml.middleware"
- />
-
-<meta:directive
- namespace="http://namespaces.zope.org/wsgi"
- name="request-factory"
- schema=".zcml.IRequestFactoryDirective"
- handler=".zcml.request_factory"
- />
-
-</configure>
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/meta.zcml (from rev 96519, Sandbox/shane/republish/zope/pipeline/meta.zcml)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/meta.zcml (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/meta.zcml 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,24 @@
+<configure xmlns:meta="http://namespaces.zope.org/meta">
+
+<meta:directive
+ namespace="http://namespaces.zope.org/wsgi"
+ name="pipeline"
+ schema=".zcml.IPipelineDirective"
+ handler=".zcml.pipeline"
+ />
+
+<meta:directive
+ namespace="http://namespaces.zope.org/wsgi"
+ name="application"
+ schema=".zcml.IApplicationDirective"
+ handler=".zcml.application"
+ />
+
+<meta:directive
+ namespace="http://namespaces.zope.org/wsgi"
+ name="request-factory"
+ schema=".zcml.IRequestFactoryDirective"
+ handler=".zcml.request_factory"
+ />
+
+</configure>
Deleted: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/zcml.py
===================================================================
--- Sandbox/shane/republish/zope/pipeline/zcml.py 2009-02-13 10:53:16 UTC (rev 96490)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/zcml.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -1,192 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Schema and implementation of WSGI pipeline directives
-
-$Id: metadirectives.py 96177 2009-02-06 07:50:13Z shane $
-"""
-__docformat__ = 'restructuredtext'
-
-from zope.component import getMultiAdapter
-from zope.component.zcml import adapter
-from zope.configuration.fields import GlobalObject
-from zope.configuration.fields import Tokens
-from zope.interface import alsoProvides
-from zope.interface import Attribute
-from zope.interface import directlyProvides
-from zope.interface import Interface
-from zope.publisher.interfaces import IWSGIApplication
-from zope.publisher.interfaces import IRequest
-from zope.schema import Int
-from zope.schema import TextLine
-
-from zope.pipeline.interfaces import IPipelineApplicationList
-from zope.pipeline.apps.requestsetup import factoryRegistry
-
-
-class IPipelineDirective(Interface):
- """Declare a list of application names in a WSGI pipeline"""
-
- for_ = Tokens(
- title=u'Request types',
- description=u'The request types that should use this pipeline',
- value_type=GlobalObject(),
- required=True)
-
- names = Tokens(
- title=u'Application names',
- description=u'The list of WSGI application names to use. '
- 'The last name in the list declares a simple application; '
- 'the rest declare a middleware application.',
- required=True)
-
-
-class IApplicationDirective(Interface):
- """Declare a simple WSGI application for use at the end of a pipeline"""
-
- factory = GlobalObject(
- title=u"Application factory",
- description=(u"A factory that creates the WSGI application. "
- u"The factory will be called with no parameters."),
- required=True,
- )
-
- name = TextLine(
- title=u"Name",
- description=u"The name of the application",
- required=True,
- )
-
- for_ = Tokens(
- title=u'Request types',
- description=u'The request types that should use this application',
- value_type=GlobalObject(),
- required=False)
-
-
-class IMiddlewareDirective(IApplicationDirective):
- """Declare a middleware WSGI application for use in a pipeline"""
- factory = GlobalObject(
- title=u"Application factory",
- description=(u"A factory that creates the WSGI application. "
- u"The factory will be called with one parameter: "
- u"the next application in the pipeline."),
- required=True,
- )
-
-
-class PipelineApplicationList(object):
- implements(IPipelineApplicationList)
-
- def __init__(self, names):
- self.names = names
-
- def adapt(self, request):
- """Called by adapter lookup"""
- return self
-
-
-def pipeline(_context, for_, names):
- """Register a pipeline application list"""
- obj = PipelineApplicationList(names)
- adapter(_context, factory=obj.adapt,
- provides=[IPipelineApplicationList], for_=for_)
-
-def application(_context, factory, name, for_=()):
- """Register a simple WSGI app for use at the end of pipeline"""
- if not for_:
- for_ = [getattr(factory, 'request_type', IRequest)]
-
- def app_factory(marker_request):
- res = factory()
- if not IWSGIApplication.providedBy(res):
- alsoProvides(res, IWSGIApplication)
- return res
-
- adapter(_context, factory=[app_factory], provides=[IWSGIApplication],
- for_=for_, name=name)
-
-def middleware(_context, factory, name, for_=()):
- """Register a middleware WSGI app for use in a pipeline"""
- if not for_:
- for_ = [getattr(factory, 'request_type', IRequest)]
- for_ = [IWSGIApplication] + list(for_)
-
- def app_factory(app, marker_request):
- res = factory(app)
- if not IWSGIApplication.providedBy(res):
- alsoProvides(res, IWSGIApplication)
- return res
-
- adapter(_context, factory=[app_factory], provides=[IWSGIApplication],
- for_=for_, name=name)
-
-
-class IRequestFactoryDirective(Interface):
- """Link information from a request to a request factory"""
-
- name = TextLine(
- title=u'Name',
- description=u'The name of the request factory.')
-
- factory = GlobalObject(
- title=u'Factory',
- description=(u'The request factory, which is a callable '
- u'that accepts one parameter, the WSGI environment, '
- u'and returns a request object. '
- u'The factory can return None if it decides it can '
- u'not handle the given environment.'),
- required=True)
-
- schemes = Tokens(
- title=u'URL Schemes',
- description=(u'A list of URL schemes to support. This matches the '
- u'wsgi.url_scheme parameter. Defaults to "http https".'),
- value_type=TextLine(),
- required=False)
-
- methods = Tokens(
- title=u'Methods',
- description=(u'A list of HTTP method names. If the method is a "*", '
- u'then all methods will match. Example: "GET POST"',
- value_type=TextLine(),
- required=False)
-
- mimetypes = Tokens(
- title=u'Mime Types',
- description=(u'A list of content/mime types of the request. If the '
- u'type is a "*" then all types will be matched. '
- u'Example: "text/html text/xml"'),
- value_type=TextLine(),
- required=False)
-
- priority = Int(
- title=u'Priority',
- description=(u'A priority number used to decide between coexistent '
- u'request factories. A higher priority number '
- u'is chosen before a lower priority number.'),
- required=False)
-
-def request_factory(_context, name, factory,
- schemes=['http', 'https'], methods=['*'], mimetypes=['*'], priority=0):
-
- factory = factory()
-
- for scheme in schemes:
- for method in methods:
- for mimetype in mimetypes:
- _context.action(
- discriminator = (scheme, method, mimetype, priority),
- callable = factoryRegistry.register,
- args = (scheme, method, mimetype, name, priority, factory)
- )
Copied: Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/zcml.py (from rev 96520, Sandbox/shane/republish/zope/pipeline/zcml.py)
===================================================================
--- Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/zcml.py (rev 0)
+++ Sandbox/shane/republish/zope.pipeline/src/zope/pipeline/zcml.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,182 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Schema and implementation of WSGI pipeline directives
+
+$Id: metadirectives.py 96177 2009-02-06 07:50:13Z shane $
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.component.zcml import adapter
+from zope.configuration.fields import GlobalObject
+from zope.configuration.fields import Tokens
+from zope.interface import Interface
+from zope.publisher.interfaces import IRequest
+from zope.schema import Int
+from zope.schema import TextLine
+
+from zope.pipeline.interfaces import IPipelineApplicationList
+from zope.pipeline.interfaces import IWSGIApplicationFactory
+from zope.pipeline.apps.requestsetup import factoryRegistry
+
+
+class IPipelineDirective(Interface):
+ """Declare a list of application names in a WSGI pipeline"""
+
+ for_ = Tokens(
+ title=u'Request types',
+ description=u'The request types that should use this pipeline',
+ value_type=GlobalObject())
+
+ names = Tokens(
+ title=u'Application names',
+ description=(
+ u'The list of WSGI application names to use. '
+ u'The last name in the list declares a simple application; '
+ u'the rest declare a middleware application.'))
+
+class PipelineApplicationList(object):
+ implements(IPipelineApplicationList)
+
+ def __init__(self, names):
+ self.names = names
+
+ def adapt(self, marker_request):
+ """Called by adapter lookup"""
+ return self
+
+def pipeline(_context, for_, names):
+ """Register a pipeline application list"""
+ obj = PipelineApplicationList(names)
+ adapter(_context, factory=obj.adapt,
+ provides=[IPipelineApplicationList], for_=for_)
+
+
+
+class IApplicationDirective(Interface):
+ """Declare a WSGI application."""
+
+ name = TextLine(
+ title=u"Name",
+ description=u"The name of the application")
+
+ factory = GlobalObject(
+ title=u"Application factory",
+ description=(
+ u"A factory that creates the WSGI application. "
+ u"If the application is used in the pipeline as "
+ u"middleware, the factory will be passed a single "
+ u"positional parameter containing the next "
+ u"application in the pipeline. Other parameters "
+ u"specified for the pipeline may also be passed as "
+ u"keyword parameters."))
+
+ for_ = Tokens(
+ title=u'Request types',
+ description=u'The request types that should use this application',
+ value_type=GlobalObject(),
+ required=False)
+
+class WSGIApplicationFactory(object):
+ implements(IWSGIApplicationFactory)
+
+ def __init__(self, app_factory):
+ self.app_factory = app_factory
+
+ def adapt(self, marker_request):
+ """Called by adapter lookup"""
+ return self
+
+ def create(self, app_name, pipeline_params, next_app=None):
+ kw = pipeline_params.get(app_name)
+ if kw is None:
+ kw = {}
+ if next_app is not None:
+ # middleware
+ app = self.app_factory(next_app, **kw)
+ else:
+ # final app
+ app = self.app_factory(**kw)
+ return app
+
+def application(_context, factory, name, for_=()):
+ """Register a WSGI application"""
+ if not for_:
+ for_ = [IRequest]
+ factory_factory = WSGIApplicationFactory(factory)
+ adapter(_context,
+ factory=[factory_factory.adapt],
+ provides=[IWSGIApplicationFactory],
+ for_=for_, name=name)
+
+
+
+
+class IRequestFactoryDirective(Interface):
+ """Link information from a request to a request factory"""
+
+ name = TextLine(
+ title=u'Name',
+ description=u'The name of the request factory.')
+
+ factory = GlobalObject(
+ title=u'Factory',
+ description=(u'The request factory, which is a callable '
+ u'that accepts one parameter, the WSGI environment, '
+ u'and returns a request object. '
+ u'The factory can return None if it decides it can '
+ u'not handle the given environment.'),
+ required=True)
+
+ schemes = Tokens(
+ title=u'URL Schemes',
+ description=(u'A list of URL schemes to support. This matches the '
+ u'wsgi.url_scheme parameter. Defaults to "http https".'),
+ value_type=TextLine(),
+ required=False)
+
+ methods = Tokens(
+ title=u'Methods',
+ description=(u'A list of HTTP method names. If the method is a "*", '
+ u'then all methods will match. Example: "GET POST"',
+ value_type=TextLine(),
+ required=False)
+
+ mimetypes = Tokens(
+ title=u'Mime Types',
+ description=(u'A list of content/mime types of the request. If the '
+ u'type is a "*" then all types will be matched. '
+ u'Example: "text/html text/xml"'),
+ value_type=TextLine(),
+ required=False)
+
+ priority = Int(
+ title=u'Priority',
+ description=(u'A priority number used to decide between coexistent '
+ u'request factories. A higher priority number '
+ u'is chosen before a lower priority number.'),
+ required=False)
+
+def request_factory(_context, name, factory,
+ schemes=['http', 'https'], methods=['*'], mimetypes=['*'], priority=0):
+
+ factory = factory()
+
+ for scheme in schemes:
+ for method in methods:
+ for mimetype in mimetypes:
+ _context.action(
+ discriminator = (scheme, method, mimetype, priority),
+ callable = factoryRegistry.register,
+ args = (scheme, method, mimetype, name, priority, factory)
+ )
Copied: Sandbox/shane/republish/zope.publisher/src/zope/__init__.py (from rev 96490, Sandbox/shane/republish/zope/__init__.py)
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/__init__.py (rev 0)
+++ Sandbox/shane/republish/zope.publisher/src/zope/__init__.py 2009-02-14 20:51:18 UTC (rev 96547)
@@ -0,0 +1,7 @@
+# this is a namespace package
+try:
+ import pkg_resources
+ pkg_resources.declare_namespace(__name__)
+except ImportError:
+ import pkgutil
+ __path__ = pkgutil.extend_path(__path__, __name__)
Property changes on: Sandbox/shane/republish/zope.publisher/src/zope/__init__.py
___________________________________________________________________
Added: svn:mergeinfo
+
Property changes on: Sandbox/shane/republish/zope.publisher/src/zope/publisher
___________________________________________________________________
Added: svn:mergeinfo
+
More information about the Checkins
mailing list