[Zope-Checkins]
SVN: Zope/branches/publication-refactor/lib/python/ZPublisher/
Replace the ZPublisher.Publish.publish method with the
Michael Kerrin
michael.kerrin at openapp.biz
Thu Apr 20 12:18:17 EDT 2006
Log message for revision 67177:
Replace the ZPublisher.Publish.publish method with the
Zope3 equivalent zope.publisher.publish. This way the
publish_module_standard and similar are just wrappers
around the Zope3 method that sets up the request correctly
and performs some other stuff I don't quite follow.
There is still a lot of work left, for example 11 tests are
still failing but we can get back to these later.
Changed:
U Zope/branches/publication-refactor/lib/python/ZPublisher/BaseRequest.py
U Zope/branches/publication-refactor/lib/python/ZPublisher/BaseResponse.py
U Zope/branches/publication-refactor/lib/python/ZPublisher/HTTPResponse.py
U Zope/branches/publication-refactor/lib/python/ZPublisher/Publication.py
U Zope/branches/publication-refactor/lib/python/ZPublisher/Publish.py
U Zope/branches/publication-refactor/lib/python/ZPublisher/Test.py
U Zope/branches/publication-refactor/lib/python/ZPublisher/tests/testPublish.py
-=-
Modified: Zope/branches/publication-refactor/lib/python/ZPublisher/BaseRequest.py
===================================================================
--- Zope/branches/publication-refactor/lib/python/ZPublisher/BaseRequest.py 2006-04-20 15:19:17 UTC (rev 67176)
+++ Zope/branches/publication-refactor/lib/python/ZPublisher/BaseRequest.py 2006-04-20 16:18:16 UTC (rev 67177)
@@ -249,10 +249,6 @@
if not path and not method:
return response.forbiddenError(self['URL'])
- if self.publication.root is not object:
- self.publication.root = object
-
- object = self.publication.getApplication(self)
roles = getRoles(None, None, object, UNSPECIFIED_ROLES)
parents.append(object)
Modified: Zope/branches/publication-refactor/lib/python/ZPublisher/BaseResponse.py
===================================================================
--- Zope/branches/publication-refactor/lib/python/ZPublisher/BaseResponse.py 2006-04-20 15:19:17 UTC (rev 67176)
+++ Zope/branches/publication-refactor/lib/python/ZPublisher/BaseResponse.py 2006-04-20 16:18:16 UTC (rev 67177)
@@ -54,6 +54,10 @@
"""Output the response body"""
self.stdout.write(str(self))
+ def setResult(self, result):
+ """IResponse"""
+ self.setBody(result)
+
def setBody(self, body):
self.body = body
Modified: Zope/branches/publication-refactor/lib/python/ZPublisher/HTTPResponse.py
===================================================================
--- Zope/branches/publication-refactor/lib/python/ZPublisher/HTTPResponse.py 2006-04-20 15:19:17 UTC (rev 67176)
+++ Zope/branches/publication-refactor/lib/python/ZPublisher/HTTPResponse.py 2006-04-20 16:18:16 UTC (rev 67177)
@@ -180,6 +180,10 @@
self.stdout = stdout
self.stderr = stderr
+ def internalError(self):
+ 'See IPublisherResponse'
+ self.setStatus(500, u"The engines can't take any more, Jim!")
+
def retry(self):
"""Return a response object to be used in a retry attempt
"""
Modified: Zope/branches/publication-refactor/lib/python/ZPublisher/Publication.py
===================================================================
--- Zope/branches/publication-refactor/lib/python/ZPublisher/Publication.py 2006-04-20 15:19:17 UTC (rev 67176)
+++ Zope/branches/publication-refactor/lib/python/ZPublisher/Publication.py 2006-04-20 16:18:16 UTC (rev 67177)
@@ -15,12 +15,14 @@
import re
import sys
import transaction
+import types
from zope.event import notify
from zope.component import queryUtility
from zope.interface import implements
from zope.publisher.interfaces import IRequest, IPublication
from zope.publisher.interfaces import NotFound, IPublicationRequest
+import zope.publisher.interfaces
from zope.publisher.browser import BrowserRequest
from zope.publisher.browser import BrowserResponse
from zope.publisher.http import StrResult
@@ -35,14 +37,42 @@
from ZPublisher.mapply import mapply
from ZPublisher.BaseRequest import RequestContainer
+from ZPublisher.HTTPRequest import HTTPRequest
+from ZPublisher.HTTPResponse import HTTPResponse
+from cStringIO import StringIO
+import traceback
+from zope.publisher.http import status_reasons, DirectResult
+from zope.publisher.interfaces import IPublisherRequest
+from zope import component
+
+
_marker = object()
+class Zope3HTTPRequestTraverser(object):
+ implements(IPublisherRequest)
+
+ def __init__(self, request):
+ self.request = request
+
+ def traverse(self, object):
+ path = self.request.get('PATH_INFO')
+ self.request['PARENTS'] = [object]
+
+ return self.request.traverse(path, self.request.response,
+ self.request.publication.validated_hook)
+
+## XXX - Five declares that HTTPRequest implements IPublisherRequest
+## but in fact it doesn't, the traverse method API is all wrong.
+## component.provideAdapter(Zope3HTTPRequestTraverser, (HTTPRequest,),
+## IPublisherRequest)
+
+
class ZopePublication(object):
"""Base Zope2 publication specification.
"""
implements(IPublication)
- def __init__(self, db=None, module_name="Zope2"):
+ def __init__(self, db = None, module_name = "Zope2"):
# db is a ZODB.DB.DB object.
# XXX We don't use this yet.
self.db = db
@@ -58,6 +88,18 @@
self.transactions_manager) = get_module_info(self.module_name)
def beforeTraversal(self, request):
+ # First check for "cancel" redirect:
+ if request.get('SUBMIT','').strip().lower()=='cancel':
+ # XXX Deprecate this, the Zope 2+3 publication won't support it.
+ cancel = request.get('CANCEL_ACTION','')
+ if cancel:
+ raise Redirect, cancel
+
+ if self.debug_mode:
+ request.response.debug_mode = self.debug_mode
+ if self.realm and not request.get('REMOTE_USER', None):
+ request.response.realm = self.realm
+
# First part of old ZPublisher.Publish.publish. Call
# 'bobo_before' hooks and start a new transaction using the
# 'transaction_manager'.
@@ -121,8 +163,9 @@
result = mapply(ob, args,
request, call_object, 1, missing_name,
dont_publish_class, request, bind=1)
- if isinstance(request, Zope2BrowserRequest):
- return StrResult(str(result))
+ ## XXX - what the hell is this.
+ ## if isinstance(request, Zope2BrowserRequest):
+ ## return StrResult(str(result))
return result
def afterCall(self, request, ob):
@@ -152,6 +195,18 @@
self.transactions_manager.abort()
def handleException(self, object, request, exc_info, retry_allowed=True):
+ if isinstance(object, types.ListType):
+ object = object[0]
+
+ # DM: provide nicer error message for FTP
+ sm = getattr(request.response, "setMessage", None)
+ if sm is not None:
+ from asyncore import compact_traceback
+ cl,val= sys.exc_info()[:2]
+ sm('%s: %s %s' % (
+ getattr(cl,'__name__',cl), val,
+ debug_mode and compact_traceback()[-1] or ''))
+
# Some exception handling from ZPublisher.Publish.publish().
if self.err_hook is None:
self._abort()
@@ -165,9 +220,9 @@
exc_info[1],
exc_info[2],
)
- except Retry:
+ except Retry, retry_exception:
if retry_allowed:
- raise
+ raise zope.publisher.interfaces.Retry(sys.exc_info)
return self.err_hook(object, request,
sys.exc_info()[0],
sys.exc_info()[1],
@@ -244,168 +299,7 @@
module_name=module_name)
return _publications[module_name]
-tr = {'environ': '_environ',
- 'TraversalRequestNameStack': '_traversal_stack',
- 'RESPONSE': 'response'}
-class Zope2BrowserResponse(BrowserResponse):
-
- def badRequestError(self, name):
- raise KeyError, name
-
- def _headers(self):
- return dict(self.getHeaders())
-
- headers = property(_headers)
-
-class Zope2BrowserRequest(BrowserRequest):
-
- # Zope 2 compatibility XXX Deprecate!
- def get_header(self, name, default=None):
- return self.getHeader(name, default)
-
- def __init__(self, *args, **kw):
- self.other = {'PARENTS':[]}
- self._lazies = {}
- self._file = None
- self._urls = []
- BrowserRequest.__init__(self, *args, **kw)
-
- def _createResponse(self):
- return Zope2BrowserResponse()
-
- def set_lazy(self, name, func):
- self._lazies[name] = func
-
- _hold = BrowserRequest.hold
-
- def __getitem__(self, key, default=_marker):
- v = self.get(key, default)
- if v is _marker:
- raise KeyError, key
- return v
-
- def __getattr__(self, key, default=_marker):
- v = self.get(key, default)
- if v is _marker:
- raise AttributeError, key
- return v
-
- def traverse(self, object):
- ob = super(Zope2BrowserRequest, self).traverse(object)
- self.other['PARENTS'].append(ob)
- return ob
-
- def set(self, key, value):
- self.other[key] = value
-
- def get(self, key, default=None, returnTaints=0,
- URLmatch=re.compile('URL(PATH)?([0-9]+)$').match,
- BASEmatch=re.compile('BASE(PATH)?([0-9]+)$').match,
- ):
- """Get a variable value
-
- Return a value for the required variable name.
- The value will be looked up from one of the request data
- categories. The search order is environment variables,
- other variables, form data, and then cookies.
-
- """
- from ZPublisher.HTTPRequest import isCGI_NAME, hide_key
-
- if (key in ('other', '_file',
- '_lazies', '_urls') or tr.has_key(key)):
- key = tr.get(key, key)
- return object.__getattribute__(self, key)
-
- if key == 'REQUEST': return self
-
- other = self.other
- if other.has_key(key):
- return other[key]
-
- if key[:1]=='U':
- match = URLmatch(key)
- if match is not None:
- pathonly, n = match.groups()
- path = self._traversed_names
- n = len(path) - int(n)
- if n < 0:
- raise KeyError, key
- if pathonly:
- path = [''] + path[:n]
- else:
- path = [self['SERVER_URL']] + path[:n]
- URL = '/'.join(path)
- if other.has_key('PUBLISHED'):
- # Don't cache URLs until publishing traversal is done.
- other[key] = URL
- self._urls = self._urls + (key,)
- return URL
-
- if isCGI_NAME(key) or key[:5] == 'HTTP_':
- environ = self.environ
- if environ.has_key(key) and (not hide_key(key)):
- return environ[key]
- return ''
-
- if key[:1]=='B':
- match = BASEmatch(key)
- if match is not None:
- pathonly, n = match.groups()
- path = self._traversed_names
- n = int(n)
- if n:
- n = n - 1
- if len(path) < n:
- raise KeyError, key
-
- v = path[:n]
- else:
- v = ['']
- if pathonly:
- v.insert(0, '')
- else:
- v.insert(0, other['SERVER_URL'])
- URL = '/'.join(v)
- if other.has_key('PUBLISHED'):
- # Don't cache URLs until publishing traversal is done.
- other[key] = URL
- self._urls = self._urls + (key,)
- return URL
-
- if key=='BODY' and self._file is not None:
- p=self._file.tell()
- self._file.seek(0)
- v=self._file.read()
- self._file.seek(p)
- self.other[key]=v
- return v
-
- if key=='BODYFILE' and self._file is not None:
- v=self._file
- self.other[key]=v
- return v
-
- if self._lazies:
- v = self._lazies.get(key, _marker)
- if v is not _marker:
- if callable(v): v = v()
- self[key] = v # Promote lazy value
- del self._lazies[key]
- return v
-
- v = super(Zope2BrowserRequest, self).get(key, _marker)
- if v is not _marker: return v
-
- return default
-
-from ZPublisher.HTTPRequest import HTTPRequest
-from ZPublisher.HTTPResponse import HTTPResponse
-from cStringIO import StringIO
-import traceback
-from zope.publisher.http import status_reasons, DirectResult
-
class Zope2HTTPResponse(HTTPResponse):
def setResult(self, result):
@@ -429,20 +323,6 @@
'See IPublisherResponse'
self.setStatus(500, u"The engines can't take any more, Jim!")
- def reset(self):
- """Reset the output result.
-
- Reset the response by nullifying already set variables.
- """
- raise Exception
-
- def retry(self):
- """Returns a retry response
-
- Returns a response suitable for repeating the publication attempt.
- """
- raise Exception
-
def getStatusString(self):
'See IHTTPResponse'
return '%i %s' % (self.status, status_reasons[self.status])
@@ -455,19 +335,20 @@
class Zope2HTTPRequest(HTTPRequest):
-
+
def supportsRetry(self):
return False
-
+
def traverse(self, object):
path = self.get('PATH_INFO')
self['PARENTS'] = [self.publication.root]
+
return HTTPRequest.traverse(self, path)
def Zope2RequestFactory(sin, env):
response=Zope2HTTPResponse()
- return Zope2HTTPRequest(sin, env, response)
+ return HTTPRequest(sin, env, response)
class Zope2HTTPFactory(object):
@@ -477,5 +358,4 @@
return True
def __call__(self):
-
return Zope2RequestFactory, ZopePublication
Modified: Zope/branches/publication-refactor/lib/python/ZPublisher/Publish.py
===================================================================
--- Zope/branches/publication-refactor/lib/python/ZPublisher/Publish.py 2006-04-20 15:19:17 UTC (rev 67176)
+++ Zope/branches/publication-refactor/lib/python/ZPublisher/Publish.py 2006-04-20 16:18:16 UTC (rev 67177)
@@ -164,42 +164,50 @@
status=200
after_list=[None]
try:
- try:
- if response is None:
- response=Response(stdout=stdout, stderr=stderr)
- else:
- stdout=response.stdout
+ if response is None:
+ response=Response(stdout=stdout, stderr=stderr)
+ else:
+ stdout=response.stdout
- if request is None:
- request=Request(stdin, environ, response)
+ if request is None:
+ request=Request(stdin, environ, response)
- response = publish(request, module_name, after_list, debug=debug)
- except SystemExit, v:
+ # We assume the publication object returned is the one in
+ # ZPublisher.Publication here so we don't bother using accessors
+ # and poke directly into the variables.
+ from ZPublisher.Publication import get_publication
+ publication = get_publication(module_name)
+ request.setPublication(publication)
+
+ from zope.publisher.publish import publish as publish3
+ publish3(request)
+ except SystemExit, v:
+ must_die=sys.exc_info()
+ request.response.exception(must_die)
+ except ImportError, v:
+ if isinstance(v, tuple) and len(v) == 3:
+ must_die=v
+ elif hasattr(sys, 'exc_info'):
must_die=sys.exc_info()
- request.response.exception(must_die)
- except ImportError, v:
- if isinstance(v, tuple) and len(v)==3: must_die=v
- elif hasattr(sys, 'exc_info'): must_die=sys.exc_info()
- else: must_die = SystemExit, v, sys.exc_info()[2]
- request.response.exception(1, v)
- except:
- request.response.exception()
- status=response.getStatus()
+ else:
+ must_die = SystemExit, v, sys.exc_info()[2]
+ request.response.exception(1, v)
+ except:
+ request.response.exception()
+ status=response.getStatus()
- if response:
- outputBody=getattr(response, 'outputBody', None)
- if outputBody is not None:
- outputBody()
- else:
- response=str(response)
- if response: stdout.write(response)
+ if request.response:
+ outputBody=getattr(request.response, 'outputBody', None)
+ if outputBody is not None:
+ outputBody()
+ else:
+ response=str(request.response)
+ if response:
+ stdout.write(response)
# The module defined a post-access function, call it
if after_list[0] is not None: after_list[0]()
- finally:
- if request is not None: request.close()
-
if must_die:
# Try to turn exception value into an exit code.
try:
Modified: Zope/branches/publication-refactor/lib/python/ZPublisher/Test.py
===================================================================
--- Zope/branches/publication-refactor/lib/python/ZPublisher/Test.py 2006-04-20 15:19:17 UTC (rev 67176)
+++ Zope/branches/publication-refactor/lib/python/ZPublisher/Test.py 2006-04-20 16:18:16 UTC (rev 67177)
@@ -180,39 +180,39 @@
after_list=[None]
from Response import Response
from Request import Request
- from Publish import publish
+ from Publication import get_publication
+ # from Publish import publish
+ from zope.publisher.publish import publish
try:
- try:
- if response is None:
- response=Response(stdout=stdout, stderr=stderr)
- else:
- stdout=response.stdout
- if request is None:
- request=Request(stdin, environ, response)
- for k, v in extra.items(): request[k]=v
- response = publish(request, module_name, after_list, debug=debug)
- except SystemExit, v:
- must_die=sys.exc_info()
- response.exception(must_die)
- except ImportError, v:
- if isinstance(v, TupleType) and len(v)==3: must_die=v
- else: must_die=sys.exc_info()
- response.exception(1, v)
- except:
- if debug:
- raise
- response.exception()
- status=response.getStatus()
- if response:
- response=str(response)
- if response: stdout.write(response)
+ if response is None:
+ response=Response(stdout=stdout, stderr=stderr)
+ else:
+ stdout=response.stdout
+ if request is None:
+ request=Request(stdin, environ, response)
+ request.setPublication(get_publication())
+ for k, v in extra.items(): request[k]=v
+ response = request.response
+ publish(request) #, module_name, after_list, debug=debug)
+ except SystemExit, v:
+ must_die=sys.exc_info()
+ response.exception(must_die)
+ except ImportError, v:
+ if isinstance(v, TupleType) and len(v)==3: must_die=v
+ else: must_die=sys.exc_info()
+ response.exception(1, v)
+ except:
+ if debug:
+ raise
+ response.exception()
+ status=response.getStatus()
+ if response:
+ response=str(response)
+ if response: stdout.write(response)
- # The module defined a post-access function, call it
- if after_list[0] is not None: after_list[0]()
+ # The module defined a post-access function, call it
+ if after_list[0] is not None: after_list[0]()
- finally:
- if request is not None: request.close()
-
if must_die:
try: raise must_die[0], must_die[1], must_die[2]
finally: must_die=None
Modified: Zope/branches/publication-refactor/lib/python/ZPublisher/tests/testPublish.py
===================================================================
--- Zope/branches/publication-refactor/lib/python/ZPublisher/tests/testPublish.py 2006-04-20 15:19:17 UTC (rev 67176)
+++ Zope/branches/publication-refactor/lib/python/ZPublisher/tests/testPublish.py 2006-04-20 16:18:16 UTC (rev 67177)
@@ -79,9 +79,21 @@
"""Mock Response to replace ZPublisher.HTTPResponse.HTTPResponse.
"""
+ def internalError(self):
+ 'See IPublisherResponse'
+ self.setStatus(500, u"The engines can't take any more, Jim!")
+
+ def setStatus(self, status, reason):
+ self.status = status
+
def setBody(self, a):
pass
+ def exception(self, fatal = 0, info = None):
+ pass
+
+ setResult = setBody
+
class Request:
"""Mock Request to replace ZPublisher.HTTPRequest.HTTPRequest.
"""
@@ -90,6 +102,8 @@
def __init__(self):
self.response = Response()
+ from ZPublisher.Publication import get_publication
+ self.publication = get_publication('ZPublisher.tests.testPublish')
def setPublication(self, publication):
self.publication = publication
@@ -103,7 +117,7 @@
def __setitem__(self, name, value):
pass
- def traverse(self, path, validated_hook):
+ def traverse(self, path, response = None, validated_hook = None):
return Object()
def close(self):
@@ -115,6 +129,8 @@
def supports_retry(self):
return self.retry_count < self.retry_max_count
+ supportsRetry = supports_retry
+
def retry(self):
self.retry_count += 1
r = self.__class__()
@@ -130,14 +146,14 @@
Tests to ensure that the ZPublisher correctly manages the ZODB
transaction boundaries.
- >>> from ZPublisher.Publish import publish
+ >>> from zope.publisher.publish import publish
ZPublisher will commit the transaction after it has made a
rendering of the object.
>>> tracer.reset()
>>> request = Request()
- >>> response = publish(request, module_name, after_list)
+ >>> response = publish(request)
>>> tracer.showTracedPath()
begin
__call__
@@ -153,7 +169,7 @@
>>> tracer.reset()
>>> tracer.exceptions['__call__'] = [ValueError]
>>> request = Request()
- >>> response = publish(request, module_name, after_list)
+ >>> response = publish(request)
>>> tracer.showTracedPath()
begin
__call__
@@ -169,7 +185,7 @@
>>> tracer.exceptions['__call__'] = [ValueError]
>>> tracer.exceptions['zpublisher_exception_hook'] = [ValueError]
>>> request = Request()
- >>> response = publish(request, module_name, after_list)
+ >>> response = publish(request, False)
Traceback (most recent call last):
...
ValueError
@@ -190,7 +206,7 @@
>>> tracer.reset()
>>> tracer.exceptions['__call__'] = [ConflictError]
>>> request = Request()
- >>> response = publish(request, module_name, after_list)
+ >>> response = publish(request)
>>> tracer.showTracedPath()
begin
__call__
@@ -207,7 +223,7 @@
>>> tracer.reset()
>>> tracer.exceptions['commit'] = [ConflictError]
>>> request = Request()
- >>> response = publish(request, module_name, after_list)
+ >>> response = publish(request)
>>> tracer.showTracedPath()
begin
__call__
@@ -225,7 +241,7 @@
>>> tracer.exceptions['__call__'] = [ConflictError, ConflictError,
... ConflictError, ConflictError]
>>> request = Request()
- >>> response = publish(request, module_name, after_list)
+ >>> response = publish(request, False)
Traceback (most recent call last):
...
ConflictError: database conflict error
@@ -254,7 +270,7 @@
>>> tracer.exceptions['__call__'] = [ValueError]
>>> tracer.exceptions['zpublisher_exception_hook'] = [ConflictError]
>>> request = Request()
- >>> response = publish(request, module_name, after_list)
+ >>> response = publish(request, False)
Traceback (most recent call last):
...
ConflictError: database conflict error
More information about the Zope-Checkins
mailing list