repoze.zope2 predates the inclusion of ZPublisher.pubevents in Zope 2, so it does
not notify the relevant events.
The following patch attempts to add them, though some are a bit hard to place
since they relate to transactions. Sorry, no tests at this point.
Note: for reasons of laziness, this patch also includes a fix for
accumulated_headers (it's a list, not a string in Zope 2.13 at least) and the fix to
issue #64.
Index: repoze/zope2/z2bob.py
=============================================================
======
--- repoze/zope2/z2bob.py (revision 11017)
+++ repoze/zope2/z2bob.py (working copy)
@@ -51,6 +51,9 @@
from ZPublisher.BaseRequest import UNSPECIFIED_ROLES
from ZPublisher.xmlrpc import Response as XMLRPCResponse
+from zope.event import notify
+from ZPublisher.pubevents import PubStart, PubSuccess, PubFailure,
PubBeforeCommit, PubAfterTraversal, PubBeforeAbort
+
from zExceptions import Unauthorized
from zExceptions import Redirect
@@ -141,6 +144,7 @@
self.traversed = []
self.default_page = 'index_html'
self.vroot_stack = None
+ self.error = False
def _configure(self, config):
self._config = config
@@ -169,6 +173,9 @@
request = makeRequest(self.environ)
request._resetURLS()
request.no_acquire_flag = False
+
+ notify(PubStart(request))
+
setDefaultSkin(request) # analogue of Publish.publish_module_standard
newInteraction() # analogue of Publish.publish
request.processInputs() # analogue of Publish.publish
@@ -228,6 +235,11 @@
self.request = request
def teardown(self):
+
+ if not self.error:
+ # XXX: This should really be after the transaction is committed
+ notify(PubSuccess(self.request))
+
endInteraction()
if self.request is not None:
# if there was not an error during setup()
@@ -313,6 +325,10 @@
# around the reversed-order bug will lose, sorry.
self.browser_default = True
default_page = path[-1]
+ else:
+ # Faux traversal, as we won't return a name so traversal will
+ # stop
+ parents.append(default)
# we need to check if we actually have a default page in
# next_name because if we try to do it in traverse, if we
@@ -398,12 +414,17 @@
return ob2
def before_invoke(self, published):
+
request = self.request
+
+ notify(PubAfterTraversal(request))
+
parents = request['PARENTS']
# We use request.PARENTS in favor of the passed-in "published"
# object to account for the fact that before_traverse code and
# our next_name method mutates the parents list to insert the
# published object
+
published = parents.pop()
# NB: it's important to reverse the parents list, or legacy VHM
@@ -447,6 +468,7 @@
# we ignore the published that gets passed in; we've set the
# actual published object in the request within before_invoke
request = self.request
+
published = request['PUBLISHED']
result = mapply(published,
positional = request.args,
@@ -554,10 +576,17 @@
result = [result]
headers = self._getResponseHeaders()
+
+ notify(PubBeforeCommit(request))
+
return status, headers, result
def handle_exception(self, exc_info):
+ self.error = True
t, v, tb = exc_info
+
+ notify(PubBeforeAbort(self.request, exc_info, self.request.supports_retry()))
+
try:
if ((t == 'Unauthorized') or
(inspect.isclass(t) and issubclass(t, _UNAUTH_CLASSES))):
@@ -581,6 +610,9 @@
finally:
del tb # no memory leak
+
+ # XXX: This should happen after transaction abort
+ notify(PubFailure(self.request, exc_info, self.request.supports_retry()))
# helper methods
@@ -617,7 +649,10 @@
def _getAccumulatedHeaders(self):
accumulated_headers = self.request.response.accumulated_headers
L = []
- more_headers = accumulated_headers.split('\n')
+ if isinstance(accumulated_headers, basestring):
+ more_headers = accumulated_headers.split('\n')
+ else:
+ more_headers = accumulated_headers
for line in more_headers:
if ':' in line:
name, value = [ x.strip() for x in line.split(':', 1) ]
|