[Checkins] SVN: zope.publisher/trunk/ Merge the zope.app.publisher refactoring results from my sandbox.

Dan Korostelev nadako at gmail.com
Thu Aug 27 10:49:25 EDT 2009


Log message for revision 103282:
  Merge the zope.app.publisher refactoring results from my sandbox.

Changed:
  U   zope.publisher/trunk/CHANGES.txt
  U   zope.publisher/trunk/setup.py
  U   zope.publisher/trunk/src/zope/publisher/browser.py
  U   zope.publisher/trunk/src/zope/publisher/configure.zcml
  U   zope.publisher/trunk/src/zope/publisher/defaultview.py
  U   zope.publisher/trunk/src/zope/publisher/interfaces/ftp.py
  U   zope.publisher/trunk/src/zope/publisher/interfaces/http.py
  U   zope.publisher/trunk/src/zope/publisher/interfaces/xmlrpc.py
  A   zope.publisher/trunk/src/zope/publisher/meta.zcml
  U   zope.publisher/trunk/src/zope/publisher/tests/test_browserlanguages.py
  U   zope.publisher/trunk/src/zope/publisher/tests/test_browserrequest.py
  A   zope.publisher/trunk/src/zope/publisher/tests/test_zcml.py
  U   zope.publisher/trunk/src/zope/publisher/xmlrpc.py
  A   zope.publisher/trunk/src/zope/publisher/zcml.py

-=-
Modified: zope.publisher/trunk/CHANGES.txt
===================================================================
--- zope.publisher/trunk/CHANGES.txt	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/CHANGES.txt	2009-08-27 14:49:25 UTC (rev 103282)
@@ -1,9 +1,17 @@
 CHANGES
 =======
 
-3.8.1 (unreleased)
+3.9.0 (unreleased)
 ------------------
 
+- Some parts of zope.app.publisher packages was moved into this package
+  during zope.app.publisher refactoring:
+  
+   * IModifiableUserPreferredLanguages adapter for requests
+   * browser:defaultView and browser:defaultSkin ZCML directives
+   * IHTTPView, IXMLRPCView and like interfaces
+   * security ZCML declarations for some of zope.publisher classes
+
 - Introduced ``IReRaiseException`` interface. If during publishing an
   exception occurs and for this exception an adapter is available that
   returns ``False`` on being called, the exception won't be reraised
@@ -21,6 +29,9 @@
 
 - Removed behavior of doing a time.sleep in the supportsRetry http request.
 
+- Add a fix for Internet Explorer versions that upload files will full
+  filesystem paths as filenames.
+
 3.8.0 (2009-05-23)
 ------------------
 

Modified: zope.publisher/trunk/setup.py
===================================================================
--- zope.publisher/trunk/setup.py	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/setup.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -23,7 +23,7 @@
 """
 
 setup(name='zope.publisher',
-      version='3.8.1dev',
+      version='3.9.0dev',
       url='http://pypi.python.org/pypi/zope.publisher',
       license='ZPL 2.1',
       author='Zope Corporation and Contributors',
@@ -44,6 +44,7 @@
                         'zope.authentication',
                         'zope.browser',
                         'zope.component',
+                        'zope.configuration',
                         'zope.event',
                         'zope.exceptions',
                         'zope.i18n',

Modified: zope.publisher/trunk/src/zope/publisher/browser.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/browser.py	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/browser.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -32,6 +32,7 @@
 from zope.interface import implements, directlyProvides
 from zope.i18n.interfaces import IUserPreferredLanguages
 from zope.i18n.interfaces import IUserPreferredCharsets
+from zope.i18n.interfaces import IModifiableUserPreferredLanguages
 from zope.location import Location
 
 from zope.publisher.interfaces import NotFound
@@ -622,7 +623,10 @@
                 d[m] = getattr(file,m)
 
         self.headers = aFieldStorage.headers
-        self.filename = unicode(aFieldStorage.filename, 'UTF-8')
+        filename = unicode(aFieldStorage.filename, 'UTF-8')
+        # fix for IE full paths
+        filename = filename[filename.rfind('\\')+1:].strip()
+        self.filename = filename
 
 class RedirectingBrowserRequest(BrowserRequest):
     """Browser requests that redirect when the actual and effective URLs differ
