Commit 71bc46f4 authored by Jan-Wijbrand Kolman's avatar Jan-Wijbrand Kolman

make filepresentation work for zope.container.folder.Folder

parent 4c64fee3
......@@ -5,6 +5,11 @@
i18n_domain="zope"
>
<interface
interface=".interfaces.IContentContainer"
type="zope.app.content.interfaces.IContentType"
/>
<adapter
provides=".interfaces.IFind"
for=".interfaces.IReadContainer"
......@@ -24,6 +29,20 @@
factory=".directory.noop"
/>
<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"
......
......@@ -25,10 +25,14 @@ $Id$
"""
__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 @@ class Cloner(object):
# 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
......@@ -19,15 +19,21 @@ __docformat__ = 'restructuredtext'
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()
......
......@@ -126,6 +126,10 @@ class IContainer(IReadContainer, IWriteContainer):
"""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."""
......
===============================
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'
......@@ -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 @@ class Test(TestCase):
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__':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment