zope.app.container-3.9.2/0000775000177100020040000000000011707310374016373 5ustar menesismenesis00000000000000zope.app.container-3.9.2/setup.py0000664000177100020040000000612111707310352020101 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2006 Zope Foundation 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. # ############################################################################## """Setup for zope.app.container package $Id: setup.py 124145 2012-01-23 16:54:20Z menesis $ """ import os from setuptools import setup, find_packages def read(*rnames): return open(os.path.join(os.path.dirname(__file__), *rnames)).read() setup(name='zope.app.container', version='3.9.2', author='Zope Corporation and Contributors', author_email='zope-dev@zope.org', description='Zope Container', long_description=( read('README.txt') + '\n\n' + read('CHANGES.txt') ), keywords = "zope3 container", classifiers = [ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: Zope Public License', 'Programming Language :: Python', 'Natural Language :: English', 'Operating System :: OS Independent', 'Topic :: Internet :: WWW/HTTP', 'Framework :: Zope3'], url='http://cheeseshop.python.org/pypi/zope.app.container', license='ZPL 2.1', packages=find_packages('src'), package_dir = {'': 'src'}, namespace_packages=['zope', 'zope.app'], extras_require=dict(test=['zope.app.testing', 'zope.app.zcmlfiles', 'zope.login', 'zope.password', 'zope.securitypolicy', 'zope.schema', 'zope.site', ]), install_requires=['setuptools', 'zope.browser', 'zope.browsermenu', 'zope.browserpage', 'zope.component', 'zope.container', 'zope.copypastemove', 'zope.dublincore >= 3.7', 'zope.event', 'zope.exceptions', 'zope.i18n', 'zope.i18nmessageid', 'zope.interface', 'zope.lifecycleevent', 'zope.location', 'zope.publisher >= 3.12', 'zope.security', 'zope.size', 'zope.traversing', ], include_package_data = True, zip_safe = False, ) zope.app.container-3.9.2/CHANGES.txt0000664000177100020040000001100611707310352020176 0ustar menesismenesis00000000000000======= CHANGES ======= 3.9.2 (2012-01-23) ------------------ - Replaced an undeclared test dependency on ``zope.app.authentication`` with ``zope.password``. - Removed undeclared test dependency on ``zope.app.folder``. - Replaced the use of ``zope.app.pagetemplate`` and deprecated ``zope.app.publisher`` with ``zope.browserpage`` and ``zope.browsermenu``. 3.9.1 (2010-09-14) ------------------ - Removed a testing dependency on ``zope.app.file``. - Replaced a testing dependency on ``zope.app.securitypolicy`` with the base ``zope.securitypolicy`` distribution. 3.9.0 (2010-08-19) ------------------ - Updated ``ftesting.zcml`` to use the new permission names exported by ``zope.dublincore`` 3.7. 3.8.2 (2010-01-08) ------------------ - Fixed tests using a newer zope.publisher that requires zope.login. 3.8.1 (2009-12-26) ------------------ - Fixed test_directive. Some parts of zope.app.publisher were moved to zope.browsermenu and zope.browserpage. - Moved tests/test_view_permissions.py to browser/tests. - Added undeclared install dependency on ``zope.app.publisher``. - Test no longer use deprecated ``zope.testing.doctestunit`` but python's ``doctest`` instead. 3.8.0 (2009-05-13) ------------------ - Moved ``IAdding`` interface to ``zope.browser.interfaces``, leaving BBB imports. 3.7.2 (2009-03-12) ------------------ - Show a "nothing to add" message instead of empty list in the adding view, if there's nothing to add. - Don't show the "Add" menu item if there's nothing to add. - Adapt to the removal of deprecated interfaces from ``zope.component.interfaces``. Now ``IAdding`` inherits from ``zope.publisher.interfaces.browser.IBrowserView``. 3.7.1 (2009-02-05) ------------------- - Updated test to accomodate "Pythonic" exception now raised from ``__setitem__`` provided by ``zope.container`` (``KeyError`` instead of ``zope.exceptions.UserError``). 3.7.0 (2009-01-31) ------------------ - Remove long-time deprecated ``IContentContainer`` class. - We now rely on a new package called ``zope.container``, which contains the basic implementation of ``zope.container`` and is intended to have less dependencies. We have gone through a wide range of packages and updated their dependencies to point to ``zope.container`` so that they will also have less indirect dependencies. For backwards compatibility we have left the original modules in ``zope.app.container`` in place and have placed imports to make sure the symbols exist in their original locations. 3.6.2 (2008-10-21) ------------------ - Fixed bug in ``_zope_app_container_contained.c``. 3.6.1 (2008-10-15) ------------------ - Reimplemented the ``BTreeContainer`` so that it directly accesses the btree methods (removed an old #TODO) - Removed usage of deprecated ``LayerField``. - Made C code compatible with Python 2.5 on 64bit architectures. - Fixed bug: Error thrown during ``__setitem__`` for an ordered container leaves bad key in order - Fixed https://bugs.launchpad.net/zope3/+bug/238579, https://bugs.launchpad.net/zope3/+bug/163149: Error with unicode traversing - Fixed https://bugs.launchpad.net/zope3/+bug/221025: The Adding menu is sorted with translated item by using a collator (better localized sorting) - Fixed https://bugs.launchpad.net/zope3/+bug/227617: - prevent the namechooser from failing on '+', '@' and '/' - added tests in the namechooser - be sure the name chooser returns unicode - Fixed https://bugs.launchpad.net/zope3/+bug/175388: The setitem's size modification is now done in ``setitemf``: setting an existing item does not change the size, and the event subscribers should see the new size instead of the old size. 3.6.0 (2008-05-06) ------------------ - Added an ``IBTreeContainer`` interface that allows an argument to the ``items``, ``keys``, and ``values`` methods with the same semantics as for a BTree object. The extended interface is implemented by the ``BTreeContainer`` class. 3.5 (2007-10-11) ---------------- - Updated bootstrap script to current version. - Store length of ``BTreeContainer`` in its own ``Length`` object for faster ``__len__`` implementation of huge containers. - Send ``IObjectModifiedEvent`` when changing the title through the ``@@contents.html`` view. This fixes https://bugs.edge.launchpad.net/zope3/+bug/98483. - Resolve ``ZopeSecurityPolicy`` and ``IRolePermissionManager`` deprecation warning. 3.4 (2007-04-22) ---------------- - Initial release as a separate project, corresponds to ``zope.app.container`` from Zope 3.4.0a1. zope.app.container-3.9.2/PKG-INFO0000664000177100020040000001514511707310374017476 0ustar menesismenesis00000000000000Metadata-Version: 1.1 Name: zope.app.container Version: 3.9.2 Summary: Zope Container Home-page: http://cheeseshop.python.org/pypi/zope.app.container Author: Zope Corporation and Contributors Author-email: zope-dev@zope.org License: ZPL 2.1 Description: This package define interfaces of container components, and provides sample container implementations such as a BTreeContainer and OrderedContainer. ======= CHANGES ======= 3.9.2 (2012-01-23) ------------------ - Replaced an undeclared test dependency on ``zope.app.authentication`` with ``zope.password``. - Removed undeclared test dependency on ``zope.app.folder``. - Replaced the use of ``zope.app.pagetemplate`` and deprecated ``zope.app.publisher`` with ``zope.browserpage`` and ``zope.browsermenu``. 3.9.1 (2010-09-14) ------------------ - Removed a testing dependency on ``zope.app.file``. - Replaced a testing dependency on ``zope.app.securitypolicy`` with the base ``zope.securitypolicy`` distribution. 3.9.0 (2010-08-19) ------------------ - Updated ``ftesting.zcml`` to use the new permission names exported by ``zope.dublincore`` 3.7. 3.8.2 (2010-01-08) ------------------ - Fixed tests using a newer zope.publisher that requires zope.login. 3.8.1 (2009-12-26) ------------------ - Fixed test_directive. Some parts of zope.app.publisher were moved to zope.browsermenu and zope.browserpage. - Moved tests/test_view_permissions.py to browser/tests. - Added undeclared install dependency on ``zope.app.publisher``. - Test no longer use deprecated ``zope.testing.doctestunit`` but python's ``doctest`` instead. 3.8.0 (2009-05-13) ------------------ - Moved ``IAdding`` interface to ``zope.browser.interfaces``, leaving BBB imports. 3.7.2 (2009-03-12) ------------------ - Show a "nothing to add" message instead of empty list in the adding view, if there's nothing to add. - Don't show the "Add" menu item if there's nothing to add. - Adapt to the removal of deprecated interfaces from ``zope.component.interfaces``. Now ``IAdding`` inherits from ``zope.publisher.interfaces.browser.IBrowserView``. 3.7.1 (2009-02-05) ------------------- - Updated test to accomodate "Pythonic" exception now raised from ``__setitem__`` provided by ``zope.container`` (``KeyError`` instead of ``zope.exceptions.UserError``). 3.7.0 (2009-01-31) ------------------ - Remove long-time deprecated ``IContentContainer`` class. - We now rely on a new package called ``zope.container``, which contains the basic implementation of ``zope.container`` and is intended to have less dependencies. We have gone through a wide range of packages and updated their dependencies to point to ``zope.container`` so that they will also have less indirect dependencies. For backwards compatibility we have left the original modules in ``zope.app.container`` in place and have placed imports to make sure the symbols exist in their original locations. 3.6.2 (2008-10-21) ------------------ - Fixed bug in ``_zope_app_container_contained.c``. 3.6.1 (2008-10-15) ------------------ - Reimplemented the ``BTreeContainer`` so that it directly accesses the btree methods (removed an old #TODO) - Removed usage of deprecated ``LayerField``. - Made C code compatible with Python 2.5 on 64bit architectures. - Fixed bug: Error thrown during ``__setitem__`` for an ordered container leaves bad key in order - Fixed https://bugs.launchpad.net/zope3/+bug/238579, https://bugs.launchpad.net/zope3/+bug/163149: Error with unicode traversing - Fixed https://bugs.launchpad.net/zope3/+bug/221025: The Adding menu is sorted with translated item by using a collator (better localized sorting) - Fixed https://bugs.launchpad.net/zope3/+bug/227617: - prevent the namechooser from failing on '+', '@' and '/' - added tests in the namechooser - be sure the name chooser returns unicode - Fixed https://bugs.launchpad.net/zope3/+bug/175388: The setitem's size modification is now done in ``setitemf``: setting an existing item does not change the size, and the event subscribers should see the new size instead of the old size. 3.6.0 (2008-05-06) ------------------ - Added an ``IBTreeContainer`` interface that allows an argument to the ``items``, ``keys``, and ``values`` methods with the same semantics as for a BTree object. The extended interface is implemented by the ``BTreeContainer`` class. 3.5 (2007-10-11) ---------------- - Updated bootstrap script to current version. - Store length of ``BTreeContainer`` in its own ``Length`` object for faster ``__len__`` implementation of huge containers. - Send ``IObjectModifiedEvent`` when changing the title through the ``@@contents.html`` view. This fixes https://bugs.edge.launchpad.net/zope3/+bug/98483. - Resolve ``ZopeSecurityPolicy`` and ``IRolePermissionManager`` deprecation warning. 3.4 (2007-04-22) ---------------- - Initial release as a separate project, corresponds to ``zope.app.container`` from Zope 3.4.0a1. Keywords: zope3 container Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Zope Public License Classifier: Programming Language :: Python Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Topic :: Internet :: WWW/HTTP Classifier: Framework :: Zope3 zope.app.container-3.9.2/bootstrap.py0000664000177100020040000000350211707310352020756 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2006 Zope Foundation 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. # ############################################################################## """Bootstrap a buildout-based project Simply run this script in a directory containing a buildout.cfg. The script accepts buildout command-line options, so you can use the -c option to specify an alternate configuration file. $Id: bootstrap.py 124135 2012-01-23 15:32:45Z menesis $ """ import os, shutil, sys, tempfile, urllib2 tmpeggs = tempfile.mkdtemp() try: import pkg_resources except ImportError: ez = {} exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' ).read() in ez ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) import pkg_resources cmd = 'from setuptools.command.easy_install import main; main()' if sys.platform == 'win32': cmd = '"%s"' % cmd # work around spawn lamosity on windows ws = pkg_resources.working_set assert os.spawnle( os.P_WAIT, sys.executable, sys.executable, '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout', dict(os.environ, PYTHONPATH= ws.find(pkg_resources.Requirement.parse('setuptools')).location ), ) == 0 ws.add_entry(tmpeggs) ws.require('zc.buildout') import zc.buildout.buildout zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap']) shutil.rmtree(tmpeggs) zope.app.container-3.9.2/COPYRIGHT.txt0000664000177100020040000000004011707310352020472 0ustar menesismenesis00000000000000Zope Foundation and Contributorszope.app.container-3.9.2/src/0000775000177100020040000000000011707310374017162 5ustar menesismenesis00000000000000zope.app.container-3.9.2/src/zope.app.container.egg-info/0000775000177100020040000000000011707310374024371 5ustar menesismenesis00000000000000zope.app.container-3.9.2/src/zope.app.container.egg-info/PKG-INFO0000664000177100020040000001514511707310367025476 0ustar menesismenesis00000000000000Metadata-Version: 1.1 Name: zope.app.container Version: 3.9.2 Summary: Zope Container Home-page: http://cheeseshop.python.org/pypi/zope.app.container Author: Zope Corporation and Contributors Author-email: zope-dev@zope.org License: ZPL 2.1 Description: This package define interfaces of container components, and provides sample container implementations such as a BTreeContainer and OrderedContainer. ======= CHANGES ======= 3.9.2 (2012-01-23) ------------------ - Replaced an undeclared test dependency on ``zope.app.authentication`` with ``zope.password``. - Removed undeclared test dependency on ``zope.app.folder``. - Replaced the use of ``zope.app.pagetemplate`` and deprecated ``zope.app.publisher`` with ``zope.browserpage`` and ``zope.browsermenu``. 3.9.1 (2010-09-14) ------------------ - Removed a testing dependency on ``zope.app.file``. - Replaced a testing dependency on ``zope.app.securitypolicy`` with the base ``zope.securitypolicy`` distribution. 3.9.0 (2010-08-19) ------------------ - Updated ``ftesting.zcml`` to use the new permission names exported by ``zope.dublincore`` 3.7. 3.8.2 (2010-01-08) ------------------ - Fixed tests using a newer zope.publisher that requires zope.login. 3.8.1 (2009-12-26) ------------------ - Fixed test_directive. Some parts of zope.app.publisher were moved to zope.browsermenu and zope.browserpage. - Moved tests/test_view_permissions.py to browser/tests. - Added undeclared install dependency on ``zope.app.publisher``. - Test no longer use deprecated ``zope.testing.doctestunit`` but python's ``doctest`` instead. 3.8.0 (2009-05-13) ------------------ - Moved ``IAdding`` interface to ``zope.browser.interfaces``, leaving BBB imports. 3.7.2 (2009-03-12) ------------------ - Show a "nothing to add" message instead of empty list in the adding view, if there's nothing to add. - Don't show the "Add" menu item if there's nothing to add. - Adapt to the removal of deprecated interfaces from ``zope.component.interfaces``. Now ``IAdding`` inherits from ``zope.publisher.interfaces.browser.IBrowserView``. 3.7.1 (2009-02-05) ------------------- - Updated test to accomodate "Pythonic" exception now raised from ``__setitem__`` provided by ``zope.container`` (``KeyError`` instead of ``zope.exceptions.UserError``). 3.7.0 (2009-01-31) ------------------ - Remove long-time deprecated ``IContentContainer`` class. - We now rely on a new package called ``zope.container``, which contains the basic implementation of ``zope.container`` and is intended to have less dependencies. We have gone through a wide range of packages and updated their dependencies to point to ``zope.container`` so that they will also have less indirect dependencies. For backwards compatibility we have left the original modules in ``zope.app.container`` in place and have placed imports to make sure the symbols exist in their original locations. 3.6.2 (2008-10-21) ------------------ - Fixed bug in ``_zope_app_container_contained.c``. 3.6.1 (2008-10-15) ------------------ - Reimplemented the ``BTreeContainer`` so that it directly accesses the btree methods (removed an old #TODO) - Removed usage of deprecated ``LayerField``. - Made C code compatible with Python 2.5 on 64bit architectures. - Fixed bug: Error thrown during ``__setitem__`` for an ordered container leaves bad key in order - Fixed https://bugs.launchpad.net/zope3/+bug/238579, https://bugs.launchpad.net/zope3/+bug/163149: Error with unicode traversing - Fixed https://bugs.launchpad.net/zope3/+bug/221025: The Adding menu is sorted with translated item by using a collator (better localized sorting) - Fixed https://bugs.launchpad.net/zope3/+bug/227617: - prevent the namechooser from failing on '+', '@' and '/' - added tests in the namechooser - be sure the name chooser returns unicode - Fixed https://bugs.launchpad.net/zope3/+bug/175388: The setitem's size modification is now done in ``setitemf``: setting an existing item does not change the size, and the event subscribers should see the new size instead of the old size. 3.6.0 (2008-05-06) ------------------ - Added an ``IBTreeContainer`` interface that allows an argument to the ``items``, ``keys``, and ``values`` methods with the same semantics as for a BTree object. The extended interface is implemented by the ``BTreeContainer`` class. 3.5 (2007-10-11) ---------------- - Updated bootstrap script to current version. - Store length of ``BTreeContainer`` in its own ``Length`` object for faster ``__len__`` implementation of huge containers. - Send ``IObjectModifiedEvent`` when changing the title through the ``@@contents.html`` view. This fixes https://bugs.edge.launchpad.net/zope3/+bug/98483. - Resolve ``ZopeSecurityPolicy`` and ``IRolePermissionManager`` deprecation warning. 3.4 (2007-04-22) ---------------- - Initial release as a separate project, corresponds to ``zope.app.container`` from Zope 3.4.0a1. Keywords: zope3 container Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Zope Public License Classifier: Programming Language :: Python Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Topic :: Internet :: WWW/HTTP Classifier: Framework :: Zope3 zope.app.container-3.9.2/src/zope.app.container.egg-info/dependency_links.txt0000664000177100020040000000000111707310367030441 0ustar menesismenesis00000000000000 zope.app.container-3.9.2/src/zope.app.container.egg-info/namespace_packages.txt0000664000177100020040000000001611707310367030723 0ustar menesismenesis00000000000000zope zope.app zope.app.container-3.9.2/src/zope.app.container.egg-info/not-zip-safe0000664000177100020040000000000111707310353026614 0ustar menesismenesis00000000000000 zope.app.container-3.9.2/src/zope.app.container.egg-info/top_level.txt0000664000177100020040000000000511707310367027120 0ustar menesismenesis00000000000000zope zope.app.container-3.9.2/src/zope.app.container.egg-info/requires.txt0000664000177100020040000000063011707310367026772 0ustar menesismenesis00000000000000setuptools zope.browser zope.browsermenu zope.browserpage zope.component zope.container zope.copypastemove zope.dublincore >= 3.7 zope.event zope.exceptions zope.i18n zope.i18nmessageid zope.interface zope.lifecycleevent zope.location zope.publisher >= 3.12 zope.security zope.size zope.traversing [test] zope.app.testing zope.app.zcmlfiles zope.login zope.password zope.securitypolicy zope.schema zope.sitezope.app.container-3.9.2/src/zope.app.container.egg-info/SOURCES.txt0000664000177100020040000000377511707310367026273 0ustar menesismenesis00000000000000CHANGES.txt COPYRIGHT.txt LICENSE.txt README.txt bootstrap.py buildout.cfg setup.py src/zope/__init__.py src/zope.app.container.egg-info/PKG-INFO src/zope.app.container.egg-info/SOURCES.txt src/zope.app.container.egg-info/dependency_links.txt src/zope.app.container.egg-info/namespace_packages.txt src/zope.app.container.egg-info/not-zip-safe src/zope.app.container.egg-info/requires.txt src/zope.app.container.egg-info/top_level.txt src/zope/app/__init__.py src/zope/app/container/__init__.py src/zope/app/container/btree.py src/zope/app/container/configure.zcml src/zope/app/container/constraints.py src/zope/app/container/contained.py src/zope/app/container/dependency.py src/zope/app/container/directory.py src/zope/app/container/find.py src/zope/app/container/ftesting.zcml src/zope/app/container/i18n.py src/zope/app/container/interfaces.py src/zope/app/container/ordered.py src/zope/app/container/sample.py src/zope/app/container/size.py src/zope/app/container/testing.py src/zope/app/container/traversal.py src/zope/app/container/browser/__init__.py src/zope/app/container/browser/add.pt src/zope/app/container/browser/adding.py src/zope/app/container/browser/commontasks.pt src/zope/app/container/browser/configure.zcml src/zope/app/container/browser/contents.pt src/zope/app/container/browser/contents.py src/zope/app/container/browser/find.pt src/zope/app/container/browser/find.py src/zope/app/container/browser/index.pt src/zope/app/container/browser/meta.zcml src/zope/app/container/browser/metaconfigure.py src/zope/app/container/browser/tests/__init__.py src/zope/app/container/browser/tests/configure.zcml src/zope/app/container/browser/tests/index.txt src/zope/app/container/browser/tests/test_adding.py src/zope/app/container/browser/tests/test_contents.py src/zope/app/container/browser/tests/test_contents_functional.py src/zope/app/container/browser/tests/test_directive.py src/zope/app/container/browser/tests/test_view_permissions.py src/zope/app/container/tests/__init__.py src/zope/app/container/tests/placelesssetup.pyzope.app.container-3.9.2/src/zope/0000775000177100020040000000000011707310374020137 5ustar menesismenesis00000000000000zope.app.container-3.9.2/src/zope/__init__.py0000664000177100020040000000031011707310352022236 0ustar menesismenesis00000000000000# this is a namespace package try: import pkg_resources pkg_resources.declare_namespace(__name__) except ImportError: import pkgutil __path__ = pkgutil.extend_path(__path__, __name__) zope.app.container-3.9.2/src/zope/app/0000775000177100020040000000000011707310374020717 5ustar menesismenesis00000000000000zope.app.container-3.9.2/src/zope/app/__init__.py0000664000177100020040000000031011707310352023016 0ustar menesismenesis00000000000000# this is a namespace package try: import pkg_resources pkg_resources.declare_namespace(__name__) except ImportError: import pkgutil __path__ = pkgutil.extend_path(__path__, __name__) zope.app.container-3.9.2/src/zope/app/container/0000775000177100020040000000000011707310374022701 5ustar menesismenesis00000000000000zope.app.container-3.9.2/src/zope/app/container/contained.py0000664000177100020040000000220211707310352025207 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2003 Zope Foundation 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. # ############################################################################## """BBB this module moved to zope.container """ # BBB from zope.container.contained import ( Contained, ObjectMovedEvent, ObjectAddedEvent, ObjectRemovedEvent, ContainerModifiedEvent, dispatchToSublocations, ContainerSublocations, containedEvent, contained, notifyContainerModified, setitem, fixing_up, uncontained, NameChooser, DecoratorSpecificationDescriptor, DecoratedSecurityCheckerDescriptor, ContainedProxyClassProvides, ContainedProxy, ) zope.app.container-3.9.2/src/zope/app/container/btree.py0000664000177100020040000000135011707310352024347 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """BBB this module moved to zope.container """ from zope.container.btree import BTreeContainer # BBB zope.app.container-3.9.2/src/zope/app/container/ordered.py0000664000177100020040000000135511707310352024677 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """BBB: this module moved to zope.container """ # BBB from zope.container.ordered import OrderedContainer zope.app.container-3.9.2/src/zope/app/container/tests/0000775000177100020040000000000011707310374024043 5ustar menesismenesis00000000000000zope.app.container-3.9.2/src/zope/app/container/tests/__init__.py0000664000177100020040000000007511707310352026152 0ustar menesismenesis00000000000000# # This file is necessary to make this directory a package. zope.app.container-3.9.2/src/zope/app/container/tests/placelesssetup.py0000664000177100020040000000174611707310352027455 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2002 Zope Foundation 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. # ############################################################################## """Unit test logic for setting up and tearing down basic infrastructure """ from zope.app.testing import ztapi from zope.app.container.interfaces import IWriteContainer, INameChooser from zope.app.container.contained import NameChooser class PlacelessSetup(object): def setUp(self): ztapi.provideAdapter(IWriteContainer, INameChooser, NameChooser) zope.app.container-3.9.2/src/zope/app/container/constraints.py0000664000177100020040000000165211707310352025622 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2003 Zope Foundation 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. # ############################################################################## """BBB this module moved to zope.container """ # BBB from zope.container.constraints import ( checkObject, checkFactory, IItemTypePrecondition, _TypesBased, ItemTypePrecondition, contains, IContainerTypesConstraint, ContainerTypesConstraint, containers ) zope.app.container-3.9.2/src/zope/app/container/configure.zcml0000664000177100020040000000035711707310352025552 0ustar menesismenesis00000000000000 zope.app.container-3.9.2/src/zope/app/container/find.py0000664000177100020040000000146711707310352024177 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """BBB: this module moved to zope.container """ # BBB from zope.container.find import ( FindAdapter, _find_helper, SimpleIdFindFilter, SimpleInterfacesFindFilter ) zope.app.container-3.9.2/src/zope/app/container/browser/0000775000177100020040000000000011707310374024364 5ustar menesismenesis00000000000000zope.app.container-3.9.2/src/zope/app/container/browser/meta.zcml0000664000177100020040000000061611707310352026200 0ustar menesismenesis00000000000000 zope.app.container-3.9.2/src/zope/app/container/browser/tests/0000775000177100020040000000000011707310374025526 5ustar menesismenesis00000000000000zope.app.container-3.9.2/src/zope/app/container/browser/tests/test_directive.py0000664000177100020040000002613311707310352031116 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2003 Zope Foundation 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. # ############################################################################## """'containerView' directive test """ import cStringIO import doctest import pprint import re import unittest from zope.interface import Interface from zope.publisher.interfaces.browser import IBrowserRequest from zope.app.container.browser.metaconfigure import containerViews atre = re.compile(' at [0-9a-fA-Fx]+') class Context(object): actions = () info = '' def action(self, discriminator, callable, args): self.actions += ((discriminator, callable, args), ) self.info = 'info' def __repr__(self): stream = cStringIO.StringIO() pprinter = pprint.PrettyPrinter(stream=stream, width=60) pprinter.pprint(self.actions) r = stream.getvalue() return (''.join(atre.split(r))).strip() class I(Interface): pass class ITestLayer(IBrowserRequest): pass def test_containerViews(): """ >>> from zope.browsermenu.metaconfigure import menus >>> from zope.interface.interface import InterfaceClass >>> zmi_views = InterfaceClass('zmi_views', __module__='zope.app.menus') >>> menus.zmi_views = zmi_views >>> zmi_actions = InterfaceClass('zmi_actions', __module__='zope.app.menus') >>> menus.zmi_actions = zmi_actions >>> context = Context() >>> containerViews(context, for_=I, contents='zope.ManageContent', ... add='zope.ManageContent', index='zope.View') >>> context ((('adapter', (, ), , u'Contents'), , ('registerAdapter', , (, ), , u'Contents', '')), (None, , ('', )), (None, , ('', )), (None, , ('', )), (None, , ('', )), (('view', , 'contents.html', , ), , ('registerAdapter', , (, ), , 'contents.html', 'info')), (None, , ('', )), (('view', , 'index.html', , ), , ('registerAdapter', , (, ), , 'index.html', 'info')), (('adapter', (, ), , u'Add'), , ('registerAdapter', , (, ), , u'Add', 'info')), (None, , ('', )), (None, , ('', )), (None, , ('', )), (None, , ('', )), (None, , ('', )), (('view', (, ), '+', ), , ('registerAdapter', , (, ), , '+', 'info'))) """ def test_containerViews_layer(): """ >>> from zope.browsermenu.metaconfigure import menus >>> from zope.interface.interface import InterfaceClass >>> zmi_views = InterfaceClass('zmi_views', __module__='zope.app.menus') >>> menus.zmi_views = zmi_views >>> zmi_actions = InterfaceClass('zmi_actions', __module__='zope.app.menus') >>> menus.zmi_actions = zmi_actions >>> context = Context() >>> containerViews(context, for_=I, contents='zope.ManageContent', ... add='zope.ManageContent', index='zope.View', layer=ITestLayer) >>> context ((('adapter', (, ), , u'Contents'), , ('registerAdapter', , (, ), , u'Contents', '')), (None, , ('', )), (None, , ('', )), (None, , ('', )), (None, , ('', )), (('view', , 'contents.html', , ), , ('registerAdapter', , (, ), , 'contents.html', 'info')), (None, , ('', )), (('view', , 'index.html', , ), , ('registerAdapter', , (, ), , 'index.html', 'info')), (('adapter', (, ), , u'Add'), , ('registerAdapter', , (, ), , u'Add', 'info')), (None, , ('', )), (None, , ('', )), (None, , ('', )), (None, , ('', )), (None, , ('', )), (('view', (, ), '+', ), , ('registerAdapter', , (, ), , '+', 'info'))) """ def test_suite(): return doctest.DocTestSuite() zope.app.container-3.9.2/src/zope/app/container/browser/tests/test_adding.py0000664000177100020040000004271711707310352030374 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2002 Zope Foundation 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. # ############################################################################## """Adding implementation tests """ import doctest import unittest import zope.interface import zope.security.checker from zope.component.interfaces import IFactory from zope.component.interfaces import ComponentLookupError from zope.interface import implements, Interface, directlyProvides from zope.publisher.browser import TestRequest from zope.publisher.interfaces.browser import IBrowserRequest from zope.publisher.browser import BrowserView from zope.browsermenu.interfaces import AddMenu from zope.browsermenu.interfaces import IMenuItemType, IBrowserMenu from zope.browsermenu.menu import BrowserMenuItem, BrowserMenu from zope.security.interfaces import ForbiddenAttribute from zope.exceptions.interfaces import UserError from zope.traversing.api import getParent from zope.traversing.browser import AbsoluteURL from zope.traversing.browser.absoluteurl import absoluteURL from zope.traversing.browser.interfaces import IAbsoluteURL from zope.traversing.interfaces import IContainmentRoot from zope.app.testing import ztapi from zope.app.testing.placelesssetup import PlacelessSetup, setUp, tearDown from zope.app.container.interfaces import IAdding from zope.app.container.interfaces import IObjectAddedEvent from zope.app.container.interfaces import IContainerNamesContainer from zope.app.container.interfaces import INameChooser from zope.app.container.interfaces import IContainer from zope.app.container.contained import contained from zope.app.container.browser.adding import Adding from zope.app.container.sample import SampleContainer class Root(object): implements(IContainmentRoot) class Container(SampleContainer): pass class CreationView(BrowserView): def action(self): return 'been there, done that' class Content(object): pass class Factory(object): implements(IFactory) title = '' description = '' def getInterfaces(self): return () def __call__(self): return Content() class AbsoluteURL(BrowserView): def __str__(self): if IContainmentRoot.providedBy(self.context): return '' name = self.context.__name__ url = absoluteURL(getParent(self.context), self.request) url += '/' + name return url __call__ = __str__ def defineMenuItem(menuItemType, for_, action, title=u'', extra=None): newclass = type(title, (BrowserMenuItem,), {'title':title, 'action':action, '_for': for_, 'extra':extra}) zope.interface.classImplements(newclass, menuItemType) ztapi.provideAdapter((for_, IBrowserRequest), menuItemType, newclass, title) def registerAddMenu(): ztapi.provideUtility(IMenuItemType, AddMenu, 'zope.app.container.add') ztapi.provideUtility(IBrowserMenu, BrowserMenu('zope.app.container.add', u'', u''), 'zope.app.container.add') class Test(PlacelessSetup, unittest.TestCase): def setUp(self): super(Test, self).setUp() def test(self): container = Container() request = TestRequest() adding = Adding(container, request) ztapi.browserView(IAdding, "Thing", CreationView) self.assertEqual(adding.contentName, None) view = adding.publishTraverse(request, 'Thing=foo') self.assertEqual(view.action(), 'been there, done that') self.assertEqual(adding.contentName, 'foo') o = object() result = adding.add(o) # Check the state of the container and result self.assertEqual(container["foo"], o) self.assertEqual(result, o) def testNoNameGiven(self): container = Container() request = TestRequest() adding = Adding(container, request) ztapi.browserView(IAdding, "Thing", CreationView) self.assertEqual(adding.contentName, None) view = adding.publishTraverse(request, 'Thing=') self.assertEqual(adding.contentName, '') def testAction(self): # make a private factory ztapi.provideUtility(IFactory, Factory(), 'fooprivate') factory = Factory() factory.__Security_checker__ = zope.security.checker.NamesChecker( ['__call__']) ztapi.provideUtility(IFactory, factory, 'foo') container = Container() adding = Adding(container, TestRequest()) adding.nextURL = lambda: '.' adding.nameAllowed = lambda: True # we can't use a private factory: self.assertRaises(ForbiddenAttribute, adding.action, type_name='fooprivate', id='bar') # typical add - id is provided by user adding.action(type_name='foo', id='bar') self.assert_('bar' in container) # missing type_name self.assertRaises(UserError, adding.action, id='bar') # missing id self.assertRaises(KeyError, adding.action, type_name='foo') # bad type_name self.assertRaises(ComponentLookupError, adding.action, type_name='***', id='bar') # alternative add - id is provided internally instead of from user adding.nameAllowed = lambda: False adding.contentName = 'baz' adding.action(type_name='foo') self.assert_('baz' in container) # alternative add w/missing contentName # Note: Passing is None as object name might be okay, if the container # is able to hand out ids itself. Let's not require a content # name to be specified! # For the container, (or really, the chooser, to choose, we have to # marke the container as a ContainerNamesContainer directlyProvides(container, IContainerNamesContainer) adding.contentName = None adding.action(type_name='foo') self.assert_('Content' in container) def test_action(self): container = Container() container = contained(container, Root(), "container") request = TestRequest() adding = Adding(container, request) adding.__name__ = '+' ztapi.browserView(IAdding, "Thing", CreationView) ztapi.browserView(Interface, "absolute_url", AbsoluteURL) ztapi.browserView(None, '', AbsoluteURL, providing=IAbsoluteURL) self.assertRaises(UserError, adding.action, '', 'foo') adding.action('Thing', 'foo') self.assertEqual(adding.request.response.getHeader('location'), '/container/+/Thing=foo') adding.action('Thing/screen1', 'foo') self.assertEqual(adding.request.response.getHeader('location'), '/container/+/Thing/screen1=foo') def test_publishTraverse_factory(self): factory = Factory() ztapi.provideUtility(IFactory, factory, 'foo') container = Container() request = TestRequest() adding = Adding(container, request) self.assert_(adding.publishTraverse(request, 'foo') is factory) def test_constraint_driven_addingInfo(): """ >>> registerAddMenu() >>> class TestMenu(zope.interface.Interface): ... pass >>> zope.interface.directlyProvides(TestMenu, IMenuItemType) >>> ztapi.provideUtility(IMenuItemType, TestMenu, 'TestMenu') >>> ztapi.provideUtility(IBrowserMenu, BrowserMenu('TestMenu', u'', u''), ... 'TestMenu') >>> defineMenuItem(TestMenu, IAdding, '', 'item1') >>> defineMenuItem(TestMenu, IAdding, '', 'Item2') >>> defineMenuItem(AddMenu, IAdding, '', 'item3', extra={'factory': 'f1'}) >>> defineMenuItem(AddMenu, IAdding, '', 'item4', extra={'factory': 'f2'}) >>> class F1(object): ... pass >>> class F2(object): ... pass >>> def pre(container, name, object): ... if not isinstance(object, F1): ... raise zope.interface.Invalid() >>> def prefactory(container, name, factory): ... if factory._callable is not F1: ... raise zope.interface.Invalid() >>> pre.factory = prefactory >>> class IContainer(zope.interface.Interface): ... def __setitem__(name, object): ... pass ... __setitem__.precondition = pre >>> class Container(object): ... zope.interface.implements(IContainer) >>> from zope.component.factory import Factory >>> ztapi.provideUtility(IFactory, Factory(F1), 'f1') >>> ztapi.provideUtility(IFactory, Factory(F2), 'f2') >>> from zope.app.container.browser.adding import Adding >>> adding = Adding(Container(), TestRequest()) >>> items = adding.addingInfo() >>> len(items) 1 >>> items[0]['title'] u'item3' >>> adding.menu_id = 'TestMenu' >>> items = adding.addingInfo() >>> len(items) 3 >>> items[0]['title'] u'item1' >>> items[1]['title'] # the collator ordered this one correctly! u'Item2' >>> items[2]['title'] u'item3' """ def test_constraint_driven_add(): """ >>> from zope.app.container.sample import SampleContainer >>> from zope.app.container.browser.adding import Adding >>> class F1(object): ... pass >>> class F2(object): ... pass >>> def pre(container, name, object): ... "a mock item constraint " ... if not isinstance(object, F1): ... raise zope.interface.Invalid('not a valid child') >>> class ITestContainer(zope.interface.Interface): ... def __setitem__(name, object): ... pass ... __setitem__.precondition = pre >>> class Container(SampleContainer): ... zope.interface.implements(ITestContainer) >>> adding = Adding(Container(), TestRequest()) >>> c = adding.add(F1()) This test should fail, because the container only accepts instances of F1 >>> adding.add(F2()) Traceback (most recent call last): ... Invalid: not a valid child >>> class ValidContainer(SampleContainer): ... zope.interface.implements(ITestContainer) >>> def constr(container): ... "a mock container constraint" ... if not isinstance(container, ValidContainer): ... raise zope.interface.Invalid('not a valid container') ... return True >>> class I2(zope.interface.Interface): ... __parent__ = zope.schema.Field(constraint = constr) >>> zope.interface.classImplements(F1, I2) This adding now fails, because the Container is not a valid parent for F1 >>> c = adding.add(F1()) Traceback (most recent call last): ... Invalid: not a valid container >>> adding = Adding(ValidContainer(), TestRequest()) >>> c = adding.add(F1()) """ def test_nameAllowed(): """ Test for nameAllowed in adding.py >>> from zope.app.container.browser.adding import Adding >>> from zope.app.container.interfaces import IContainerNamesContainer Class implements IContainerNamesContainer >>> class FakeContainer(object): ... zope.interface.implements(IContainerNamesContainer) nameAllowed returns False if the class imlements IContainerNamesContainer >>> adding = Adding(FakeContainer(),TestRequest()) >>> adding.nameAllowed() False Fake class without IContainerNamesContainer >>> class Fake(object): ... pass nameAllowed returns True if the class doesn't imlement IContainerNamesContainer >>> adding = Adding(Fake(),TestRequest()) >>> adding.nameAllowed() True """ def test_chooseName(): """If user don't enter name, pick one >>> class MyContainer(object): ... args = {} ... zope.interface.implements(INameChooser, IContainer) ... def chooseName(self, name, object): ... self.args["choose"] = name, object ... return 'pickone' ... def checkName(self, name, object): ... self.args["check"] = name, object ... def __setitem__(self, name, object): ... setattr(self, name, object) ... self.name = name ... def __getitem__(self, key): ... return getattr(self, key) >>> request = TestRequest() >>> mycontainer = MyContainer() >>> adding = Adding(mycontainer, request) >>> o = object() >>> add_obj = adding.add(o) >>> mycontainer.name 'pickone' >>> add_obj is o True Make sure right arguments passed to INameChooser adapter: >>> name, obj = mycontainer.args["choose"] >>> name '' >>> obj is o True >>> name, obj = mycontainer.args["check"] >>> name 'pickone' >>> obj is o True """ def test_SingleMenuItem_and_CustomAddView_NonICNC(): """ This tests the condition if the content has Custom Add views and the container contains only a single content object >>> registerAddMenu() >>> defineMenuItem(AddMenu, IAdding, '', 'item3', extra={'factory': 'f1'}) >>> class F1(object): ... pass >>> class F2(object): ... pass >>> def pre(container, name, object): ... if not isinstance(object, F1): ... raise zope.interface.Invalid() >>> def prefactory(container, name, factory): ... if factory._callable is not F1: ... raise zope.interface.Invalid() >>> pre.factory = prefactory >>> class IContainer(zope.interface.Interface): ... def __setitem__(name, object): ... pass ... __setitem__.precondition = pre >>> class Container(object): ... zope.interface.implements(IContainer) >>> from zope.component.factory import Factory >>> ztapi.provideUtility(IFactory, Factory(F1), 'f1') >>> ztapi.provideUtility(IFactory, Factory(F2), 'f2') >>> from zope.app.container.browser.adding import Adding >>> adding = Adding(Container(), TestRequest()) >>> items = adding.addingInfo() >>> len(items) 1 isSingleMenuItem returns True if there is only one content class inside the Container >>> adding.isSingleMenuItem() True hasCustomAddView will return False as the content does not have a custom Add View >>> adding.hasCustomAddView() True """ def test_SingleMenuItem_and_NoCustomAddView_NonICNC(): """ This function checks the case where there is a single content object and there is non custom add view . Also the container does not implement IContainerNamesContainer >>> registerAddMenu() >>> defineMenuItem(AddMenu, None, '', 'item3', extra={'factory': ''}) >>> class F1(object): ... pass >>> class F2(object): ... pass >>> def pre(container, name, object): ... if not isinstance(object, F1): ... raise zope.interface.Invalid() >>> def prefactory(container, name, factory): ... if factory._callable is not F1: ... raise zope.interface.Invalid() >>> pre.factory = prefactory >>> class IContainer(zope.interface.Interface): ... def __setitem__(name, object): ... pass ... __setitem__.precondition = pre >>> class Container(object): ... zope.interface.implements(IContainer) >>> from zope.component.factory import Factory >>> ztapi.provideUtility(IFactory, Factory(F1), 'f1') >>> ztapi.provideUtility(IFactory, Factory(F2), 'f2') >>> from zope.app.container.browser.adding import Adding >>> adding = Adding(Container(), TestRequest()) >>> items = adding.addingInfo() >>> len(items) 1 The isSingleMenuItem will return True if there is one single content that can be added inside the Container >>> adding.isSingleMenuItem() True hasCustomAddView will return False as the content does not have a custom Add View >>> adding.hasCustomAddView() False """ def test_isSingleMenuItem_with_ICNC(): """ This test checks for whether there is a single content that can be added and the container uses IContainerNamesContaienr >>> registerAddMenu() >>> defineMenuItem(AddMenu, None, '', 'item3', extra={'factory': ''}) >>> class F1(object): ... pass >>> class F2(object): ... pass >>> def pre(container, name, object): ... if not isinstance(object, F1): ... raise zope.interface.Invalid() >>> def prefactory(container, name, factory): ... if factory._callable is not F1: ... raise zope.interface.Invalid() >>> pre.factory = prefactory >>> class IContainer(zope.interface.Interface): ... def __setitem__(name, object): ... pass ... __setitem__.precondition = pre >>> class Container(object): ... zope.interface.implements(IContainer, IContainerNamesContainer) >>> from zope.app.container.browser.adding import Adding >>> adding = Adding(Container(), TestRequest()) >>> items = adding.addingInfo() >>> len(items) 1 >>> adding.isSingleMenuItem() True >>> adding.hasCustomAddView() False """ def test_suite(): return unittest.TestSuite(( unittest.makeSuite(Test), doctest.DocTestSuite(setUp=setUp, tearDown=tearDown), )) if __name__=='__main__': unittest.main(defaultTest='test_suite') zope.app.container-3.9.2/src/zope/app/container/browser/tests/configure.zcml0000664000177100020040000000070111707310352030370 0ustar menesismenesis00000000000000 zope.app.container-3.9.2/src/zope/app/container/browser/tests/test_contents_functional.py0000664000177100020040000003577311707310352033231 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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 Container's 'Contents' view """ import unittest from persistent import Persistent import transaction from zope import copypastemove from zope.interface import implements, Interface from zope.annotation.interfaces import IAttributeAnnotatable from zope.dublincore.interfaces import IZopeDublinCore from zope.app.container.interfaces import IReadContainer, IContained from zope.app.testing import ztapi from zope.app.testing.functional import BrowserTestCase from zope.app.testing.functional import FunctionalDocFileSuite from zope.app.container.testing import AppContainerLayer class IImmovable(Interface): """Marker interface for immovable objects.""" class IUncopyable(Interface): """Marker interface for uncopyable objects.""" class File(Persistent): implements(IAttributeAnnotatable) class ImmovableFile(File): implements(IImmovable) class UncopyableFile(File): implements(IUncopyable) class ObjectNonCopier(copypastemove.ObjectCopier): def copyable(self): return False class ObjectNonMover(copypastemove.ObjectMover): def moveable(self): return False class ReadOnlyContainer(Persistent): implements(IReadContainer, IContained) __parent__ = __name__ = None def __init__(self): self.data = {} def keys(self): return self.data.keys() def __getitem__(self, key): return self.data[key] def get(self, key, default=None): return self.data.get(key, default) def __iter__(self): return iter(self.data) def values(self): return self.data.values() def __len__(self): return len(self.data) def items(self): return self.data.items() def __contains__(self, key): return key in self.data def has_key(self, key): return self.data.has_key(key) class Test(BrowserTestCase): def test_inplace_add(self): root = self.getRootFolder() self.assert_('foo' not in root) response = self.publish( '/@@contents.html', basic='mgr:mgrpw', form={'type_name': u'BrowserAdd__zope.site.folder.Folder'}) body = ' '.join(response.getBody().split()) self.assert_(body.find('type="hidden" name="type_name"') >= 0) self.assert_(body.find('input name="new_value"') >= 0) self.assert_(body.find('type="submit" name="container_cancel_button"') >= 0) self.assert_(body.find('type="submit" name="container_rename_button"') < 0) response = self.publish( '/@@contents.html', basic='mgr:mgrpw', form={'type_name': u'BrowserAdd__zope.site.folder.Folder', 'new_value': 'foo'}) self.assertEqual(response.getStatus(), 302) self.assertEqual(response.getHeader('Location'), 'http://localhost/@@contents.html') root._p_jar.sync() self.assert_('foo' in root) def test_inplace_rename_multiple(self): root = self.getRootFolder() root['foo'] = File() self.assert_('foo' in root) transaction.commit() # Check that we don't change mode if there are no items selected response = self.publish('/@@contents.html', basic='mgr:mgrpw', form={'container_rename_button': u''}) body = ' '.join(response.getBody().split()) self.assert_(body.find('input name="new_value:list"') < 0) self.assert_(body.find('type="submit" name="container_cancel_button"') < 0) self.assert_(body.find('type="submit" name="container_rename_button"') >= 0) self.assert_(body.find('div class="page_error"') >= 0) # Check normal multiple select response = self.publish('/@@contents.html', basic='mgr:mgrpw', form={'container_rename_button': u'', 'ids': ['foo']}) body = ' '.join(response.getBody().split()) self.assert_(body.find('input name="new_value:list"') >= 0) self.assert_(body.find('type="submit" name="container_cancel_button"') >= 0) self.assert_(body.find('type="submit" name="container_rename_button"') < 0) response = self.publish('/@@contents.html', basic='mgr:mgrpw', form={'rename_ids': ['foo'], 'new_value': ['bar']}) self.assertEqual(response.getStatus(), 302) self.assertEqual(response.getHeader('Location'), 'http://localhost/@@contents.html') root._p_jar.sync() self.assert_('foo' not in root) self.assert_('bar' in root) def test_inplace_rename_single(self): root = self.getRootFolder() root['foo'] = File() self.assert_('foo' in root) transaction.commit() response = self.publish('/@@contents.html', basic='mgr:mgrpw', form={'rename_ids': ['foo']}) body = ' '.join(response.getBody().split()) self.assert_(body.find('input name="new_value:list"') >= 0) self.assert_(body.find('type="submit" name="container_cancel_button"') >= 0) self.assert_(body.find('type="submit" name="container_rename_button"') < 0) response = self.publish('/@@contents.html', basic='mgr:mgrpw', form={'rename_ids': ['foo'], 'new_value': ['bar']}) self.assertEqual(response.getStatus(), 302) self.assertEqual(response.getHeader('Location'), 'http://localhost/@@contents.html') root._p_jar.sync() self.assert_('foo' not in root) self.assert_('bar' in root) def test_inplace_change_title(self): root = self.getRootFolder() root['foo'] = File() transaction.commit() self.assert_('foo' in root) dc = IZopeDublinCore(root['foo']) self.assert_(dc.title == '') response = self.publish('/@@contents.html', basic='mgr:mgrpw', form={'retitle_id': u'foo'}) body = ' '.join(response.getBody().split()) self.assert_(body.find('type="hidden" name="retitle_id"') >= 0) self.assert_(body.find('input name="new_value"') >= 0) self.assert_(body.find('type="submit" name="container_cancel_button"') >= 0) self.assert_(body.find('type="submit" name="container_rename_button"') < 0) response = self.publish('/@@contents.html', basic='mgr:mgrpw', form={'retitle_id': u'foo', 'new_value': u'test title'}) self.assertEqual(response.getStatus(), 302) self.assertEqual(response.getHeader('Location'), 'http://localhost/@@contents.html') root._p_jar.sync() self.assert_('foo' in root) dc = IZopeDublinCore(root['foo']) self.assert_(dc.title == 'test title') def test_pasteable_for_deleted_clipboard_item(self): """Tests Paste button visibility when copied item is deleted.""" root = self.getRootFolder() root['foo'] = File() # item to be copied/deleted root['bar'] = File() # ensures that there's always an item in # the collection view transaction.commit() # confirm foo in contents, Copy button visible, Paste not visible response = self.publish('/@@contents.html', basic='mgr:mgrpw') self.assertEqual(response.getStatus(), 200) self.assert_(response.getBody().find( 'foo') != -1) self.assert_(response.getBody().find( ' nothing valid to paste -> Paste should not be visible del root['foo'] transaction.commit() response = self.publish('/@@contents.html', basic='mgr:mgrpw') self.assertEqual(response.getStatus(), 200) self.assert_(response.getBody().find( 'foo') != -1) self.assert_(response.getBody().find( 'bar') != -1) self.assert_(response.getBody().find( ' bar still available -> Paste should be visible del root['foo'] transaction.commit() response = self.publish('/@@contents.html', basic='mgr:mgrpw') self.assertEqual(response.getStatus(), 200) self.assert_(response.getBody().find( '>> response = http(r""" ... GET / HTTP/1.1 ... """) And we can check that there isn't a form (where the management operations would have buttons):: >>> body = response.getBody().lower() >>> "" % __name__ class TestCutCopyPaste(PlacefulSetup, TestCase): def setUp(self): PlacefulSetup.setUp(self) PlacefulSetup.buildFolders(self) ztapi.provideAdapter(IContained, IObjectCopier, ObjectCopier) ztapi.provideAdapter(IContained, IObjectMover, ObjectMover) ztapi.provideAdapter(IContainer, IContainerItemRenamer, ContainerItemRenamer) ztapi.provideAdapter(IAnnotations, IPrincipalClipboard, PrincipalClipboard) ztapi.provideAdapter(Principal, IAnnotations, PrincipalAnnotations) def testRename(self): container = traverse(self.rootFolder, 'folder1') fc = self._TestView__newView(container) ids=['document1', 'document2'] for id in ids: document = Document() container[id] = document fc.request.form.update({'rename_ids': ids, 'new_value': ['document1_1', 'document2_2'] }) fc.renameObjects() self.failIf('document1_1' not in container) self.failIf('document1' in container) def testCopyPaste(self): container = traverse(self.rootFolder, 'folder1') fc = self._TestView__newView(container) ids=['document1', 'document2'] for id in ids: document = Document() container[id] = document fc.request.form['ids'] = ids fc.copyObjects() fc.pasteObjects() self.failIf('document1' not in container) self.failIf('document2' not in container) self.failIf('document1-2' not in container) self.failIf('document2-2' not in container) def testCopyFolder(self): container = traverse(self.rootFolder, 'folder1') fc = self._TestView__newView(container) ids = ['folder1_1'] fc.request.form['ids'] = ids fc.copyObjects() fc.pasteObjects() self.failIf('folder1_1' not in container) self.failIf('folder1_1-2' not in container) def testCopyFolder2(self): container = traverse(self.rootFolder, '/folder1/folder1_1') fc = self._TestView__newView(container) ids = ['folder1_1_1'] fc.request.form['ids'] = ids fc.copyObjects() fc.pasteObjects() self.failIf('folder1_1_1' not in container) self.failIf('folder1_1_1-2' not in container) def testCopyFolder3(self): container = traverse(self.rootFolder, '/folder1/folder1_1') target = traverse(self.rootFolder, '/folder2/folder2_1') fc = self._TestView__newView(container) tg = self._TestView__newView(target) ids = ['folder1_1_1'] fc.request.form['ids'] = ids fc.copyObjects() tg.pasteObjects() self.failIf('folder1_1_1' not in container) self.failIf('folder1_1_1' not in target) def testCutPaste(self): container = traverse(self.rootFolder, 'folder1') fc = self._TestView__newView(container) ids=['document1', 'document2'] for id in ids: document = Document() container[id] = document fc.request.form['ids'] = ids fc.cutObjects() fc.pasteObjects() self.failIf('document1' not in container) self.failIf('document2' not in container) def testCutFolder(self): container = traverse(self.rootFolder, 'folder1') fc = self._TestView__newView(container) ids = ['folder1_1'] fc.request.form['ids'] = ids fc.cutObjects() fc.pasteObjects() self.failIf('folder1_1' not in container) def testCutFolder2(self): container = traverse(self.rootFolder, '/folder1/folder1_1') fc = self._TestView__newView(container) ids = ['folder1_1_1'] fc.request.form['ids'] = ids fc.cutObjects() fc.pasteObjects() self.failIf('folder1_1_1' not in container) def testCutFolder3(self): container = traverse(self.rootFolder, '/folder1/folder1_1') target = traverse(self.rootFolder, '/folder2/folder2_1') fc = self._TestView__newView(container) tg = self._TestView__newView(target) ids = ['folder1_1_1'] fc.request.form['ids'] = ids fc.cutObjects() tg.pasteObjects() self.failIf('folder1_1_1' in container) self.failIf('folder1_1_1' not in target) def _TestView__newView(self, container): from zope.app.container.browser.contents import Contents from zope.publisher.browser import TestRequest request = TestRequest() request.setPrincipal(Principal()) return Contents(container, request) class Test(BaseTestContentsBrowserView, TestCase): def _TestView__newContext(self): from zope.app.container.sample import SampleContainer from zope.site.folder import rootFolder root = rootFolder() container = SampleContainer() return contained(container, root, 'sample') def _TestView__newView(self, container): from zope.app.container.browser.contents import Contents from zope.publisher.browser import TestRequest request = TestRequest() request.setPrincipal(Principal()) return Contents(container, request) def test_suite(): return TestSuite(( makeSuite(Test), makeSuite(TestCutCopyPaste), )) if __name__=='__main__': main(defaultTest='test_suite') zope.app.container-3.9.2/src/zope/app/container/browser/tests/__init__.py0000664000177100020040000000007511707310352027635 0ustar menesismenesis00000000000000# # This file is necessary to make this directory a package. zope.app.container-3.9.2/src/zope/app/container/browser/tests/test_view_permissions.py0000664000177100020040000000753011707310352032545 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2004 Zope Foundation 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. # ############################################################################## """Container View Permissions Tests """ import unittest import transaction from zope.annotation.interfaces import IAttributeAnnotatable from zope.interface import alsoProvides from zope.security.interfaces import Unauthorized from zope.app.testing.functional import BrowserTestCase from zope.container.ordered import OrderedContainer from zope.dublincore.interfaces import IZopeDublinCore from zope.securitypolicy.interfaces import IRolePermissionManager from zope.app.container.testing import AppContainerLayer class Tests(BrowserTestCase): def test_default_view_permissions(self): """Tests the default view permissions. """ # add an item that can be viewed from the root folder obj = OrderedContainer() alsoProvides(obj, IAttributeAnnotatable) self.getRootFolder()['obj'] = obj IZopeDublinCore(obj).title = u'My object' transaction.commit() response = self.publish('/') self.assertEquals(response.getStatus(), 200) body = response.getBody() # confirm we can see the file name self.assert_(body.find('obj') != -1) # confirm we can see the metadata title self.assert_(body.find('My object') != -1) def test_deny_view(self): """Tests the denial of view permissions to anonymous. This test uses the ZMI interface to deny anonymous zope.View permission to the root folder. """ # deny zope.View to zope.Anonymous prm = IRolePermissionManager(self.getRootFolder()) prm.denyPermissionToRole('zope.View', 'zope.Anonymous') transaction.commit() # confirm Unauthorized when viewing root folder self.assertRaises(Unauthorized, self.publish, '/') def test_deny_dublincore_view(self): """Tests the denial of dublincore view permissions to anonymous. Users who can view a folder contents page but cannot view dublin core should still be able to see the folder items' names, but not their title, modified, and created info. """ # add an item that can be viewed from the root folder obj = OrderedContainer() alsoProvides(obj, IAttributeAnnotatable) self.getRootFolder()['obj'] = obj IZopeDublinCore(obj).title = u'My object' # deny zope.app.dublincore.view to zope.Anonymous prm = IRolePermissionManager(self.getRootFolder()) prm.denyPermissionToRole('zope.dublincore.view', 'zope.Anonymous') # Try both spellings just in case we are used with an older zope.dc prm.denyPermissionToRole('zope.app.dublincore.view', 'zope.Anonymous') transaction.commit() response = self.publish('/') self.assertEquals(response.getStatus(), 200) body = response.getBody() # confirm we can see the file name self.assert_(body.find('obj') != -1) # confirm we *cannot* see the metadata title self.assert_(body.find('My object') == -1) def test_suite(): suite = unittest.TestSuite() Tests.layer = AppContainerLayer suite.addTest(unittest.makeSuite(Tests)) return suite if __name__=='__main__': unittest.main(defaultTest='test_suite') zope.app.container-3.9.2/src/zope/app/container/browser/find.pt0000664000177100020040000000112011707310352025637 0ustar menesismenesis00000000000000

