[Checkins] SVN: zope.container/trunk/src/zope/container/ make filepresentation work for zope.container.folder.Folder
Jan-Wijbrand Kolman
janwijbrand at gmail.com
Fri Jan 30 06:53:14 EST 2009
Log message for revision 95545:
make filepresentation work for zope.container.folder.Folder
Changed:
U zope.container/trunk/src/zope/container/configure.zcml
U zope.container/trunk/src/zope/container/directory.py
U zope.container/trunk/src/zope/container/folder.py
U zope.container/trunk/src/zope/container/interfaces.py
A zope.container/trunk/src/zope/container/tests/directory.txt
U zope.container/trunk/src/zope/container/tests/test_directory.py
-=-
Modified: zope.container/trunk/src/zope/container/configure.zcml
===================================================================
--- zope.container/trunk/src/zope/container/configure.zcml 2009-01-30 11:27:03 UTC (rev 95544)
+++ zope.container/trunk/src/zope/container/configure.zcml 2009-01-30 11:53:13 UTC (rev 95545)
@@ -5,6 +5,11 @@
i18n_domain="zope"
>
+ <interface
+ interface=".interfaces.IContentContainer"
+ type="zope.app.content.interfaces.IContentType"
+ />
+
<adapter
provides=".interfaces.IFind"
for=".interfaces.IReadContainer"
@@ -25,6 +30,20 @@
/>
<adapter
+ for=".interfaces.IContentContainer"
+ provides="zope.filerepresentation.interfaces.IDirectoryFactory"
+ factory="zope.container.directory.Cloner"
+ permission="zope.ManageContent"
+ />
+
+ <adapter
+ for=".interfaces.IContentContainer"
+ provides="zope.filerepresentation.interfaces.IReadDirectory"
+ factory=".filerepresentation.ReadDirectory"
+ permission="zope.View"
+ />
+
+ <adapter
factory="zope.container.traversal.ContainerTraversable"
provides="zope.traversing.interfaces.ITraversable"
for="zope.container.interfaces.IReadContainer"
Modified: zope.container/trunk/src/zope/container/directory.py
===================================================================
--- zope.container/trunk/src/zope/container/directory.py 2009-01-30 11:27:03 UTC (rev 95544)
+++ zope.container/trunk/src/zope/container/directory.py 2009-01-30 11:53:13 UTC (rev 95545)
@@ -25,10 +25,14 @@
"""
__docformat__ = 'restructuredtext'
-import zope.filerepresentation.interfaces
-from zope.security.proxy import removeSecurityProxy
from zope.interface import implements
+from zope.location.interfaces import ISite
+from zope.security.proxy import removeSecurityProxy
+import zope.filerepresentation.interfaces
+
+MARKER = object()
+
def noop(container):
"""Adapt an `IContainer` to an `IWriteDirectory` by just returning it
@@ -60,3 +64,55 @@
# exciting side effects as a result of instantiation. :)
return removeSecurityProxy(self.context).__class__()
+
+
+class RootDirectoryFactory(object):
+
+ def __init__(self, context):
+ pass
+
+ def __call__(self, name):
+ return Folder()
+
+
+class ReadDirectory(object):
+ """Adapter to provide a file-system rendition of folders."""
+
+ def __init__(self, context):
+ self.context = context
+
+ def keys(self):
+ keys = self.context.keys()
+ if ISite.providedBy(self.context):
+ return list(keys) + ['++etc++site']
+ return keys
+
+ def get(self, key, default=None):
+ if key == '++etc++site' and ISite.providedBy(self.context):
+ return self.context.getSiteManager()
+ return self.context.get(key, default)
+
+ def __iter__(self):
+ return iter(self.keys())
+
+ def __getitem__(self, key):
+ v = self.get(key, MARKER)
+ if v is MARKER:
+ raise KeyError(key)
+ return v
+
+ def values(self):
+ return map(self.get, self.keys())
+
+ def __len__(self):
+ l = len(self.context)
+ if ISite.providedBy(self.context):
+ l += 1
+ return l
+
+ def items(self):
+ get = self.get
+ return [(key, get(key)) for key in self.keys()]
+
+ def __contains__(self, key):
+ return self.get(key) is not None
Modified: zope.container/trunk/src/zope/container/folder.py
===================================================================
--- zope.container/trunk/src/zope/container/folder.py 2009-01-30 11:27:03 UTC (rev 95544)
+++ zope.container/trunk/src/zope/container/folder.py 2009-01-30 11:53:13 UTC (rev 95545)
@@ -19,15 +19,21 @@
from BTrees.OOBTree import OOBTree
from persistent import Persistent
-from zope.container.interfaces import IContainer
+from zope.container.interfaces import IContainer, IContentContainer
from zope.container.contained import Contained, setitem, uncontained
from zope.exceptions import DuplicationError
from zope.interface import implements, directlyProvides
+# XXX This container implementation is really only used by
+# zope.site.folder.Folder. Please do not use it.
+
+# XXX Check whether this IContainer implementation cannot really
+# be replaced by the BTreeContainer.
+
class Folder(Persistent, Contained):
"""The standard Zope Folder implementation."""
- implements(IContainer)
+ implements(IContentContainer)
def __init__(self):
self.data = OOBTree()
Modified: zope.container/trunk/src/zope/container/interfaces.py
===================================================================
--- zope.container/trunk/src/zope/container/interfaces.py 2009-01-30 11:27:03 UTC (rev 95544)
+++ zope.container/trunk/src/zope/container/interfaces.py 2009-01-30 11:53:13 UTC (rev 95545)
@@ -126,6 +126,10 @@
"""Readable and writable content container."""
+class IContentContainer(IContainer):
+ """A container that is to be used as a content type."""
+
+
class IBTreeContainer(IContainer):
"""Container that supports BTree semantics for some methods."""
Added: zope.container/trunk/src/zope/container/tests/directory.txt
===================================================================
--- zope.container/trunk/src/zope/container/tests/directory.txt (rev 0)
+++ zope.container/trunk/src/zope/container/tests/directory.txt 2009-01-30 11:53:13 UTC (rev 95545)
@@ -0,0 +1,43 @@
+===============================
+File representation for folders
+===============================
+
+Folders can be represented in file-system-like protocols (e.g. FTP). An
+adapter abstracts some internals away and adds support for accessing the
+'++etc++site' folder from those protocols.
+
+ >>> from zope.container.folder import Folder
+ >>> from zope.container.directory import ReadDirectory
+ >>> folder = Folder()
+
+The new folder isn't a site manager and doesn't have any entries:
+
+ >>> fs_folder = ReadDirectory(folder)
+ >>> list(fs_folder.keys())
+ []
+ >>> fs_folder.get('test', )
+ >>> fs_folder['test']
+ Traceback (most recent call last):
+ KeyError: 'test'
+ >>> list(fs_folder.__iter__())
+ []
+ >>> fs_folder.values()
+ []
+ >>> len(fs_folder)
+ 0
+ >>> fs_folder.items()
+ []
+ >>> 'test' in fs_folder
+ False
+
+This is a short regression test for #728: we get a KeyError when trying to
+access non-existing entries:
+
+ >>> from zope.security.proxy import ProxyFactory
+ >>> from zope.security.checker import NamesChecker
+ >>> proxied_folder = ProxyFactory(fs_folder, NamesChecker(('get',)))
+ >>> proxied_fs_folder = ReadDirectory(proxied_folder)
+ >>> print proxied_fs_folder['i dont exist']
+ Traceback (most recent call last):
+ KeyError: 'i dont exist'
+
Modified: zope.container/trunk/src/zope/container/tests/test_directory.py
===================================================================
--- zope.container/trunk/src/zope/container/tests/test_directory.py 2009-01-30 11:27:03 UTC (rev 95544)
+++ zope.container/trunk/src/zope/container/tests/test_directory.py 2009-01-30 11:53:13 UTC (rev 95545)
@@ -16,6 +16,9 @@
$Id$
"""
from unittest import TestCase, TestSuite, main, makeSuite
+from zope.testing import doctest
+from zope.container import testing
+
import zope.container.directory
class Directory(object):
@@ -31,8 +34,12 @@
self.assertEqual(clone.__class__, d.__class__)
def test_suite():
+ flags = doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE
return TestSuite((
makeSuite(Test),
+ doctest.DocFileSuite("directory.txt",
+ setUp=testing.setUp, tearDown=testing.tearDown,
+ optionflags=flags),
))
if __name__=='__main__':
More information about the Checkins
mailing list