[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/publisher/ Fixed issue 247: z.a.publisher.browser.resource should not use __parent__

Fred L. Drake, Jr. fdrake at gmail.com
Mon Aug 9 15:14:02 EDT 2004


Log message for revision 26968:
  Fixed issue 247: z.a.publisher.browser.resource should not use __parent__
  
  This allows the thread-local site to be used to compute the URL for
  resources instead of walking up the __parent__ links and doing several
  checks.
  
  To make this work, resources need to have properly initialized
  __name__ values; this mostly requires that the registered names get
  passed in several places where they weren't passed before.
  
  Added some explanation of what a resource directory is.
  
  (merged from ZopeX3-3.0 branch revisions 26966, 26967)
  


Changed:
  U   Zope3/trunk/src/zope/app/publisher/browser/directoryresource.py
  U   Zope3/trunk/src/zope/app/publisher/browser/fileresource.py
  U   Zope3/trunk/src/zope/app/publisher/browser/i18nresourcemeta.py
  U   Zope3/trunk/src/zope/app/publisher/browser/pagetemplateresource.py
  U   Zope3/trunk/src/zope/app/publisher/browser/resource.py
  U   Zope3/trunk/src/zope/app/publisher/browser/resourcemeta.py
  A   Zope3/trunk/src/zope/app/publisher/browser/tests/support.py
  U   Zope3/trunk/src/zope/app/publisher/browser/tests/test_directives.py
  U   Zope3/trunk/src/zope/app/publisher/browser/tests/test_directoryresource.py
  U   Zope3/trunk/src/zope/app/publisher/browser/tests/test_fileresource.py
  U   Zope3/trunk/src/zope/app/publisher/browser/tests/test_icondirective.py
  U   Zope3/trunk/src/zope/app/publisher/browser/tests/test_pagetemplateresource.py
  U   Zope3/trunk/src/zope/app/publisher/browser/tests/test_resource.py
  U   Zope3/trunk/src/zope/app/publisher/browser/tests/testi18nfileresource.py
  U   Zope3/trunk/src/zope/app/publisher/fileresource.py


-=-
Modified: Zope3/trunk/src/zope/app/publisher/browser/directoryresource.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/directoryresource.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/directoryresource.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -13,9 +13,18 @@
 ##############################################################################
 """Resource Directory
 
+A 'resource directory' is an on-disk directory which is registered as
+a resource using the <resourceDirectory> ZCML directive.  The
+directory is treated as a source for individual resources; it can be
+traversed to retrieve resources represented by contained files, which
+can in turn be treated as resources.  The contained files have
+__name__ values which include a '/' separating the __name__ of the
+resource directory from the name of the file within the directory.
+
 $Id$
 """
 import os
+import posixpath
 
 from zope.interface import implements
 from zope.exceptions import NotFoundError
@@ -34,9 +43,10 @@
 # we only need this class as a context for DirectoryResource
 class Directory(object):
 
-    def __init__(self, path, checker):
+    def __init__(self, path, checker, name):
         self.path = path
         self.checker = checker
+        self.__name__ = name
 
 class DirectoryResource(BrowserView, Resource):
 
@@ -76,18 +86,20 @@
             return default
         ext = os.path.splitext(os.path.normcase(name))[1]
         factory = self.resource_factories.get(ext, self.default_factory)
-        resource = factory(filename, self.context.checker)(self.request)
+        rname = posixpath.join(self.]__name__, name)
+        resource = factory(filename, self.context.checker, rname)(self.request)
         resource.__parent__ = self
-        resource.__name__ = name
         return resource
 
 class DirectoryResourceFactory(object):
 
-    def __init__(self, path, checker):
-        self.__dir = Directory(path, checker)
+    def __init__(self, path, checker, name):
+        self.__dir = Directory(path, checker, name)
         self.__checker = checker
+        self.__name = name
 
     def __call__(self, request):
         resource = DirectoryResource(self.__dir, request)
         resource.__Security_checker__ = self.__checker
+        resource.__name__ = self.__name
         return resource

Modified: Zope3/trunk/src/zope/app/publisher/browser/fileresource.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/fileresource.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/fileresource.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -110,22 +110,26 @@
 
 class FileResourceFactory(object):
 
-    def __init__(self, path, checker):
-        self.__file = File(path)
+    def __init__(self, path, checker, name):
+        self.__file = File(path, name)
         self.__checker = checker
