[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