[Zope-CVS] SVN: book/trunk/insensitivefolder/ Made a copy of zope.app.demo.insesitivefolder for the book, so that I have

Stephan Richter srichter at cosmos.phy.tufts.edu
Tue Aug 24 09:39:36 EDT 2004


Log message for revision 27240:
  Made a copy of zope.app.demo.insesitivefolder for the book, so that I have 
  better control of the changes and can provide all sample code at one 
  palce.
  
   --This line, and those below, will be ignored--
  
  A    insensitivefolder
  A    insensitivefolder/ftests.py
  AM   insensitivefolder/cifolder_icon.png
  A    insensitivefolder/configure.zcml
  A    insensitivefolder/__init__.py
  A    insensitivefolder/tests.py
  


Changed:
  A   book/trunk/insensitivefolder/
  A   book/trunk/insensitivefolder/__init__.py
  A   book/trunk/insensitivefolder/cifolder_icon.png
  A   book/trunk/insensitivefolder/configure.zcml
  A   book/trunk/insensitivefolder/ftests.py
  A   book/trunk/insensitivefolder/tests.py


-=-
Added: book/trunk/insensitivefolder/__init__.py
===================================================================
--- book/trunk/insensitivefolder/__init__.py	2004-08-23 23:55:09 UTC (rev 27239)
+++ book/trunk/insensitivefolder/__init__.py	2004-08-24 13:39:36 UTC (rev 27240)
@@ -0,0 +1,82 @@
+##############################################################################
+#
+# Copyright (c) 2003, 2004 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.
+#
+##############################################################################
+"""Case-Insensitive Traverser and Folder
+
+$Id: __init__.py 26729 2004-07-23 21:20:21Z pruggera $
+"""
+__docformat__ = 'restructuredtext'
+from zope.component.interfaces import IFactory
+from zope.interface import implements, implementedBy
+from zope.interface import directlyProvides, directlyProvidedBy 
+from zope.publisher.interfaces import NotFound
+
+from zope.app import zapi
+from zope.app.folder import Folder
+from zope.app.folder.interfaces import IFolder
+from zope.app.container.traversal import ContainerTraverser
+
+
+class CaseInsensitiveFolderTraverser(ContainerTraverser):
+
+    __used_for__ = ICaseInsensitiveFolder
+
+    def publishTraverse(self, request, name):
+        """See zope.publisher.interfaces.browser.IBrowserPublisher"""
+        subob = self._guessTraverse(name) 
+        if subob is None:
+            view = zapi.queryView(self.context, name, request)
+            if view is not None:
+                return view
+
+            raise NotFound(self.context, name, request)
+         
+        return subob
+
+    def _guessTraverse(self, name):
+        for key in self.context.keys():
+            if key.lower() == name.lower():
+                return self.context[key]
+        return None
+
+
+class ICaseInsensitiveFolder(IFolder):
+    """Marker for folders whose contained items keys are case insensitive.
+
+    When traversing in this folder, all names will be converted to lower
+    case. For example, if the traverser requests an item called 'Foo', in
+    reality the first item matching 'foo' or any upper-and-lowercase variants
+    are looked up in the container."""
+
+class CaseInsensitiveFolderFactory(object):
+    """A Factory that creates case-insensitive Folders."""
+    implements(IFactory)
+
+    title = "Case-Insensitive Folder Factory"
+    description = "A Factory that creates case-insensitive Folders."
+
+    def __call__(self):
+        """See zope.component.interfaces.IFactory
+
+        Create a folder and mark it as case insensitive.
+        """
+        folder = Folder()
+        directlyProvides(folder, directlyProvidedBy(folder),
+                         ICaseInsensitiveFolder)
+        return folder
+    
+    def getInterfaces(self):
+        """See zope.component.interfaces.IFactory"""
+        return implementedBy(Folder) + ICaseInsensitiveFolder
+
+caseInsensitiveFolderFactory = CaseInsensitiveFolderFactory()

Added: book/trunk/insensitivefolder/cifolder_icon.png
===================================================================
(Binary files differ)


