[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/Content/Folder - Folder.py:1.2 FolderLimit.py:1.2 LoadedFolder.py:1.2 LoadedFolderFields.py:1.2 OrderedFolder.py:1.2 RootFolder.py:1.2 __init__.py:1.2 folder.zcml:1.2
Jim Fulton
jim@zope.com
Mon, 10 Jun 2002 19:28:31 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Content/Folder
In directory cvs.zope.org:/tmp/cvs-serv17445/lib/python/Zope/App/OFS/Content/Folder
Added Files:
Folder.py FolderLimit.py LoadedFolder.py LoadedFolderFields.py
OrderedFolder.py RootFolder.py __init__.py folder.zcml
Log Message:
Merged Zope-3x-branch into newly forked Zope3 CVS Tree.
=== Zope3/lib/python/Zope/App/OFS/Content/Folder/Folder.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+from Zope.App.OFS.Container.IContainer import IContainer
+
+import Persistence
+from Persistence.BTrees.OOBTree import OOBTree
+from Zope.ComponentArchitecture.ServiceManagerContainer \
+ import ServiceManagerContainer
+
+from Zope.ComponentArchitecture.IServiceManagerContainer import \
+ IServiceManagerContainer
+from types import StringTypes
+from Zope.App.OFS.Annotation.IAnnotatable import IAnnotatable
+from Zope.App.OFS.Container.Exceptions import UnaddableError
+
+class IFolder(IContainer, IServiceManagerContainer):
+ """The standard Zope Folder object interface."""
+
+class Folder(Persistence.Persistent, ServiceManagerContainer):
+ """The standard Zope Folder implementation."""
+
+ __implements__ = IFolder, IAnnotatable
+
+ def __init__(self):
+ self.data = OOBTree()
+
+ def keys(self):
+ """Return a sequence-like object containing the names
+ associated with the objects that appear in the folder
+ """
+ return self.data.keys()
+
+ def __iter__(self):
+ return iter(self.data.keys())
+
+ def values(self):
+ """Return a sequence-like object containing the objects that
+ appear in the folder.
+ """
+ return self.data.values()
+
+ def items(self):
+ """Return a sequence-like object containing tuples of the form
+ (name, object) for the objects that appear in the folder.
+ """
+ return self.data.items()
+
+ def __getitem__(self, name):
+ """Return the named object, or the value of the default
+ argument if given and the named object is not found.
+ If no default is given and the object is not found a
+ KeyError is raised.
+ """
+ return self.data[name]
+
+ def get(self, name, default=None):
+ """Return the named object, or the value of the default
+ argument if given and the named object is not found.
+ If no default is given and the object is not found a
+ KeyError is raised.
+ """
+ return self.data.get(name, default)
+
+ def __contains__(self, name):
+ """Return true if the named object appears in the folder."""
+ return self.data.has_key(name)
+
+ def __len__(self):
+ """Return the number of objects in the folder."""
+ return len(self.data)
+
+ def setObject(self, name, object):
+ """Add the given object to the folder under the given name."""
+ if type(name) in StringTypes and len(name)==0:
+ raise ValueError
+ self.data[name] = object
+ return name
+
+ def __delitem__(self, name):
+ """Delete the named object from the folder. Raises a KeyError
+ if the object is not found."""
+ del self.data[name]
+
=== Zope3/lib/python/Zope/App/OFS/Content/Folder/FolderLimit.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from Zope.App.OFS.Container.IContainerLimit import IContainerLimit
+from Zope.App.OFS.Container.Exceptions import UnaddableError
+
+
+class FolderLimitExceededError(UnaddableError):
+ """Exception that is raised, when the limit of the folder was
+ reached."""
+ pass
+
+
+class FolderLimit:
+ """Implements a feature that allows to restrict the amount of items in
+ a Folder.
+ """
+
+ __implements__ = IContainerLimit
+
+ _limit = 1000
+
+ ############################################################
+ # Implementation methods for interface
+ # Zope.App.OFS.IContainerLimit
+
+ def setLimit(self, limit):
+ '''See interface IContainerLimit'''
+ self._limit = limit
+
+
+ def getLimit(self):
+ '''See interface IContainerLimit'''
+ return self._limit
+
+
+ def isLimitReached(self):
+ '''See interface IContainerLimit'''
+ if len(self) >= self._limit:
+ return 1
+ else:
+ return 0
+
+ #
+ ############################################################
=== Zope3/lib/python/Zope/App/OFS/Content/Folder/LoadedFolder.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""
+Revision information:
+$Id$
+
+Implemented LoadedFolder Functionality:
+
+- Order Folder items
+- Define a max amount of items possible
+
+Todo Functionality:
+
+- Define what content objects can be added (user)
+ + add the option to the configuration zpt
+ + how does the security work for this? like if this folder is
+ created under a folder that doesnt allow images for example?
+ so need to figure out how to get a list of "allowed" content
+ objects. also, will what can be added to this folder be
+ static or dynamic in the sence of if security settings change
+ will this folder know about it?
+"""
+
+from Folder import Folder, IFolder
+from FolderLimit import FolderLimit, FolderLimitExceededError
+from OrderedFolder import OrderedFolder
+from types import StringTypes
+
+from Zope.App.OFS.Container.Exceptions import UnaddableError
+
+class ILoadedFolder(IFolder):
+ """The standard Zope Loaded Folder object interface."""
+
+class LoadedFolder(Folder, FolderLimit, OrderedFolder):
+ """Implements some nice additional features to the regular
+ Folder.
+ """
+
+ __implements__ = (ILoadedFolder, Folder.__implements__,
+ FolderLimit.__implements__, OrderedFolder.__implements__)
+
+
+ # XXX Reimplementation of some of the IReadContainer API. Shrug.
+
+ def keys(self):
+ """Return a sequence-like object containing the names
+ associated with the objects that appear in the folder
+ """
+ return self._orderedIds
+
+
+ def values(self):
+ """Return a sequence-like object containing the objects that
+ appear in the folder.
+ """
+ result = []
+ for id in self.keys():
+ result.append(self.data[id])
+
+ return tuple(result)
+
+
+ def items(self):
+ """Return a sequence-like object containing tuples of the form
+ (name, object) for the objects that appear in the folder.
+ """
+ result = []
+ for id in self.keys():
+ result.append((id, self.data[id]))
+
+ return result
+
+
+ # XXX Reimplementation of some of the IWriteContainer API. Shrug again.
+
+ def setObject(self, name, object):
+ """Add the given object to the folder under the given name."""
+ if type(name) in StringTypes and len(name)==0:
+ raise ValueError
+ if self.isLimitReached():
+ raise FolderLimitExceededError(self, object,
+ 'The folder\'s limit (%d item%s) was exeeded.' %
+ (self.getLimit(), self.getLimit()==1 and "" or "s" ))
+ else:
+ self.data[name] = object
+ if name not in self._orderedIds:
+ self._orderedIds += (name,)
+
+ return name
+
+ def __delitem__(self, name):
+ """Delete the named object from the folder. Raises a KeyError
+ if the object is not found."""
+ del self.data[name]
+ ids = list(self._orderedIds)
+ ids.remove(name)
+ self._orderedIds = tuple(ids)
=== Zope3/lib/python/Zope/App/OFS/Content/Folder/LoadedFolderFields.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+
+
+from Zope.App.Formulator import getField
+
+
+LimitField = getField('IntegerField')(
+ id='limit',
+ title='Limit',
+ description='Limit of objects in the container.',
+ start=1,
+ default=1000 )
=== Zope3/lib/python/Zope/App/OFS/Content/Folder/OrderedFolder.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""
+Revision information:
+$Id$
+
+"""
+
+from Zope.App.OFS.Container.IOrderedContainer import IOrderedContainer
+from types import StringType
+
+
+class OrderedFolder:
+ """Adds the Ordering Feature to a Folder
+ """
+
+ __implements__ = IOrderedContainer
+
+ _orderedIds = ()
+
+
+ def moveObjectsByPositions(self, ids, positionDelta):
+ """ """
+
+ if type(ids) is StringType:
+ ids = (ids,)
+
+ # Interestingly enough, we need to switch the order when
+ # moving, so that the movements won't cancel each
+ # other
+ if positionDelta > 0:
+ ids = list(ids)
+ ids.reverse()
+
+ moved_objects = 0
+
+ for id in ids:
+ old_position = self.getObjectPosition(id)
+ new_position = old_position + positionDelta
+ # Make sure the new position makes sense and is valid
+ if not (old_position == new_position or
+ new_position > len(self) or
+ new_position < 0):
+
+ id_list = list(self._orderedIds)
+ # now delete the entry ...
+ id_list.remove(id)
+ # ... and now add it again
+ id_list.insert(new_position, id)
+ self._orderedIds = tuple(id_list)
+
+ moved_objects += 1
+
+ return moved_objects
+
+
+ ############################################################
+ # Implementation methods for interface
+ # Zope.App.OFS.IOrderedContainer
+
+ def getObjectPosition(self, id):
+ '''See interface IOrderedContainer'''
+
+ if id in self._orderedIds:
+ return list(self._orderedIds).index(id)
+ else:
+ # If the object was not found, throw an error.
+ # Yeah, that is good raise 'ObjectNotFound',
+ raise ( 'ObjectNotFound',
+ 'The object named %s was not found.' %id)
+
+
+ def moveObjectsDown(self, ids):
+ '''See interface IOrderedContainer'''
+ return self.moveObjectsByPositions(ids, +1)
+
+
+ def moveObjectsUp(self, ids):
+ '''See interface IOrderedContainer'''
+ return self.moveObjectsByPositions(ids, -1)
+
+
+ def moveObjectsToTop(self, ids):
+ '''See interface IOrderedContainer'''
+ if type(ids) is StringType:
+ ids = (ids,)
+
+ position_delta = - self.getObjectPosition(ids[0])
+ return self.moveObjectsByPositions(ids, position_delta)
+
+
+ def moveObjectsToBottom(self, ids):
+ '''See interface IOrderedContainer'''
+ if type(ids) is StringType:
+ ids = (ids,)
+
+ # Whee, we will do the reverse twice, but for going to the bottom
+ # there is no other choice.
+ ids = list(ids)
+ ids.reverse()
+
+ position_delta = len(self) - self.getObjectPosition(ids[-1]) - 1
+
+ return self.moveObjectsByPositions(ids, position_delta)
+
+
+ def moveObjectToPosition(self, id, position):
+ '''See interface IOrderedContainer'''
+ return self.moveObjectsByPositions(id,
+ position - self.getObjectPosition(id))
+
+ #
+ ############################################################
+
=== Zope3/lib/python/Zope/App/OFS/Content/Folder/RootFolder.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+from Folder import IFolder, Folder
+
+
+class IRootFolder(IFolder):
+ """The standard Zope root Folder object interface."""
+
+
+class RootFolder(Folder):
+ """The standard Zope root Folder implementation."""
+
+ __implements__ = Folder.__implements__, IRootFolder
+
+ def __call__(self):
+ return 'You have reached the wrong number (but the right ' \
+ 'object!). Please try again later.'
=== Zope3/lib/python/Zope/App/OFS/Content/Folder/__init__.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
=== Zope3/lib/python/Zope/App/OFS/Content/Folder/folder.zcml 1.1 => 1.2 ===
+ xmlns='http://namespaces.zope.org/zope'
+ xmlns:security='http://namespaces.zope.org/security'
+ xmlns:zmi='http://namespaces.zope.org/zmi'
+>
+
+ <!-- Simple Folder Directives -->
+
+ <content class=".Folder.">
+ <zmi:factory
+ id="Folder"
+ permission="Zope.ManageContent"
+ title="Son of Folder"
+ description="Minimal folder" />
+ <security:require
+ permission="Zope.View" />
+ <security:allow
+ interface="Zope.ComponentArchitecture.IServiceManagerContainer.IReadServiceManagerContainer"
+ />
+ <security:require
+ permission="Zope.ManageServices"
+ interface="Zope.ComponentArchitecture.IServiceManagerContainer.IWriteServiceManagerContainer"
+ />
+ <security:require
+ permission="Zope.View"
+ interface="Zope.App.OFS.Container.IContainer.IReadContainer" />
+ <security:require
+ permission="Zope.ManageContent"
+ interface="Zope.App.OFS.Container.IContainer.IWriteContainer" />
+ </content>
+
+ <!-- XXX Do we really need RootFolder? -->
+ <content class=".RootFolder.">
+ <security:mimic class=".Folder." />
+ </content>
+
+ <zmi:tabs for=".Folder.IFolder.">
+ <zmi:tab label="Contents" action="@@index.html"/>
+ <zmi:tab label="Role Permissions"
+ action="@@AllRolePermissions.html"/>
+ </zmi:tabs>
+
+
+ <!-- Loaded Folder Directives -->
+ <content class=".LoadedFolder.">
+ <zmi:factory
+ id="LoadedFolder"
+ permission="Zope.ManageContent"
+ title="Loaded Folder"
+ description="A Folder having all the goodies." />
+
+ <security:require
+ permission="Zope.View" />
+ <security:allow
+ interface="Zope.ComponentArchitecture.IServiceManagerContainer.IReadServiceManagerContainer"
+ />
+ <security:require
+ permission="Zope.ManageServices"
+ interface="Zope.ComponentArchitecture.IServiceManagerContainer.IWriteServiceManagerContainer"
+ />
+ <security:require
+ permission="Zope.View"
+ interface="Zope.App.OFS.Container.IContainer.IReadContainer"
+ />
+ <security:require
+ permission="Zope.ManageContent"
+ interface="Zope.App.OFS.Container.IContainer.IWriteContainer"
+ />
+ <security:require
+ permission="Zope.View"
+ interface="Zope.App.OFS.Container.IOrderedContainer.IReadOrderedContainer"
+ />
+ <security:require
+ permission="Zope.ManageContent"
+ interface="Zope.App.OFS.Container.IOrderedContainer.IWriteOrderedContainer"
+ />
+ <security:require
+ permission="Zope.View"
+ interface="Zope.App.OFS.Container.IContainerLimit.IReadContainerLimit"
+ />
+ <security:require
+ permission="Zope.ManageContent"
+ interface="Zope.App.OFS.Container.IContainerLimit.IWriteContainerLimit"
+ />
+ </content>
+
+ <adapter
+ factory="Zope.App.OFS.Annotation.AttributeAnnotations."
+ provides="Zope.App.OFS.Annotation.IAnnotations."
+ for=".Folder.IFolder." />
+
+ <zmi:tabs for="Zope.App.OFS.Container.IContainerLimit.">
+ <zmi:tab label="Limit" action="@@FolderLimitEditForm.html"/>
+ </zmi:tabs>
+
+ <zmi:tabs for=".LoadedFolder.ILoadedFolder.">
+ <zmi:tab label="Contents" action="@@index.html"/>
+ <zmi:tab label="Role Permissions"
+ action="@@AllRolePermissions.html"/>
+ </zmi:tabs>
+
+
+ <!-- Further Directives -->
+
+ <include package=".Views" file="views.zcml" />
+
+</zopeConfigure>