@@ -823,6 +827,49 @@
 
         return [lang for quality, lang in accepts]
 
+class NotCompatibleAdapterError(Exception):
+    """Adapter not compatible with
+       zope.i18n.interfaces.IModifiableBrowserLanguages has been used.
+    """
+
+BROWSER_LANGUAGES_KEY = "zope.publisher.browser.IUserPreferredLanguages"
+
+class CacheableBrowserLanguages(BrowserLanguages):
+
+    implements(IUserPreferredLanguages)
+
+    def getPreferredLanguages(self):
+        languages_data = self._getLanguagesData()
+        if "overridden" in languages_data:
+            return languages_data["overridden"]
+        elif "cached" not in languages_data:
+            languages_data["cached"] = super(
+                CacheableBrowserLanguages, self).getPreferredLanguages()
+        return languages_data["cached"]
+
+    def _getLanguagesData(self):
+        annotations = self.request.annotations
+        languages_data = annotations.get(BROWSER_LANGUAGES_KEY)
+        if languages_data is None:
+            annotations[BROWSER_LANGUAGES_KEY] = languages_data = {}
+        return languages_data
+
+class ModifiableBrowserLanguages(CacheableBrowserLanguages):
+
+    implements(IModifiableUserPreferredLanguages)
+
+    def setPreferredLanguages(self, languages):
+        languages_data = self.request.annotations.get(BROWSER_LANGUAGES_KEY)
+        if languages_data is None:
+            # Better way to create a compatible with
+            # IModifiableUserPreferredLanguages adapter is to use
+            # CacheableBrowserLanguages as base class or as example.
+            raise NotCompatibleAdapterError("Adapter not compatible with "
+                "zope.i18n.interfaces.IModifiableBrowserLanguages "
+                "has been used.")
+        languages_data["overridden"] = languages
+        self.request.setupLocale()
+
 class BrowserView(Location):
     """Browser View.
 

Modified: zope.publisher/trunk/src/zope/publisher/configure.zcml
===================================================================
--- zope.publisher/trunk/src/zope/publisher/configure.zcml	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/configure.zcml	2009-08-27 14:49:25 UTC (rev 103282)
@@ -16,14 +16,59 @@
         zcml:condition="installed zope.annotation"
         interface="zope.annotation.interfaces.IAttributeAnnotatable"
         />
+    <require
+        permission="zope.View"
+        interface="zope.publisher.interfaces.http.IHTTPApplicationRequest"/>
   </class>
 
+  <class class="zope.publisher.http.URLGetter">
+    <allow attributes="get __getitem__ __str__" />
+  </class>
+
+  <class class="zope.publisher.http.DirectResult">
+    <allow interface="zope.publisher.http.IResult" />
+  </class>
+
+  <class class="zope.publisher.browser.BrowserRequest">
+    <allow
+      interface="zope.publisher.interfaces.browser.IBrowserApplicationRequest"
+      attributes="response locale __str__"
+      />
+  </class>
+
+  <class class="zope.publisher.browser.TestRequest">
+    <allow
+      interface="zope.publisher.interfaces.browser.IBrowserApplicationRequest"
+      attributes="response"
+      />
+  </class>
+
+  <class class="zope.publisher.browser.BrowserResponse">
+    <allow
+      interface="zope.publisher.interfaces.http.IHTTPResponse"
+      />
+  </class>
+
   <adapter factory="zope.publisher.http.HTTPCharsets" />
+
+  <adapter
+    factory=".browser.ModifiableBrowserLanguages"
+    for="zope.publisher.interfaces.http.IHTTPRequest"
+    provides="zope.i18n.interfaces.IModifiableUserPreferredLanguages"
+    />
   
   <class class="xmlrpclib.Binary">
     <allow attributes="data encode decode" />
   </class>
 
+  <class class="xmlrpclib.Fault">
+    <allow attributes="faultCode faultString" />
+  </class>
+
+  <class class="xmlrpclib.DateTime">
+    <allow attributes="value" />
+  </class>
+
   <adapter factory=".xmlrpc.ListPreMarshaller" />
   <adapter factory=".xmlrpc.TuplePreMarshaller" />
   <adapter factory=".xmlrpc.BinaryPreMarshaller" />

Modified: zope.publisher/trunk/src/zope/publisher/defaultview.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/defaultview.py	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/defaultview.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -43,7 +43,6 @@
         a context.
         """
 
-# TODO: needs tests
 def getDefaultViewName(object, request, context=None):
     name = queryDefaultViewName(object, request, context=context)
     if name is not None:

Modified: zope.publisher/trunk/src/zope/publisher/interfaces/ftp.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/interfaces/ftp.py	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/interfaces/ftp.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -22,12 +22,15 @@
 
 from zope.publisher.interfaces import IPublishTraverse
 from zope.publisher.interfaces import IRequest
+from zope.publisher.interfaces import IView
 
-
 class IFTPRequest(IRequest):
     """FTP Request
     """
 
+class IFTPView(IView):
+    """FTP View"""
+
 class IFTPCredentials(Interface):
 
     def _authUserPW():

Modified: zope.publisher/trunk/src/zope/publisher/interfaces/http.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/interfaces/http.py	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/interfaces/http.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -27,6 +27,7 @@
 from zope.publisher.interfaces import IPublishTraverse
 from zope.publisher.interfaces import IRequest
 from zope.publisher.interfaces import IResponse
+from zope.publisher.interfaces import IView
 
 
 class IVirtualHostRequest(Interface):
@@ -214,6 +215,10 @@
         """
 
 
+class IHTTPView(IView):
+    "HTTP View"
+
+
 class IHTTPCredentials(Interface):
 
     # TODO: Eventially this will be a different method

Modified: zope.publisher/trunk/src/zope/publisher/interfaces/xmlrpc.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/interfaces/xmlrpc.py	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/interfaces/xmlrpc.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -20,7 +20,7 @@
 
 from zope.interface import Interface
 
-from zope.publisher.interfaces import IPublication
+from zope.publisher.interfaces import IPublication, IView
 from zope.publisher.interfaces import IPublishTraverse
 from zope.publisher.interfaces.http import IHTTPRequest
 
@@ -43,11 +43,11 @@
     """XML-RPC Request
     """
 
+class IXMLRPCView(IView):
+    """XMLRPC View"""
+
 class IXMLRPCPremarshaller(Interface):
     """Pre-Marshaller to remove proxies for xmlrpclib"""
 
     def __call__(self):
         """Return the given object without proxies."""
-
-
-

Copied: zope.publisher/trunk/src/zope/publisher/meta.zcml (from rev 103281, Sandbox/nadako/zope.publisher/src/zope/publisher/meta.zcml)
===================================================================
--- zope.publisher/trunk/src/zope/publisher/meta.zcml	                        (rev 0)
+++ zope.publisher/trunk/src/zope/publisher/meta.zcml	2009-08-27 14:49:25 UTC (rev 103282)
@@ -0,0 +1,19 @@
+<configure xmlns:meta="http://namespaces.zope.org/meta">
+
+  <meta:directives namespace="http://namespaces.zope.org/browser">
+
+    <meta:directive
+        name="defaultView"
+        schema=".zcml.IDefaultViewDirective"
+        handler=".zcml.defaultView"
+        />
+
+    <meta:directive
+        name="defaultSkin"
+        schema=".zcml.IDefaultSkinDirective"
+        handler=".zcml.defaultSkin"
+        />
+
+  </meta:directives>
+
+</configure>

Modified: zope.publisher/trunk/src/zope/publisher/tests/test_browserlanguages.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/tests/test_browserlanguages.py	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/tests/test_browserlanguages.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -18,8 +18,10 @@
 import unittest
 
 from zope.publisher.browser import BrowserLanguages
+from zope.publisher.browser import CacheableBrowserLanguages
+from zope.publisher.browser import ModifiableBrowserLanguages
+from zope.publisher.browser import NotCompatibleAdapterError
 
-
 # Note: The expected output is in order of preference,
 # empty 'q=' means 'q=1', and if theres more than one
 # empty, we assume they are in order of preference.
@@ -54,10 +56,44 @@
             self.assertEqual(list(browser_languages.getPreferredLanguages()),
                              expected)
 
+class CacheableBrowserLanguagesTests(BrowserLanguagesTest):
 
+    def factory(self, request):
+        return CacheableBrowserLanguages(request)
+
+    def test_cached_languages(self):
+        eq = self.failUnlessEqual
+        request = TestRequest("da, en, pt")
+        browser_languages = self.factory(request)
+        eq(list(browser_languages.getPreferredLanguages()), ["da", "en", "pt"])
+        request["HTTP_ACCEPT_LANGUAGE"] = "ru, en"
+        eq(list(browser_languages.getPreferredLanguages()), ["da", "en", "pt"])
+
+class ModifiableBrowserLanguagesTests(CacheableBrowserLanguagesTests):
+
+    def factory(self, request):
+        return ModifiableBrowserLanguages(request)
+
+    def test_setPreferredLanguages(self):
+        eq = self.failUnlessEqual
+        request = TestRequest("da, en, pt")
+        browser_languages = self.factory(request)
+        eq(list(browser_languages.getPreferredLanguages()), ["da", "en", "pt"])
+        browser_languages.setPreferredLanguages(["ru", "en"])
+        self.failUnless(request.localized)
+        eq(list(browser_languages.getPreferredLanguages()), ["ru", "en"])
+
+    def test_conflicting_adapters(self):
+        request = TestRequest("da, en, pt")
+        not_compatible_browser_languages = BrowserLanguages(request)
+        browser_languages = self.factory(request)
+        self.assertRaises(NotCompatibleAdapterError,
+            browser_languages.setPreferredLanguages, ["ru", "en"])
+
+
 def test_suite():
-    loader=unittest.TestLoader()
-    return loader.loadTestsFromTestCase(BrowserLanguagesTest)
-
-if __name__=='__main__':
-    unittest.TextTestRunner().run(test_suite())
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(BrowserLanguagesTest))
+    suite.addTest(unittest.makeSuite(CacheableBrowserLanguagesTests))
+    suite.addTest(unittest.makeSuite(ModifiableBrowserLanguagesTests))
+    return suite

Modified: zope.publisher/trunk/src/zope/publisher/tests/test_browserrequest.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/tests/test_browserrequest.py	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/tests/test_browserrequest.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -47,6 +47,15 @@
 -----------------------------1--
 """ % ('test' * 1000)
 
