[Zope-Checkins] SVN: Zope/branches/publication-refactor/lib/python/
- Another checkpoint. Enough majik to render the quickstart
page, not much else.
Sidnei da Silva
sidnei at enfoldsystems.com
Tue Dec 13 19:10:46 EST 2005
Log message for revision 40775:
- Another checkpoint. Enough majik to render the quickstart page, not much else.
Changed:
_U Zope/branches/publication-refactor/lib/python/
U Zope/branches/publication-refactor/lib/python/Products/Five/configure.zcml
U Zope/branches/publication-refactor/lib/python/Products/Five/meta.zcml
U Zope/branches/publication-refactor/lib/python/ZPublisher/Publication.py
U Zope/branches/publication-refactor/lib/python/Zope2/Startup/__init__.py
U Zope/branches/publication-refactor/lib/python/Zope2/Startup/handlers.py
U Zope/branches/publication-refactor/lib/python/Zope2/Startup/zopeschema.xml
-=-
Property changes on: Zope/branches/publication-refactor/lib/python
___________________________________________________________________
Name: svn:externals
- ZConfig svn://svn.zope.org/repos/main/ZConfig/tags/ZConfig-2.3.1
BTrees svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/BTrees
persistent svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/persistent
ThreadedAsync svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/ThreadedAsync
transaction svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/transaction
ZEO svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/ZEO
ZODB svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/ZODB
ZopeUndo svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/ZopeUndo
zdaemon -r 39732 svn://svn.zope.org/repos/main/zdaemon/trunk/src/zdaemon
pytz -r 40549 svn://svn.zope.org/repos/main/Zope3/trunk/src/pytz
zodbcode -r 40549 svn://svn.zope.org/repos/main/Zope3/trunk/src/zodbcode
ClientCookie -r 40549 svn://svn.zope.org/repos/main/Zope3/trunk/src/ClientCookie
mechanize -r 40549 svn://svn.zope.org/repos/main/Zope3/trunk/src/mechanize
+ ZConfig svn://svn.zope.org/repos/main/ZConfig/tags/ZConfig-2.3.1
BTrees svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/BTrees
persistent svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/persistent
ThreadedAsync svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/ThreadedAsync
transaction svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/transaction
ZEO svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/ZEO
ZODB svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/ZODB
ZopeUndo svn://svn.zope.org/repos/main/ZODB/tags/3.6.0b4/src/ZopeUndo
zdaemon -r 39732 svn://svn.zope.org/repos/main/zdaemon/trunk/src/zdaemon
pytz -r 40549 svn://svn.zope.org/repos/main/Zope3/trunk/src/pytz
zodbcode -r 40549 svn://svn.zope.org/repos/main/Zope3/trunk/src/zodbcode
ClientCookie -r 40549 svn://svn.zope.org/repos/main/Zope3/trunk/src/ClientCookie
mechanize -r 40549 svn://svn.zope.org/repos/main/Zope3/trunk/src/mechanize
twisted svn://svn.twistedmatrix.com/svn/Twisted/branches/releases/2.1.x/twisted
Modified: Zope/branches/publication-refactor/lib/python/Products/Five/configure.zcml
===================================================================
--- Zope/branches/publication-refactor/lib/python/Products/Five/configure.zcml 2005-12-13 17:56:02 UTC (rev 40774)
+++ Zope/branches/publication-refactor/lib/python/Products/Five/configure.zcml 2005-12-14 00:10:45 UTC (rev 40775)
@@ -15,6 +15,14 @@
<include package="zope.app.event" />
<include package="zope.app.traversing" />
+ <publisher
+ name="Zope2-HTTP"
+ factory="ZPublisher.Publication.Zope2HTTPFactory"
+ methods="*"
+ mimetypes="*"
+ priority="0"
+ />
+
<!-- do 'traditional' traversing by default; needed by ZPT -->
<adapter
for="*"
Modified: Zope/branches/publication-refactor/lib/python/Products/Five/meta.zcml
===================================================================
--- Zope/branches/publication-refactor/lib/python/Products/Five/meta.zcml 2005-12-13 17:56:02 UTC (rev 40774)
+++ Zope/branches/publication-refactor/lib/python/Products/Five/meta.zcml 2005-12-14 00:10:45 UTC (rev 40775)
@@ -172,4 +172,7 @@
<!-- load the i18n:registerTranslations directive -->
<include package="zope.app.i18n" file="meta.zcml" />
+ <!-- load the zope:publisher directive -->
+ <include package="zope.app.publication" file="meta.zcml" />
+
</configure>
Modified: Zope/branches/publication-refactor/lib/python/ZPublisher/Publication.py
===================================================================
--- Zope/branches/publication-refactor/lib/python/ZPublisher/Publication.py 2005-12-13 17:56:02 UTC (rev 40774)
+++ Zope/branches/publication-refactor/lib/python/ZPublisher/Publication.py 2005-12-14 00:10:45 UTC (rev 40775)
@@ -12,14 +12,22 @@
##############################################################################
__version__='$Revision$'[11:-2]
+import re
import sys
import transaction
+
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
+from zope.publisher.browser import BrowserRequest
+from zope.publisher.browser import BrowserResponse
+from zope.publisher.http import StrResult
from zope.app.publication.interfaces import EndRequestEvent
from zope.app.publication.interfaces import BeforeTraverseEvent
+from zope.app.publication.interfaces import IBrowserRequestFactory
+from zope.app.publication.interfaces import IRequestPublicationFactory
from ZPublisher.Publish import Retry
from ZPublisher.Publish import get_module_info, call_object
@@ -27,6 +35,8 @@
from ZPublisher.mapply import mapply
from ZPublisher.BaseRequest import RequestContainer
+_marker = object()
+
class ZopePublication(object):
"""Base Zope2 publication specification.
"""
@@ -83,11 +93,7 @@
# If the top object has a __bobo_traverse__ method, then use it
# to possibly traverse to an alternate top-level object.
if hasattr(ob, '__bobo_traverse__'):
- try:
- ob = ob.__bobo_traverse__(request)
- except:
- # XXX Blind except? Yuck!
- pass
+ ob = ob.__bobo_traverse__(request)
if hasattr(ob, '__of__'):
# Try to bind the top-level object to the request
@@ -109,9 +115,12 @@
else:
# It's a Zope 2 request.
args = request.args
- return mapply(ob, args,
- request, call_object, 1, missing_name,
- dont_publish_class, request, bind=1)
+ result = mapply(ob, args,
+ request, call_object, 1, missing_name,
+ dont_publish_class, request, bind=1)
+ if isinstance(request, Zope2BrowserRequest):
+ return StrResult(str(result))
+ return result
def afterCall(self, request, ob):
# Last part of ZPublisher.Publish.{publish, publish_module_standard},
@@ -154,12 +163,13 @@
exc_info[2],
)
except Retry:
- if not retry_allowed:
- return self.err_hook(object, request,
- sys.exc_info()[0],
- sys.exc_info()[1],
- sys.exc_info()[2],
- )
+ if retry_allowed:
+ raise
+ return self.err_hook(object, request,
+ sys.exc_info()[0],
+ sys.exc_info()[1],
+ sys.exc_info()[2],
+ )
finally:
self._abort()
@@ -213,6 +223,13 @@
TypeError, AttributeError):
raise NotFound(ob, name)
+ def getDefaultTraversal(self, request, ob):
+ if hasattr(ob, '__browser_default__'):
+ return object.__browser_default__(request)
+ if getattr(ob, 'index_html', None):
+ return ob, ['index_html']
+ return ob, []
+
_publications = {}
def get_publication(module_name=None):
if module_name is None:
@@ -221,3 +238,166 @@
_publications[module_name] = ZopePublication(db=None,
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):
+
+ 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(BrowserRequest, 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 = [other['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
+
+
+class Zope2HTTPFactory(object):
+
+ implements(IRequestPublicationFactory)
+
+ def canHandle(self, environment):
+ return True
+
+ def __call__(self):
+ return Zope2BrowserRequest, ZopePublication
Modified: Zope/branches/publication-refactor/lib/python/Zope2/Startup/__init__.py
===================================================================
--- Zope/branches/publication-refactor/lib/python/Zope2/Startup/__init__.py 2005-12-13 17:56:02 UTC (rev 40774)
+++ Zope/branches/publication-refactor/lib/python/Zope2/Startup/__init__.py 2005-12-14 00:10:45 UTC (rev 40775)
@@ -20,12 +20,11 @@
import socket
from re import compile
from socket import gethostbyaddr
+import twisted.internet.reactor
import ZConfig
-
from ZConfig.components.logger import loghandler
-
logger = logging.getLogger("Zope")
started = False
@@ -106,10 +105,11 @@
def run(self):
# the mainloop.
try:
- import ZServer
- import Lifetime
- Lifetime.loop()
- sys.exit(ZServer.exit_code)
+ #import ZServer
+ #import Lifetime
+ #Lifetime.loop()
+ #sys.exit(ZServer.exit_code)
+ twisted.internet.reactor.run()
finally:
self.shutdown()
Modified: Zope/branches/publication-refactor/lib/python/Zope2/Startup/handlers.py
===================================================================
--- Zope/branches/publication-refactor/lib/python/Zope2/Startup/handlers.py 2005-12-13 17:56:02 UTC (rev 40774)
+++ Zope/branches/publication-refactor/lib/python/Zope2/Startup/handlers.py 2005-12-14 00:10:45 UTC (rev 40775)
@@ -1,8 +1,15 @@
import os
import sys
+import time
+import logging
from re import compile
from socket import gethostbyaddr
+import twisted.internet
+import zope.event
+import zope.app.appsetup.interfaces
+import zope.app.twisted.main
+
# top-level key handlers
@@ -133,7 +140,7 @@
"'catalog-getObject-raises' option will be removed in Zope 2.10:\n",
DeprecationWarning)
- from Products.ZCatalog import CatalogBrains
+ from Products.ZCatalog import CatalogBrains
CatalogBrains.GETOBJECT_RAISES = bool(value)
return value
@@ -143,7 +150,8 @@
def root_handler(config):
""" Mutate the configuration with defaults and perform
fixups of values that require knowledge about configuration
- values outside of their context. """
+ values outside of their context.
+ """
# Set environment variables
for k,v in config.environment.items():
@@ -165,7 +173,7 @@
instanceprod = os.path.join(config.instancehome, 'Products')
if instanceprod not in config.products:
config.products.append(instanceprod)
-
+
import Products
L = []
for d in config.products + Products.__path__:
@@ -190,6 +198,26 @@
config.cgi_environment,
config.port_base)
+ if not config.twisted_servers:
+ config.twisted_servers = []
+ else:
+ db = object() # config.db_tab.getDatabase(mount_point='/')
+ zope.event.notify(zope.app.appsetup.interfaces.DatabaseOpened(db))
+
+ # Set number of threads (reuse zserver_threads variable)
+ twisted.internet.reactor.suggestThreadPoolSize(config.zserver_threads)
+
+ # Create a root service
+ rootService = zope.app.twisted.main.ZopeService()
+
+ for server in config.twisted_servers:
+ service = server.create(db)
+ service.setServiceParent(rootService)
+
+ rootService.startService()
+ twisted.internet.reactor.addSystemEventTrigger(
+ 'before', 'shutdown', rootService.stopService)
+
# set up trusted proxies
if config.trusted_proxies:
import ZPublisher.HTTPRequest
@@ -217,3 +245,29 @@
if isIp_(host): return [host]
return gethostbyaddr(host)[2]
+# XXX Need to find a better place for this.
+
+import twisted.web2.wsgi
+import twisted.web2.server
+import twisted.web2.log
+
+try:
+ from twisted.web2.http import HTTPFactory
+except ImportError:
+ from twisted.web2.channel.http import HTTPFactory
+
+from zope.component import provideUtility
+from zope.app import wsgi
+from zope.app.twisted.server import ServerType, SSLServerType
+from zope.app.twisted.interfaces import IServerType
+
+def createHTTPFactory(db):
+ resource = twisted.web2.wsgi.WSGIResource(
+ wsgi.WSGIPublisherApplication(db))
+ resource = twisted.web2.log.LogWrapperResource(resource)
+
+ return HTTPFactory(twisted.web2.server.Site(resource))
+
+http = ServerType(createHTTPFactory, 8080)
+
+provideUtility(http, IServerType, 'Zope2-HTTP')
Modified: Zope/branches/publication-refactor/lib/python/Zope2/Startup/zopeschema.xml
===================================================================
--- Zope/branches/publication-refactor/lib/python/Zope2/Startup/zopeschema.xml 2005-12-13 17:56:02 UTC (rev 40774)
+++ Zope/branches/publication-refactor/lib/python/Zope2/Startup/zopeschema.xml 2005-12-14 00:10:45 UTC (rev 40775)
@@ -11,6 +11,12 @@
<import package="tempstorage"/>
<import package="Zope2.Startup" file="warnfilter.xml"/>
+ <sectiontype name="server" datatype="zope.app.twisted.server.ServerFactory">
+ <key name="type" required="yes" />
+ <key name="address" datatype="inet-address" />
+ <key name="backlog" datatype="integer" default="50" />
+ </sectiontype>
+
<sectiontype name="logger" datatype=".LoggerFactory">
<description>
This "logger" type only applies to access and request ("trace")
@@ -791,7 +797,9 @@
<metadefault>on</metadefault>
</key>
+ <multisection type="server" name="*" attribute="twisted_servers" />
<multisection type="ZServer.server" name="*" attribute="servers"/>
+
<key name="port-base" datatype="integer" default="0">
<description>
Base port number that gets added to the specific port numbers
More information about the Zope-Checkins
mailing list