Property changes on: book/trunk/insensitivefolder/cifolder_icon.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: book/trunk/insensitivefolder/configure.zcml
===================================================================
--- book/trunk/insensitivefolder/configure.zcml	2004-08-23 23:55:09 UTC (rev 27239)
+++ book/trunk/insensitivefolder/configure.zcml	2004-08-24 13:39:36 UTC (rev 27240)
@@ -0,0 +1,43 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:browser="http://namespaces.zope.org/browser"
+    i18n_domain="zope">
+
+
+  <!-- Register the Traverser -->
+  <view
+      for=".ICaseInsensitiveFolder"
+      type="zope.publisher.interfaces.browser.IBrowserRequest"
+      factory=".CaseInsensitiveFolderTraverser"
+      provides="zope.publisher.interfaces.browser.IBrowserPublisher"
+      permission="zope.Public"
+      />
+
+  <view
+      for=".ICaseInsensitiveFolder"
+      type="zope.publisher.interfaces.xmlrpc.IXMLRPCRequest"
+      factory=".CaseInsensitiveFolderTraverser"
+      provides="zope.publisher.interfaces.xmlrpc.IXMLRPCPublisher"
+      permission="zope.Public"
+      />
+
+<!-- Case-insensitive Folder Registration -->
+<factory
+    id="zope.CaseInsensitiveFolder"
+    component=".caseInsensitiveFolderFactory"
+    />
+
+<browser:addMenuItem
+    factory="zope.CaseInsensitiveFolder"
+    title="Case insensitive Folder" 
+    description="A simple case insensitive Folder." 
+    permission="zope.ManageContent"
+    />
+
+<browser:icon
+    name="zmi_icon"
+    for=".ICaseInsensitiveFolder"
+    file="cifolder_icon.png"
+    />
+
+</configure>
\ No newline at end of file

Added: book/trunk/insensitivefolder/ftests.py
===================================================================
--- book/trunk/insensitivefolder/ftests.py	2004-08-23 23:55:09 UTC (rev 27239)
+++ book/trunk/insensitivefolder/ftests.py	2004-08-24 13:39:36 UTC (rev 27240)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2003, 2004 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.
+#
+##############################################################################
+"""Functional tests for the case-insensitive traverser and folder.
+
+$Id: ftests.py 25177 2004-06-02 13:17:31Z jim $
+"""
+import unittest
+from zope.app.tests.functional import BrowserTestCase
+from zope.publisher.interfaces import NotFound
+
+class TestCaseInsensitiveFolder(BrowserTestCase):
+
+    def testAddCaseInsensitiveFolder(self):
+        # Step 1: add the case insensitive folder
+        response = self.publish(
+            '/+/action.html',
+            basic='mgr:mgrpw',
+            form={'type_name': u'zope.CaseInsensitiveFolder',
+                  'id': u'cisf'})
+        self.assertEqual(response.getStatus(), 302)
+        self.assertEqual(response.getHeader('Location'),
+                         'http://localhost/@@contents.html')
+        # Step 2: add the file
+        response = self.publish('/cisf/+/action.html',
+                                basic='mgr:mgrpw',
+                                form={'type_name': u'zope.app.content.File',
+                                      'id': u'foo'})
+        self.assertEqual(response.getStatus(), 302)
+        self.assertEqual(response.getHeader('Location'),
+                         'http://localhost/cisf/@@contents.html')
+        # Step 3: check that the file is traversed
+        response = self.publish('/cisf/foo')
+        self.assertEqual(response.getStatus(), 200)
+        response = self.publish('/cisf/foO')
+        self.assertEqual(response.getStatus(), 200)
+        self.assertRaises(NotFound, self.publish, '/cisf/bar')
+                          
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(TestCaseInsensitiveFolder),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: book/trunk/insensitivefolder/tests.py
===================================================================
--- book/trunk/insensitivefolder/tests.py	2004-08-23 23:55:09 UTC (rev 27239)
+++ book/trunk/insensitivefolder/tests.py	2004-08-24 13:39:36 UTC (rev 27240)
@@ -0,0 +1,54 @@
+##############################################################################
+#
+# Copyright (c) 2003, 2004 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 the case-insensitive Folder.
+
+$Id: tests.py 25177 2004-06-02 13:17:31Z jim $
+"""
+import unittest
+from zope.app.container.tests import test_containertraverser  
+from book.insensitivefolder import CaseInsensitiveContainerTraverser
+
+class Container(test_containertraverser.TestContainer):
+
+    def keys(self):
+        return self.__dict__.keys()
+
+    def __getitem__(self, name):
+        return self.__dict__[name]
+
+
+class InsensitiveCaseTraverserTest(test_containertraverser.TraverserTest):
+
+    def _getTraverser(self, context, request):
+        return CaseInsensitiveContainerTraverser(context, request)
+
+    def _getContainer(self, **kw):
+        return Container(**kw)
+        
+    def test_allLowerCaseItemTraversal(self):
+        self.assertEquals(
+            self.traverser.publishTraverse(self.request, 'foo'),
+            self.foo)
+        self.assertEquals(
+            self.traverser.publishTraverse(self.request, 'foO'),
+            self.foo)
+
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(InsensitiveCaseTraverserTest),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')



More information about the Zope-CVS mailing list