+IE_FILE_BODY = """-----------------------------1
+Content-Disposition: form-data; name="upload"; filename="C:\\Windows\\notepad.exe"
+Content-Type: text/plain
+
+Some data
+-----------------------------1--
+"""
+
+
 def publish(request):
     publish_(request, handle_errors=0)
 
@@ -200,6 +209,11 @@
         request.processInputs()
         self.assert_(request.form['upload'].name)
 
+        request  = self._createRequest(extra, body=IE_FILE_BODY)
+        request.processInputs()
+        self.assertEquals(request.form['upload'].filename, 'notepad.exe')
+
+
     def testDefault2(self):
         extra = {'PATH_INFO': '/folder/item2/view'}
         request = self._createRequest(extra)

Copied: zope.publisher/trunk/src/zope/publisher/tests/test_zcml.py (from rev 103281, Sandbox/nadako/zope.publisher/src/zope/publisher/tests/test_zcml.py)
===================================================================
--- zope.publisher/trunk/src/zope/publisher/tests/test_zcml.py	                        (rev 0)
+++ zope.publisher/trunk/src/zope/publisher/tests/test_zcml.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -0,0 +1,169 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 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.
+#
+##############################################################################
+"""Tests for browser:defaultSkin and browser:defaultView directives
+
+$Id: tests.py 103163 2009-08-24 16:22:07Z nadako $
+"""
+from cStringIO import StringIO
+import unittest
+
+from zope.testing import cleanup
+from zope import component
+
+from zope.configuration.xmlconfig import XMLConfig, xmlconfig
+from zope.publisher.browser import TestRequest, BrowserView
+from zope.publisher.defaultview import getDefaultViewName
+from zope.publisher.interfaces import IDefaultViewName, IDefaultSkin
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.interface import Interface, implements, providedBy, directlyProvides
+
+import zope.publisher
+
+class IOb(Interface):
+    pass
+
+class Ob(object):
+    implements(IOb)
+
+class ITestLayer(IBrowserRequest):
+    """Test Layer."""
+
+class ITestSkin(ITestLayer):
+    """Test Skin."""
+
+class V1(BrowserView):
+    pass
+
+class V2(BrowserView):
+    pass
+
+
+request = TestRequest()
+ob = Ob()
+
+template = """<configure
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:browser='http://namespaces.zope.org/browser'
+   i18n_domain='zope'>
+   %s
+   </configure>"""
+
+class Test(cleanup.CleanUp, unittest.TestCase):
+
+    def setUp(self):
+        super(Test, self).setUp()
+        XMLConfig('meta.zcml', zope.publisher)()
+
+    def testDefaultView(self):
+        self.assertTrue(
+            component.queryMultiAdapter((ob, request), IDefaultViewName) is None)
+        xmlconfig(StringIO(template % (
+            '''
+            <browser:defaultView
+                name="test"
+                for="zope.publisher.tests.test_zcml.IOb" />
+            '''
+            )))
+
+        self.assertEqual(getDefaultViewName(ob, request), 'test')
+
+    def testDefaultViewWithLayer(self):
+        class FakeRequest(TestRequest):
+            implements(ITestLayer)
+        request2 = FakeRequest()
+
+        self.assertEqual(
+            component.queryMultiAdapter((ob, request2), IDefaultViewName),
+            None)
+
+        xmlconfig(StringIO(template % (
+            '''
+            <browser:defaultView
+                for="zope.publisher.tests.test_zcml.IOb"
+                name="test"
+                />
+            <browser:defaultView
+                for="zope.publisher.tests.test_zcml.IOb"
+                layer="zope.publisher.tests.test_zcml.ITestLayer"
+                name="test2"
+                />
+            '''
+            )))
+
+        self.assertEqual(
+            zope.publisher.defaultview.getDefaultViewName(ob, request2),
+            'test2')
+        self.assertEqual(
+            zope.publisher.defaultview.getDefaultViewName(ob, request),
+            'test')
+
+    def testDefaultViewForClass(self):
+        self.assertEqual(
+            component.queryMultiAdapter((ob, request), IDefaultViewName),
+            None)
+
+        xmlconfig(StringIO(template % (
+            '''
+            <browser:defaultView
+                for="zope.publisher.tests.test_zcml.Ob"
+                name="test"
+                />
+            '''
+            )))
+
+        self.assertEqual(
+            zope.publisher.defaultview.getDefaultViewName(ob, request),
+            'test')
+
+    def testDefaultSkin(self):
+        request = TestRequest()
+        self.assertEqual(
+            component.queryMultiAdapter((ob, request), name='test'),
+            None)
+
+        XMLConfig('meta.zcml', component)()
+        xmlconfig(StringIO(template % (
+            '''
+            <interface
+                interface="
+                  zope.publisher.tests.test_zcml.ITestSkin"
+                type="zope.publisher.interfaces.browser.IBrowserSkinType"
+                name="Test Skin"
+                />
+            <browser:defaultSkin name="Test Skin" />
+            <view
+                for="zope.publisher.tests.test_zcml.IOb"
+                type="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
+                name="test"
+                factory="zope.publisher.tests.test_zcml.V1"
+                />
+            <view
+                for="zope.publisher.tests.test_zcml.IOb"
+                type="zope.publisher.tests.test_zcml.ITestLayer"
+                name="test"
+                factory="zope.publisher.tests.test_zcml.V2"
+                />
+            '''
+            )))
+
+        # Simulate Zope Publication behavior in beforeTraversal()
+        adapters = component.getSiteManager().adapters
+        skin = adapters.lookup((providedBy(request),), IDefaultSkin, '')
+        directlyProvides(request, skin)
+
+        v = component.queryMultiAdapter((ob, request), name='test')
+        self.assertTrue(isinstance(v, V2))
+
+def test_suite():
+    return unittest.makeSuite(Test)