id
zope.app.container-3.9.2/src/zope/app/container/browser/add.pt0000664000177100020040000000354411707310352025463 0ustar menesismenesis00000000000000

There are no addable content types for this container.

Inserted title Add Content
Folders are generic containers for content, including other folders.

zope.app.container-3.9.2/src/zope/app/container/browser/configure.zcml0000664000177100020040000000112611707310352027230 0ustar menesismenesis00000000000000 zope.app.container-3.9.2/src/zope/app/container/browser/find.py0000664000177100020040000000300011707310352025643 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """Find View Class """ __docformat__ = 'restructuredtext' from zope.traversing.api import getName from zope.traversing.browser.absoluteurl import absoluteURL from zope.publisher.browser import BrowserView from zope.app.container.find import SimpleIdFindFilter from zope.app.container.interfaces import IFind # Very simple implementation right now class Find(BrowserView): def findByIds(self, ids): """Do a find for the `ids` listed in `ids`, which is a string.""" finder = IFind(self.context) ids = ids.split() # if we don't have any ids listed, don't search at all if not ids: return [] request = self.request result = [] for object in finder.find([SimpleIdFindFilter(ids)]): url = absoluteURL(object, request) result.append({ 'id': getName(object), 'url': url}) return result zope.app.container-3.9.2/src/zope/app/container/browser/metaconfigure.py0000664000177100020040000000747411707310352027576 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """Container-specific browser ZCML namespace directive handlers """ __docformat__ = 'restructuredtext' from zope.interface import Interface from zope.component import queryMultiAdapter from zope.configuration.fields import GlobalObject, GlobalInterface from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.security.zcml import Permission from zope.browserpage.metaconfigure import page, view from zope.browsermenu.metaconfigure import menuItemDirective from zope.app.container.browser.contents import Contents from zope.app.container.browser.adding import Adding from zope.app.container.i18n import ZopeMessageFactory as _ class IContainerViews(Interface): """Define several container views for an `IContainer` implementation.""" for_ = GlobalObject( title=u"The declaration this containerViews are for.", description=u""" The containerViews will be available for all objects that provide this declaration. """, required=True) contents = Permission( title=u"The permission needed for content page.", required=False) index = Permission( title=u"The permission needed for index page.", required=False) add = Permission( title=u"The permission needed for add page.", required=False) layer = GlobalInterface( title=_("The layer the view is in."), description=_("""A skin is composed of layers. It is common to put skin specific views in a layer named after the skin. If the 'layer' attribute is not supplied, it defaults to 'default'."""), required=False ) def containerViews(_context, for_, contents=None, add=None, index=None, layer=IDefaultBrowserLayer): """Set up container views for a given content type.""" if for_ is None: raise ValueError("A for interface must be specified.") if contents is not None: from zope.app.menus import zmi_views page(_context, name='contents.html', permission=contents, for_=for_, layer=layer, class_=Contents, attribute='contents', menu=zmi_views, title=_('Contents')) if index is not None: page(_context, name='index.html', permission=index, for_=for_, layer=layer, class_=Contents, attribute='index') if add is not None: from zope.app.menus import zmi_actions viewObj = view(_context, name='+', layer=layer, for_=for_, permission=add, class_=Adding) menuItemDirective( _context, zmi_actions, for_, '+', _('Add'), permission=add, layer=layer, filter='python:modules["zope.app.container.browser.metaconfigure"].menuFilter(context, request)') viewObj.page(_context, name='index.html', attribute='index') viewObj.page(_context, name='action.html', attribute='action') viewObj() def menuFilter(context, request): '''This is a function that filters the "Add" menu item''' adding = queryMultiAdapter((context, request), name="+") if adding is None: adding = Adding(context, request) adding.__parent__ = context adding.__name__ = '+' info = adding.addingInfo() return bool(info) zope.app.container-3.9.2/src/zope/app/container/browser/contents.py0000664000177100020040000003746411707310352026605 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """View Class for the Container's Contents view. """ __docformat__ = 'restructuredtext' import urllib from zope.component import queryMultiAdapter from zope.event import notify from zope.exceptions.interfaces import UserError from zope.security.interfaces import Unauthorized from zope.security import canWrite from zope.size.interfaces import ISized from zope.traversing.interfaces import TraversalError from zope.publisher.browser import BrowserView from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile from zope.dublincore.interfaces import IZopeDublinCore from zope.dublincore.interfaces import IDCDescriptiveProperties from zope.copypastemove.interfaces import IPrincipalClipboard from zope.copypastemove.interfaces import IObjectCopier, IObjectMover from zope.copypastemove.interfaces import IContainerItemRenamer from zope.annotation.interfaces import IAnnotations from zope.lifecycleevent import ObjectModifiedEvent, Attributes from zope.traversing.api import getName, getPath, joinPath, traverse from zope.app.container.i18n import ZopeMessageFactory as _ from zope.app.container.browser.adding import Adding from zope.app.container.interfaces import IContainer, DuplicateIDError from zope.app.container.interfaces import IContainerNamesContainer class Contents(BrowserView): __used_for__ = IContainer error = '' message = '' normalButtons = False specialButtons = False supportsRename = False def listContentInfo(self): request = self.request if "container_cancel_button" in request: if "type_name" in request: del request.form['type_name'] if "rename_ids" in request and "new_value" in request: del request.form['rename_ids'] if "retitle_id" in request and "new_value" in request: del request.form['retitle_id'] return self._normalListContentsInfo() elif "container_rename_button" in request and not request.get("ids"): self.error = _("You didn't specify any ids to rename.") elif "container_add_button" in request: if "single_type_name" in request \ and "single_new_value" in request: request.form['type_name'] = request['single_type_name'] request.form['new_value'] = request['single_new_value'] self.addObject() elif 'single_type_name' in request \ and 'single_new_value' not in request: request.form['type_name'] = request['single_type_name'] request.form['new_value'] = "" self.addObject() elif "type_name" in request and "new_value" in request: self.addObject() elif "rename_ids" in request and "new_value" in request: self.renameObjects() elif "retitle_id" in request and "new_value" in request: self.changeTitle() elif "container_cut_button" in request: self.cutObjects() elif "container_copy_button" in request: self.copyObjects() elif "container_paste_button" in request: self.pasteObjects() elif "container_delete_button" in request: self.removeObjects() else: return self._normalListContentsInfo() if self.error: return self._normalListContentsInfo() status = request.response.getStatus() if status not in (302, 303): # Only redirect if nothing else has request.response.redirect(request.URL) return () def normalListContentInfo(self): return self._normalListContentsInfo() def _normalListContentsInfo(self): request = self.request self.specialButtons = ( 'type_name' in request or 'rename_ids' in request or ('container_rename_button' in request and request.get("ids")) or 'retitle_id' in request ) self.normalButtons = not self.specialButtons info = map(self._extractContentInfo, self.context.items()) self.supportsCut = info self.supportsCopy = info self.supportsDelete = info self.supportsPaste = self.pasteable() self.supportsRename = ( self.supportsCut and not IContainerNamesContainer.providedBy(self.context) ) return info def _extractContentInfo(self, item): request = self.request rename_ids = {} if "container_rename_button" in request: for rename_id in request.get('ids', ()): rename_ids[rename_id] = rename_id elif "rename_ids" in request: for rename_id in request.get('rename_ids', ()): rename_ids[rename_id] = rename_id retitle_id = request.get('retitle_id') id, obj = item info = {} info['id'] = info['cb_id'] = id info['object'] = obj info['url'] = urllib.quote(id.encode('utf-8')) info['rename'] = rename_ids.get(id) info['retitle'] = id == retitle_id zmi_icon = queryMultiAdapter((obj, self.request), name='zmi_icon') if zmi_icon is None: info['icon'] = None else: info['icon'] = zmi_icon() dc = IZopeDublinCore(obj, None) if dc is not None: info['retitleable'] = canWrite(dc, 'title') info['plaintitle'] = not info['retitleable'] title = self.safe_getattr(dc, 'title', None) if title: info['title'] = title formatter = self.request.locale.dates.getFormatter( 'dateTime', 'short') created = self.safe_getattr(dc, 'created', None) if created is not None: info['created'] = formatter.format(created) modified = self.safe_getattr(dc, 'modified', None) if modified is not None: info['modified'] = formatter.format(modified) else: info['retitleable'] = 0 info['plaintitle'] = 1 sized_adapter = ISized(obj, None) if sized_adapter is not None: info['size'] = sized_adapter return info def safe_getattr(self, obj, attr, default): """Attempts to read the attr, returning default if Unauthorized.""" try: return getattr(obj, attr, default) except Unauthorized: return default def renameObjects(self): """Given a sequence of tuples of old, new ids we rename""" request = self.request ids = request.get("rename_ids") newids = request.get("new_value") renamer = IContainerItemRenamer(self.context) for oldid, newid in zip(ids, newids): if newid != oldid: renamer.renameItem(oldid, newid) def changeTitle(self): """Given a sequence of tuples of old, new ids we rename""" request = self.request id = request.get("retitle_id") new = request.get("new_value") item = self.context[id] dc = IDCDescriptiveProperties(item) dc.title = new notify(ObjectModifiedEvent(item, Attributes(IZopeDublinCore, 'title'))) def hasAdding(self): """Returns true if an adding view is available.""" adding = queryMultiAdapter((self.context, self.request), name="+") return (adding is not None) def addObject(self): request = self.request if IContainerNamesContainer.providedBy(self.context): new = "" else: new = request["new_value"] adding = queryMultiAdapter((self.context, self.request), name="+") if adding is None: adding = Adding(self.context, request) else: # Set up context so that the adding can build a url # if the type name names a view. # Note that we can't so this for the "adding is None" case # above, because there is no "+" view. adding.__parent__ = self.context adding.__name__ = '+' adding.action(request['type_name'], new) def removeObjects(self): """Remove objects specified in a list of object ids""" request = self.request ids = request.get('ids') if not ids: self.error = _("You didn't specify any ids to remove.") return container = self.context for id in ids: del container[id] def copyObjects(self): """Copy objects specified in a list of object ids""" request = self.request ids = request.get('ids') if not ids: self.error = _("You didn't specify any ids to copy.") return container_path = getPath(self.context) # For each item, check that it can be copied; if so, save the # path of the object for later copying when a destination has # been selected; if not copyable, provide an error message # explaining that the object can't be copied. items = [] for id in ids: ob = self.context[id] copier = IObjectCopier(ob) if not copier.copyable(): m = {"name": id} title = getDCTitle(ob) if title: m["title"] = title self.error = _( "Object '${name}' (${title}) cannot be copied", mapping=m) else: self.error = _("Object '${name}' cannot be copied", mapping=m) return items.append(joinPath(container_path, id)) # store the requested operation in the principal annotations: clipboard = getPrincipalClipboard(self.request) clipboard.clearContents() clipboard.addItems('copy', items) def cutObjects(self): """move objects specified in a list of object ids""" request = self.request ids = request.get('ids') if not ids: self.error = _("You didn't specify any ids to cut.") return container_path = getPath(self.context) # For each item, check that it can be moved; if so, save the # path of the object for later moving when a destination has # been selected; if not movable, provide an error message # explaining that the object can't be moved. items = [] for id in ids: ob = self.context[id] mover = IObjectMover(ob) if not mover.moveable(): m = {"name": id} title = getDCTitle(ob) if title: m["title"] = title self.error = _( "Object '${name}' (${title}) cannot be moved", mapping=m) else: self.error = _("Object '${name}' cannot be moved", mapping=m) return items.append(joinPath(container_path, id)) # store the requested operation in the principal annotations: clipboard = getPrincipalClipboard(self.request) clipboard.clearContents() clipboard.addItems('cut', items) def pasteable(self): """Decide if there is anything to paste """ target = self.context clipboard = getPrincipalClipboard(self.request) items = clipboard.getContents() for item in items: try: obj = traverse(target, item['target']) except TraversalError: pass else: if item['action'] == 'cut': mover = IObjectMover(obj) moveableTo = self.safe_getattr(mover, 'moveableTo', None) if moveableTo is None or not moveableTo(target): return False elif item['action'] == 'copy': copier = IObjectCopier(obj) copyableTo = self.safe_getattr(copier, 'copyableTo', None) if copyableTo is None or not copyableTo(target): return False else: raise return True def pasteObjects(self): """Paste ojects in the user clipboard to the container """ target = self.context clipboard = getPrincipalClipboard(self.request) items = clipboard.getContents() moved = False not_pasteable_ids = [] for item in items: duplicated_id = False try: obj = traverse(target, item['target']) except TraversalError: pass else: if item['action'] == 'cut': mover = IObjectMover(obj) try: mover.moveTo(target) moved = True except DuplicateIDError: duplicated_id = True elif item['action'] == 'copy': copier = IObjectCopier(obj) try: copier.copyTo(target) except DuplicateIDError: duplicated_id = True else: raise if duplicated_id: not_pasteable_ids.append(getName(obj)) if moved: # Clear the clipboard if we do a move, but not if we only do a copy clipboard.clearContents() if not_pasteable_ids != []: # Show the ids of objects that can't be pasted because # their ids are already taken. # TODO Can't we add a 'copy_of' or something as a prefix # instead of raising an exception ? raise UserError( _("The given name(s) %s is / are already being used" %( str(not_pasteable_ids)))) def hasClipboardContents(self): """Interogate the ``PrinicipalAnnotation`` to see if clipboard contents exist.""" if not self.supportsPaste: return False # touch at least one item to in clipboard confirm contents clipboard = getPrincipalClipboard(self.request) items = clipboard.getContents() for item in items: try: traverse(self.context, item['target']) except TraversalError: pass else: return True return False contents = ViewPageTemplateFile('contents.pt') contentsMacros = contents _index = ViewPageTemplateFile('index.pt') def index(self): if 'index.html' in self.context: self.request.response.redirect('index.html') return '' return self._index() class JustContents(Contents): """Like Contents, but does't delegate to item named index.html""" def index(self): return self._index() def getDCTitle(ob): dc = IDCDescriptiveProperties(ob, None) if dc is None: return None else: return dc.title def getPrincipalClipboard(request): """Return the clipboard based on the request.""" user = request.principal annotations = IAnnotations(user) return IPrincipalClipboard(annotations) zope.app.container-3.9.2/src/zope/app/container/browser/__init__.py0000664000177100020040000000007511707310352026473 0ustar menesismenesis00000000000000# # This file is necessary to make this directory a package. zope.app.container-3.9.2/src/zope/app/container/browser/commontasks.pt0000664000177100020040000000277411707310352027275 0ustar menesismenesis00000000000000 zope.app.container-3.9.2/src/zope/app/container/browser/contents.pt0000664000177100020040000001650611707310352026572 0ustar menesismenesis00000000000000
Error message
Name Title Size Created Modified
foo                  
zope.app.container-3.9.2/src/zope/app/container/browser/adding.py0000664000177100020040000001723711707310352026172 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2002 Zope Foundation 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. # ############################################################################## """Adding View The Adding View is used to add new objects to a container. It is sort of a factory screen. """ __docformat__ = 'restructuredtext' from zope.app.container.constraints import checkFactory from zope.app.container.constraints import checkObject from zope.app.container.i18n import ZopeMessageFactory as _ from zope.app.container.interfaces import IAdding from zope.app.container.interfaces import IContainerNamesContainer from zope.app.container.interfaces import INameChooser from zope.browsermenu.menu import getMenu from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile from zope.component import getMultiAdapter from zope.component import getUtility from zope.component import queryAdapter from zope.component import queryMultiAdapter from zope.component import queryUtility from zope.component.interfaces import IFactory from zope.event import notify from zope.exceptions.interfaces import UserError from zope.i18n.interfaces.locales import ICollator from zope.i18n.locales.fallbackcollator import FallbackCollator from zope.interface import implements from zope.lifecycleevent import ObjectCreatedEvent from zope.location import LocationProxy from zope.publisher.browser import BrowserView from zope.publisher.interfaces import IPublishTraverse from zope.security.proxy import removeSecurityProxy from zope.traversing.browser.absoluteurl import absoluteURL import zope.security.checker class Adding(BrowserView): implements(IAdding, IPublishTraverse) def add(self, content): """See zope.app.container.interfaces.IAdding """ container = self.context name = self.contentName chooser = INameChooser(container) # check precondition checkObject(container, name, content) if IContainerNamesContainer.providedBy(container): # The container picks its own names. # We need to ask it to pick one. name = chooser.chooseName(self.contentName or '', content) else: request = self.request name = request.get('add_input_name', name) if name is None: name = chooser.chooseName(self.contentName or '', content) elif name == '': name = chooser.chooseName('', content) chooser.checkName(name, content) container[name] = content self.contentName = name # Set the added object Name return container[name] contentName = None # usually set by Adding traverser def nextURL(self): """See zope.app.container.interfaces.IAdding""" return absoluteURL(self.context, self.request) + '/@@contents.html' # set in BrowserView.__init__ request = None context = None def publishTraverse(self, request, name): """See zope.publisher.interfaces.IPublishTraverse""" if '=' in name: view_name, content_name = name.split("=", 1) self.contentName = content_name if view_name.startswith('@@'): view_name = view_name[2:] return getMultiAdapter((self, request), name=view_name) if name.startswith('@@'): view_name = name[2:] else: view_name = name view = queryMultiAdapter((self, request), name=view_name) if view is not None: return view factory = queryUtility(IFactory, name) if factory is None: return super(Adding, self).publishTraverse(request, name) return factory def action(self, type_name='', id=''): if not type_name: raise UserError(_(u"You must select the type of object to add.")) if type_name.startswith('@@'): type_name = type_name[2:] if '/' in type_name: view_name = type_name.split('/', 1)[0] else: view_name = type_name if queryMultiAdapter((self, self.request), name=view_name) is not None: url = "%s/%s=%s" % ( absoluteURL(self, self.request), type_name, id) self.request.response.redirect(url) return if not self.contentName: self.contentName = id # TODO: If the factory wrapped by LocationProxy is already a Proxy, # then ProxyFactory does not do the right thing and the # original's checker info gets lost. No factory that was # registered via ZCML and was used via addMenuItem worked # here. (SR) factory = getUtility(IFactory, type_name) if not type(factory) is zope.security.checker.Proxy: factory = LocationProxy(factory, self, type_name) factory = zope.security.checker.ProxyFactory(factory) content = factory() # Can't store security proxies. # Note that it is important to do this here, rather than # in add, otherwise, someone might be able to trick add # into unproxying an existing object, content = removeSecurityProxy(content) notify(ObjectCreatedEvent(content)) self.add(content) self.request.response.redirect(self.nextURL()) def nameAllowed(self): """Return whether names can be input by the user.""" return not IContainerNamesContainer.providedBy(self.context) menu_id = None index = ViewPageTemplateFile("add.pt") def addingInfo(self): """Return menu data. This is sorted by title. """ container = self.context result = [] for menu_id in (self.menu_id, 'zope.app.container.add'): if not menu_id: continue for item in getMenu(menu_id, self, self.request): extra = item.get('extra') if extra: factory = extra.get('factory') if factory: factory = getUtility(IFactory, factory) if not checkFactory(container, None, factory): continue elif item['extra']['factory'] != item['action']: item['has_custom_add_view']=True # translate here to have a localized sorting item['title'] = zope.i18n.translate(item['title'], context=self.request) result.append(item) # sort the adding info with a collator instead of a basic unicode sort collator = queryAdapter(self.request.locale, ICollator) if collator is None: collator = FallbackCollator(self.request.locale) result.sort(key = lambda x: collator.key(x['title'])) return result def isSingleMenuItem(self): "Return whether there is single menu item or not." return len(self.addingInfo()) == 1 def hasCustomAddView(self): "This should be called only if there is `singleMenuItem` else return 0" if self.isSingleMenuItem(): menu_item = self.addingInfo()[0] if 'has_custom_add_view' in menu_item: return True return False zope.app.container-3.9.2/src/zope/app/container/browser/index.pt0000664000177100020040000000274011707310352026037 0ustar menesismenesis00000000000000
  Name Title Created Modified