+        self.__name = name
 
     def __call__(self, request):
         resource = FileResource(self.__file, request)
         resource.__Security_checker__ = self.__checker
+        resource.__name__ = self.__name
         return resource
 
 class ImageResourceFactory(object):
 
-    def __init__(self, path, checker):
-        self.__file = Image(path)
+    def __init__(self, path, checker, name):
+        self.__file = Image(path, name)
         self.__checker = checker
+        self.__name = name
 
     def __call__(self, request):
         resource = FileResource(self.__file, request)
         resource.__Security_checker__ = self.__checker
+        resource.__name__ = self.__name
         return resource

Modified: Zope3/trunk/src/zope/app/publisher/browser/i18nresourcemeta.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/i18nresourcemeta.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/i18nresourcemeta.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -56,7 +56,7 @@
                     "Can't use both files and images in the same "
                     "i18n-resource directive"
                     )
-            self.__data[language] = File(_context.path(file))
+            self.__data[language] = File(_context.path(file), self.name)
             self.__format = File
         elif image is not None:
             if self.__format is not None and self.__format != Image:
@@ -64,7 +64,7 @@
                     "Can't use both files and images in the same "
                     "i18n-resource directive"
                     )
-            self.__data[language] = Image(_context.path(image))
+            self.__data[language] = Image(_context.path(image), self.name)
             self.__format = Image
         else:
             raise ConfigurationError(

Modified: Zope3/trunk/src/zope/app/publisher/browser/pagetemplateresource.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/pagetemplateresource.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/pagetemplateresource.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -43,11 +43,13 @@
 
 class PageTemplateResourceFactory(object):
 
-    def __init__(self, path, checker):
+    def __init__(self, path, checker, name):
         self.__pt = PageTemplate(path)
         self.__checker = checker
+        self.__name = name
 
     def __call__(self, request):
         resource = PageTemplateResource(self.__pt, request)
         resource.__Security_checker__ = self.__checker
+        resource.__name__ = self.__name
         return resource

Modified: Zope3/trunk/src/zope/app/publisher/browser/resource.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/resource.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/resource.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -15,14 +15,15 @@
 
 $Id$
 """
+from zope.component.interfaces import IResource
+from zope.interface import implements
+
 from zope.app import zapi
+from zope.app.component.hooks import getSite
 from zope.app.location import Location
-from zope.app.site.interfaces import ISite
-from zope.app.traversing.interfaces import IContainmentRoot
 from zope.app.traversing.browser.interfaces import IAbsoluteURL
-from zope.component.interfaces import IResource
-from zope.interface import implements
 
+
 class Resource(Location):
     implements(IResource)
 
@@ -30,24 +31,10 @@
         self.request = request
 
     def __call__(self):
-        names = []
         name = self.__name__
         if name.startswith('++resource++'):
             name = name[12:]
-        names.append(name)
 
-        site = self.__parent__
-        while True:
-            if ISite.providedBy(site):
-                break
-            if IContainmentRoot.providedBy(site):
-                site = None
-                break
-            if IResource.providedBy(site) and site.__name__:
-                names.append(site.__name__)
-            site = site.__parent__
-
-        names.reverse()
-        name = '/'.join(filter(None, names))
+        site = getSite()
         url = str(zapi.getViewProviding(site, IAbsoluteURL, self.request))
         return "%s/@@/%s" % (url, name)

Modified: Zope3/trunk/src/zope/app/publisher/browser/resourcemeta.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/resourcemeta.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/resourcemeta.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -46,11 +46,11 @@
             )
 
     if file:
-        factory = FileResourceFactory(file, checker)
+        factory = FileResourceFactory(file, checker, name)
     elif image:
-        factory = ImageResourceFactory(image, checker)
+        factory = ImageResourceFactory(image, checker, name)
     else:
-        factory = PageTemplateResourceFactory(template, checker)
+        factory = PageTemplateResourceFactory(template, checker, name)
 
     _context.action(
         discriminator = ('resource', name, IBrowserRequest, layer),
@@ -72,7 +72,7 @@
             "Directory %s does not exist" % directory
             )
 
-    factory = DirectoryResourceFactory(directory, checker)
+    factory = DirectoryResourceFactory(directory, checker, name)
     _context.action(
         discriminator = ('resource', name, IBrowserRequest, layer),
         callable = handler,

Copied: Zope3/trunk/src/zope/app/publisher/browser/tests/support.py (from rev 26967, Zope3/branches/ZopeX3-3.0/src/zope/app/publisher/browser/tests/support.py)


Property changes on: Zope3/trunk/src/zope/app/publisher/browser/tests/support.py
___________________________________________________________________
Name: svn:mime-type
   + text/x-python
Name: svn:eol-style
   + native

Modified: Zope3/trunk/src/zope/app/publisher/browser/tests/test_directives.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/tests/test_directives.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/tests/test_directives.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -35,6 +35,7 @@
     globalBrowserMenuService
 from zope.publisher.browser import TestRequest
 
+from zope.app.publisher.browser.fileresource import FileResource
 from zope.app.publisher.browser.i18nfileresource import I18nFileResource
 
 import zope.app.publisher.browser
@@ -806,6 +807,7 @@
             ))
 
         r = ProxyFactory(getResource('index.html', request))
+        self.assertEqual(r.__name__, "index.html")
 
         # Make sure we can access available attrs and not others
         for n in ('GET', 'HEAD', 'publishTraverse', 'request', '__call__'):
@@ -814,6 +816,7 @@
         self.assertRaises(Exception, getattr, r, '_testData')
 
         r = removeAllProxies(r)
+        self.assert_(r.__class__ is FileResource)
         self.assertEqual(r._testData(), open(path, 'rb').read())
 
 

Modified: Zope3/trunk/src/zope/app/publisher/browser/tests/test_directoryresource.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/tests/test_directoryresource.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/tests/test_directoryresource.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -33,8 +33,7 @@
 from zope.app.publisher.browser.pagetemplateresource import \
      PageTemplateResource
 import zope.app.publisher.browser.tests as p
-from zope.app.traversing.interfaces import IContainmentRoot
-from zope.app.site.interfaces import ISite
+from zope.app.publisher.browser.tests import support
 
 test_directory = os.path.dirname(p.__file__)
 
@@ -42,23 +41,17 @@
     ('get', '__getitem__', 'request', 'publishTraverse')
     )
 
-class Site(object):
-    implements(ISite, IContainmentRoot)
-
 class Ob(Contained): pass
 
-site = Site()
 ob = Ob()
 
-class Test(PlacelessSetup, TestCase):
+class Test(support.SiteHandler, PlacelessSetup, TestCase):
 
-    def setUp(self):
-        super(Test, self).setUp()
-
     def testNotFound(self):
         path = os.path.join(test_directory, 'testfiles')
         request = TestRequest()
-        resource = DirectoryResourceFactory(path, checker)(request)
+        factory = DirectoryResourceFactory(path, checker, 'testfiles')
+        resource = factory(request)
         self.assertRaises(NotFoundError, resource.publishTraverse,
                           resource.request, 'doesnotexist')
         self.assertRaises(NotFoundError, resource.get, 'doesnotexist')
@@ -66,43 +59,43 @@
     def testGetitem(self):
         path = os.path.join(test_directory, 'testfiles')
         request = TestRequest()
-        resource = DirectoryResourceFactory(path, checker)(request)
+        factory = DirectoryResourceFactory(path, checker, 'testfiles')
+        resource = factory(request)
         self.assertRaises(KeyError, resource.__getitem__, 'doesnotexist')
         file = resource['test.txt']
 
     def testProxy(self):
         path = os.path.join(test_directory, 'testfiles')
         request = TestRequest()
-        resource = DirectoryResourceFactory(path, checker)(request)
+        factory = DirectoryResourceFactory(path, checker, 'testfiles')
+        resource = factory(request)
         file = ProxyFactory(resource['test.txt'])
         self.assert_(isProxy(file))
 
     def testURL(self):
         request = TestRequest()
-        request._vh_root = site
+        request._vh_root = support.site
         path = os.path.join(test_directory, 'testfiles')
-        files = DirectoryResourceFactory(path, checker)(request)
-        files.__parent__ = site
-        files.__name__ = 'test_files'
+        files = DirectoryResourceFactory(path, checker, 'test_files')(request)
+        files.__parent__ = support.site
         file = files['test.gif']
         self.assertEquals(file(), 'http://127.0.0.1/@@/test_files/test.gif')
 
     def testURL2Level(self):
         request = TestRequest()
-        request._vh_root = site
-        ob.__parent__ = site
+        request._vh_root = support.site
+        ob.__parent__ = support.site
         ob.__name__ = 'ob'
         path = os.path.join(test_directory, 'testfiles')
-        files = DirectoryResourceFactory(path, checker)(request)
+        files = DirectoryResourceFactory(path, checker, 'test_files')(request)
         files.__parent__ = ob
-        files.__name__ = 'test_files'
         file = files['test.gif']
         self.assertEquals(file(), 'http://127.0.0.1/@@/test_files/test.gif')
 
     def testCorrectFactories(self):
         path = os.path.join(test_directory, 'testfiles')
         request = TestRequest()
-        resource = DirectoryResourceFactory(path, checker)(request)
+        resource = DirectoryResourceFactory(path, checker, 'files')(request)
 
         image = resource['test.gif']
         self.assert_(isinstance(removeAllProxies(image), FileResource))

Modified: Zope3/trunk/src/zope/app/publisher/browser/tests/test_fileresource.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/tests/test_fileresource.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/tests/test_fileresource.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -50,7 +50,8 @@
     def testNoTraversal(self):
 
         path = os.path.join(test_directory, 'testfiles', 'test.txt')
-        resource = FileResourceFactory(path, checker)(TestRequest())
+        factory = FileResourceFactory(path, checker, 'test.txt')
+        resource = factory(TestRequest())
         self.assertRaises(NotFoundError,
                           resource.publishTraverse,
                           resource.request,
@@ -60,7 +61,8 @@
 
         path = os.path.join(test_directory, 'testfiles', 'test.txt')
 
-        resource = FileResourceFactory(path, checker)(TestRequest())
+        factory = FileResourceFactory(path, checker, 'test.txt')
+        resource = factory(TestRequest())
         self.assertEqual(resource.GET(), open(path, 'rb').read())
 
         response = removeAllProxies(resource.request).response
@@ -69,7 +71,8 @@
     def testFileHEAD(self):
 
         path = os.path.join(test_directory, 'testfiles', 'test.txt')
-        resource = FileResourceFactory(path, checker)(TestRequest())
+        factory = FileResourceFactory(path, checker, 'test.txt')
+        resource = factory(TestRequest())
 
         self.assertEqual(resource.HEAD(), '')
 
@@ -80,7 +83,8 @@
 
         path = os.path.join(test_directory, 'testfiles', 'test.gif')
 
-        resource = ImageResourceFactory(path, checker)(TestRequest())
+        factory = ImageResourceFactory(path, checker, 'test.gif')
+        resource = factory(TestRequest())
 
         self.assertEqual(resource.GET(), open(path, 'rb').read())
 
@@ -90,7 +94,8 @@
     def testImageHEAD(self):
 
         path = os.path.join(test_directory, 'testfiles', 'test.gif')
-        resource = ImageResourceFactory(path, checker)(TestRequest())
+        factory = ImageResourceFactory(path, checker, 'test.gif')
+        resource = factory(TestRequest())
 
         self.assertEqual(resource.HEAD(), '')
 

Modified: Zope3/trunk/src/zope/app/publisher/browser/tests/test_icondirective.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/tests/test_icondirective.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/tests/test_icondirective.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -19,20 +19,23 @@
 from StringIO import StringIO
 from unittest import TestCase, main, makeSuite
 
-from zope.security.interfaces import Forbidden
+from zope.component import queryView, getView, getResource
+from zope.configuration.exceptions import ConfigurationError
+from zope.configuration.xmlconfig import xmlconfig, XMLConfig
+from zope.interface import implements
 from zope.proxy import removeAllProxies
-from zope.app.tests.placelesssetup import PlacelessSetup
-from zope.configuration.xmlconfig import xmlconfig, XMLConfig
 from zope.publisher.browser import TestRequest
+from zope.security.checker import ProxyFactory, CheckerPublic
+from zope.security.interfaces import Forbidden
+
+import zope.app.publisher.browser
+
 from zope.app.component.tests.views import IC
-from zope.component import queryView, getView, getResource
-from zope.configuration.exceptions import ConfigurationError
-from zope.interface import implements
 from zope.app.site.interfaces import ISite
+from zope.app.publisher.browser.tests import support
+from zope.app.tests.placelesssetup import PlacelessSetup
 from zope.app.traversing.interfaces import IContainmentRoot
-from zope.security.checker import ProxyFactory
 
-import zope.app.publisher.browser
 
 template = """<configure
    xmlns='http://namespaces.zope.org/zope'
@@ -46,10 +49,10 @@
 request = TestRequest()
 
 class Ob(object):
-    implements(IC, ISite, IContainmentRoot)
+    implements(IC)
 
 ob = Ob()
-request._vh_root = ob
+request._vh_root = support.site
 
 def defineCheckers():
     # define the appropriate checker for a FileResource for these tests
@@ -58,7 +61,7 @@
     protectName(FileResource, '__call__', 'zope.Public')
 
 
-class Test(PlacelessSetup, TestCase):
+class Test(support.SiteHandler, PlacelessSetup, TestCase):
 
     def setUp(self):
         super(Test, self).setUp()

Modified: Zope3/trunk/src/zope/app/publisher/browser/tests/test_pagetemplateresource.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/tests/test_pagetemplateresource.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/tests/test_pagetemplateresource.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -45,7 +45,8 @@
     def testNoTraversal(self):
         path = os.path.join(test_directory, 'testfiles', 'test.pt')
         request = TestRequest()
-        resource = PageTemplateResourceFactory(path, checker)(request)
+        factory = PageTemplateResourceFactory(path, checker, 'test.pt')
+        resource = factory(request)
         self.assertRaises(NotFoundError, resource.publishTraverse,
                           resource.request, ())
 
@@ -53,7 +54,8 @@
         path = os.path.join(test_directory, 'testfiles', 'testresource.pt')
         test_data = "Foobar"
         request = TestRequest(test_data=test_data)
-        resource = PageTemplateResourceFactory(path, checker)(request)
+        factory = PageTemplateResourceFactory(path, checker, 'testresource.pt')
+        resource = factory(request)
         self.assert_(resource(), test_data)        
 
 def test_suite():

Modified: Zope3/trunk/src/zope/app/publisher/browser/tests/test_resource.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/tests/test_resource.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/tests/test_resource.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -16,9 +16,13 @@
 $Id$
 """
 import unittest
-from zope.app.publisher.browser.resource import Resource
+
+from zope.component.service import serviceManager
 from zope.interface import implements
 from zope.publisher.browser import TestRequest
+
+from zope.app.component.hooks import setSite
+from zope.app.publisher.browser.resource import Resource
 from zope.app.site.interfaces import ISite
 from zope.app.tests.placelesssetup import PlacelessSetup
 from zope.app.traversing.interfaces import IContainmentRoot
@@ -26,10 +30,21 @@
 class Site(object):
     implements(ISite, IContainmentRoot)
 
+    def getSiteManager(self):
+        return serviceManager
+
 site = Site()
 
 class TestResource(PlacelessSetup, unittest.TestCase):
 
+    def setUp(self):
+        super(TestResource, self).setUp()
+        setSite(site)
+
+    def tearDown(self):
+        setSite()
+        super(TestResource, self).tearDown()
+
     def testGlobal(self):
         req = TestRequest()
         r = Resource(req)

Modified: Zope3/trunk/src/zope/app/publisher/browser/tests/testi18nfileresource.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/tests/testi18nfileresource.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/browser/tests/testi18nfileresource.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -64,8 +64,8 @@
     def _createDict(self, filename1='test.pt', filename2='test2.pt'):
         path1 = os.path.join(test_directory, 'testfiles', filename1)
         path2 = os.path.join(test_directory, 'testfiles', filename2)
-        return { 'en': File(path1),
-                 'fr': File(path2) }
+        return { 'en': File(path1, filename1),
+                 'fr': File(path2, filename2) }
 
 
     def testNoTraversal(self):

Modified: Zope3/trunk/src/zope/app/publisher/fileresource.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/fileresource.py	2004-08-09 19:00:10 UTC (rev 26967)
+++ Zope3/trunk/src/zope/app/publisher/fileresource.py	2004-08-09 19:14:02 UTC (rev 26968)
@@ -26,14 +26,14 @@
 
 class File(object):
     
-    def __init__(self, path):
+    def __init__(self, path, name):
         self.path = path
 
         f = open(path, 'rb')
         data = f.read()
         f.close()
         self.content_type, enc = guess_content_type(path, data)
-        self.__name__ = posixpath.basename(path)
+        self.__name__ = name
         self.lmt = float(os.path.getmtime(path)) or time()
         self.lmh = rfc1123_date(self.lmt)
 
@@ -41,8 +41,8 @@
 class Image(File):
     """Image objects stored in external files."""
 
-    def __init__(self, path):
-        super(Image, self).__init__(path)
+    def __init__(self, path, name):
+        super(Image, self).__init__(path, name)
         if self.content_type in (None, 'application/octet-stream'):
             ext = os.path.splitext(self.path)[1]
             if ext:



More information about the Zope3-Checkins mailing list