Modified: zope.publisher/trunk/src/zope/publisher/xmlrpc.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/xmlrpc.py	2009-08-27 14:38:12 UTC (rev 103281)
+++ zope.publisher/trunk/src/zope/publisher/xmlrpc.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -28,7 +28,7 @@
 import zope.interface
 from zope.interface import implements
 from zope.publisher.interfaces.xmlrpc import \
-        IXMLRPCPublisher, IXMLRPCRequest, IXMLRPCPremarshaller
+        IXMLRPCPublisher, IXMLRPCRequest, IXMLRPCPremarshaller, IXMLRPCView
 
 from zope.publisher.http import HTTPRequest, HTTPResponse, DirectResult
 from zope.security.proxy import isinstance
@@ -162,6 +162,16 @@
         # XML-RPC prefers a status of 200 ("ok") even when reporting errors.
         self.setStatus(200)
 
+
+class XMLRPCView(object):
+    """A base XML-RPC view that can be used as mix-in for XML-RPC views.""" 
+    implements(IXMLRPCView)
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+
+
 class PreMarshallerBase(object):
     """Abstract base class for pre-marshallers."""
     zope.interface.implements(IXMLRPCPremarshaller)

Copied: zope.publisher/trunk/src/zope/publisher/zcml.py (from rev 103281, Sandbox/nadako/zope.publisher/src/zope/publisher/zcml.py)
===================================================================
--- zope.publisher/trunk/src/zope/publisher/zcml.py	                        (rev 0)
+++ zope.publisher/trunk/src/zope/publisher/zcml.py	2009-08-27 14:49:25 UTC (rev 103282)
@@ -0,0 +1,120 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 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.
+#
+##############################################################################
+"""Default view and default skin ZCML configuration feature.
+
+$Id: metaconfigure.py 103163 2009-08-24 16:22:07Z nadako $
+"""
+from zope import component
+from zope.component.interface import provideInterface
+from zope.component.zcml import handler
+from zope.configuration.fields import GlobalObject, GlobalInterface
+from zope.interface import Interface
+from zope.publisher.interfaces import IDefaultViewName
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IBrowserSkinType
+from zope.publisher.interfaces.browser import IDefaultSkin
+from zope.schema import TextLine
+
+
+class IDefaultSkinDirective(Interface):
+    """Sets the default browser skin"""
+
+    name = TextLine(
+        title=u"Default skin name",
+        description=u"Default skin name",
+        required=True
+        )
+
+
+class IDefaultViewDirective(Interface):
+    """
+    The name of the view that should be the default.
+
+    This name refers to view that should be the
+    view used by default (if no view name is supplied
+    explicitly).
+    """
+
+    name = TextLine(
+        title=u"The name of the view that should be the default.",
+        description=u"""
+        This name refers to view that should be the view used by
+        default (if no view name is supplied explicitly).""",
+        required=True
+        )
+
+    for_ = GlobalObject(
+        title=u"The interface this view is the default for.",
+        description=u"""Specifies the interface for which the view is
+        registered. All objects implementing this interface can make use of
+        this view. If this attribute is not specified, the view is available
+        for all objects.""",
+        required=False
+        )
+
+    layer = GlobalInterface(
+        title=u"The layer the default view is declared for",
+        description=u"The default layer for which the default view is "
+                    u"applicable. By default it is applied to all layers.",
+        required=False
+        )
+
+
+def setDefaultSkin(name, info=''):
+    """Set the default skin.
+
+    >>> from zope.interface import directlyProvides
+    >>> from zope.app.testing import ztapi
+
+    >>> class Skin1: pass
+    >>> directlyProvides(Skin1, IBrowserSkinType)
+
+    >>> ztapi.provideUtility(IBrowserSkinType, Skin1, 'Skin1')
+    >>> setDefaultSkin('Skin1')
+    >>> adapters = component.getSiteManager().adapters
+
+	Lookup the default skin for a request that has the
+
+    >>> adapters.lookup((IBrowserRequest,), IDefaultSkin, '') is Skin1
+    True
+    """
+    skin = component.getUtility(IBrowserSkinType, name)
+    handler('registerAdapter',
+            skin, (IBrowserRequest,), IDefaultSkin, '', info),
+
+
+def defaultSkin(_context, name):
+
+    _context.action(
+        discriminator = 'defaultSkin',
+        callable = setDefaultSkin,
+        args = (name, _context.info)
+        )
+
+
+def defaultView(_context, name, for_=None, layer=IBrowserRequest):
+
+    _context.action(
+        discriminator = ('defaultViewName', for_, layer, name),
+        callable = handler,
+        args = ('registerAdapter',
+                name, (for_, layer), IDefaultViewName, '', _context.info)
+        )
+
+    if for_ is not None:
+        _context.action(
+            discriminator = None,
+            callable = provideInterface,
+            args = ('', for_)
+            )



More information about the Checkins mailing list