ID here      
zope.app.container-3.9.2/src/zope/app/container/traversal.py0000664000177100020040000000146311707310352025256 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """BBB: this module moved to zope.container """ # BBB from zope.container.traversal import ( ContainerTraverser, ItemTraverser, _marker, ContainerTraversable ) zope.app.container-3.9.2/src/zope/app/container/dependency.py0000664000177100020040000000140511707310352025365 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2002 Zope Foundation 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. # ############################################################################## """BBB: this module moved to zope.container """ # BBB from zope.container.dependency import ( exception_msg, CheckDependency ) zope.app.container-3.9.2/src/zope/app/container/__init__.py0000664000177100020040000000007511707310352025010 0ustar menesismenesis00000000000000# # This file is necessary to make this directory a package. zope.app.container-3.9.2/src/zope/app/container/directory.py0000664000177100020040000000135611707310352025260 0ustar menesismenesis00000000000000############################################################################## # Copyright (c) 2003 Zope Foundation 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. ############################################################################## """BBB: this module moved to zope.container """ # BBB from zope.container.directory import ( noop, Cloner ) zope.app.container-3.9.2/src/zope/app/container/testing.py0000664000177100020040000000032411707310352024723 0ustar menesismenesis00000000000000import os from zope.app.testing.functional import ZCMLLayer AppContainerLayer = ZCMLLayer( os.path.join(os.path.split(__file__)[0], 'ftesting.zcml'), __name__, 'AppContainerLayer', allow_teardown=True) zope.app.container-3.9.2/src/zope/app/container/interfaces.py0000664000177100020040000000245111707310352025374 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2003 Zope Foundation 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. # ############################################################################## """Container-related interfaces """ __docformat__ = 'restructuredtext' # BBB from zope.browser.interfaces import IAdding # BBB from zope.container.interfaces import ( DuplicateIDError, ContainerError, InvalidContainerType, InvalidItemType, InvalidType, IContained, IItemContainer, ISimpleReadContainer, IReadContainer, IWriteContainer, IItemWriteContainer, IContainer, IBTreeContainer, IOrderedContainer, IContainerNamesContainer, IObjectMovedEvent, UnaddableError, IObjectAddedEvent, INameChooser, IObjectRemovedEvent, IContainerModifiedEvent, IFind, IObjectFindFilter, IIdFindFilter ) zope.app.container-3.9.2/src/zope/app/container/size.py0000664000177100020040000000134311707310352024222 0ustar menesismenesis00000000000000 ############################################################################## # # Copyright (c) 2002 Zope Foundation 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. # ############################################################################## """BBB: this module moved to zope.container """ # BBB from zope.container.size import ContainerSized zope.app.container-3.9.2/src/zope/app/container/sample.py0000664000177100020040000000135311707310352024532 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation 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. # ############################################################################## """BBB: this module moved to zope.container """ # BBB from zope.container.sample import SampleContainer zope.app.container-3.9.2/src/zope/app/container/ftesting.zcml0000664000177100020040000000252111707310352025407 0ustar menesismenesis00000000000000 zope.app.container-3.9.2/src/zope/app/container/i18n.py0000664000177100020040000000157211707310352024033 0ustar menesismenesis00000000000000############################################################################## # # Copyright (c) 2003 Zope Foundation 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. # ############################################################################## """Customization of zope.i18n for the Zope application server """ __docformat__ = 'restructuredtext' # import this as _ to create i18n messages in the zope domain from zope.i18nmessageid import MessageFactory ZopeMessageFactory = MessageFactory('zope') zope.app.container-3.9.2/buildout.cfg0000664000177100020040000000015411707310352020677 0ustar menesismenesis00000000000000[buildout] develop = . parts = test [test] recipe = zc.recipe.testrunner eggs = zope.app.container [test] zope.app.container-3.9.2/README.txt0000664000177100020040000000022511707310352020064 0ustar menesismenesis00000000000000This package define interfaces of container components, and provides sample container implementations such as a BTreeContainer and OrderedContainer. zope.app.container-3.9.2/setup.cfg0000664000177100020040000000007311707310374020214 0ustar menesismenesis00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 zope.app.container-3.9.2/LICENSE.txt0000664000177100020040000000402611707310352020214 0ustar menesismenesis00000000000000Zope Public License (ZPL) Version 2.1 A copyright notice accompanies this license document that identifies the copyright holders. This license has been certified as open source. It has also been designated as GPL compatible by the Free Software Foundation (FSF). Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions in source code must retain the accompanying copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the accompanying copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Names of the copyright holders must not be used to endorse or promote products derived from this software without prior written permission from the copyright holders. 4. The right to distribute this software or to use it for any purpose does not give you the right to use Servicemarks (sm) or Trademarks (tm) of the copyright holders. Use of them is covered by separate agreement with the copyright holders. 5. If any files are modified, you must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. Disclaimer THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.