[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