[Checkins] SVN: z3ext.controlpanel/ initial import
Nikolay Kim
fafhrd at datacom.kz
Fri Mar 21 05:09:54 EDT 2008
Log message for revision 84833:
initial import
Changed:
A z3ext.controlpanel/
A z3ext.controlpanel/branches/
A z3ext.controlpanel/tags/
A z3ext.controlpanel/trunk/
A z3ext.controlpanel/trunk/AUTHOR.txt
A z3ext.controlpanel/trunk/CHANGES.txt
A z3ext.controlpanel/trunk/LICENSE.txt
A z3ext.controlpanel/trunk/bootstrap.py
A z3ext.controlpanel/trunk/buildout.cfg
A z3ext.controlpanel/trunk/setup.py
A z3ext.controlpanel/trunk/src/
A z3ext.controlpanel/trunk/src/z3ext/
A z3ext.controlpanel/trunk/src/z3ext/__init__.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/README.txt
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/__init__.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/__init__.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/breadcrumb.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/category.pt
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/category.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet.pt
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet_icon.gif
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configure.zcml
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/interfaces.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/layout.pt
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/navigation.pt
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/navigation.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/preferences-system.png
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/README.txt
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/__init__.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/configure.zcml
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/interfaces.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/test_functional.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/configlet.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/configlettype.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/configure.zcml
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/ftesting.zcml
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/i18n.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/interfaces.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/meta.zcml
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/root.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/storage.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/testing.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/tests.py
A z3ext.controlpanel/trunk/src/z3ext/controlpanel/zcml.py
-=-
Property changes on: z3ext.controlpanel/trunk
___________________________________________________________________
Name: svn:ignore
+ bin
develop-eggs
eggs
parts
coverage
.installed.cfg
Added: z3ext.controlpanel/trunk/AUTHOR.txt
===================================================================
--- z3ext.controlpanel/trunk/AUTHOR.txt (rev 0)
+++ z3ext.controlpanel/trunk/AUTHOR.txt 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1 @@
+Nikolay Kim (fafhrd91 <at> gmail <dot> com)
Added: z3ext.controlpanel/trunk/CHANGES.txt
===================================================================
--- z3ext.controlpanel/trunk/CHANGES.txt (rev 0)
+++ z3ext.controlpanel/trunk/CHANGES.txt 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,64 @@
+=======
+CHANGES
+=======
+
+1.2.0 (2008-03-21)
+------------------
+
+- Use z3ext.pagelet directive for browser views
+
+- Added i18n
+
+- Moved to svn.zope.org
+
+
+1.1.7 (2008-03-18)
+------------------
+
+- Added functional tests
+
+
+1.1.6 (2008-02-28)
+------------------
+
+- Use z3c.autoinclude
+
+
+1.1.5 (2008-02-22)
+------------------
+
+- Added buildout.cfg for testing
+
+- Added viewlet manager for configlet navigation
+
+
+1.1.4 (2008-02-20)
+------------------
+
+- Use z3ext.layoutform
+
+
+1.1.3 (2008-02-0?)
+------------------
+
+- Added 'UI' configuration category
+
+
+1.1.2 (2008-02-04)
+------------------
+
+- Fixed problem with generated class and persistence
+
+- Remove all <grant/> directives
+
+
+1.1.0 (2008-01-31)
+------------------
+
+- Use z3ext.layout for rendering
+
+
+1.0.0 (2007-26-07)
+------------------
+
+- Initial release.
Added: z3ext.controlpanel/trunk/LICENSE.txt
===================================================================
--- z3ext.controlpanel/trunk/LICENSE.txt (rev 0)
+++ z3ext.controlpanel/trunk/LICENSE.txt 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,54 @@
+Zope 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.
Added: z3ext.controlpanel/trunk/bootstrap.py
===================================================================
--- z3ext.controlpanel/trunk/bootstrap.py (rev 0)
+++ z3ext.controlpanel/trunk/bootstrap.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""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$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+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)
Property changes on: z3ext.controlpanel/trunk/bootstrap.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/buildout.cfg
===================================================================
--- z3ext.controlpanel/trunk/buildout.cfg (rev 0)
+++ z3ext.controlpanel/trunk/buildout.cfg 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,18 @@
+[buildout]
+develop = .
+parts = test coverage-test coverage-report
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3ext.controlpanel [test]
+
+[coverage-test]
+recipe = zc.recipe.testrunner
+eggs = z3ext.controlpanel [test]
+defaults = ['--coverage', '../../coverage']
+
+[coverage-report]
+recipe = zc.recipe.egg
+eggs = z3c.coverage
+scripts = coverage=coverage-report
+arguments = ('coverage', 'coverage/report')
Added: z3ext.controlpanel/trunk/setup.py
===================================================================
--- z3ext.controlpanel/trunk/setup.py (rev 0)
+++ z3ext.controlpanel/trunk/setup.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,86 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Setup for z3ext.controlpanel package
+
+$Id$
+"""
+import sys, os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+version='1.2.0'
+
+
+setup(name = 'z3ext.controlpanel',
+ version = version,
+ description = "Control Panel - userfriendly system control panel.",
+ long_description = (
+ 'Detailed Documentation\n' +
+ '======================\n'
+ + '\n\n' +
+ read('src', 'z3ext', 'controlpanel', 'README.txt')
+ + '\n\n' +
+ read('CHANGES.txt')
+ ),
+ 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'],
+ author = 'Nikolay Kim',
+ author_email = 'fafhrd91 at gmail.com',
+ url='http://z3ext.net/',
+ license='ZPL 2.1',
+ packages=find_packages('src'),
+ package_dir = {'':'src'},
+ namespace_packages=['z3ext'],
+ install_requires = ['setuptools',
+ 'zope.schema',
+ 'zope.interface',
+ 'zope.component',
+ 'zope.annotation',
+ 'zope.security',
+ 'zope.location',
+ 'zope.publisher',
+ 'zope.i18nmessageid',
+ 'zope.viewlet',
+ 'zope.contentprovider',
+ 'zope.cachedescriptors',
+ 'zope.app.publisher',
+ 'zope.app.component',
+ 'zope.app.security',
+ 'zope.configuration',
+ 'z3c.traverser',
+ 'z3c.autoinclude',
+ 'z3ext.layout',
+ 'z3ext.layoutform',
+ ],
+ extras_require = dict(test=['zope.securitypolicy',
+ 'zope.app.security',
+ 'zope.app.testing',
+ 'zope.app.zcmlfiles',
+ 'zope.traversing',
+ 'zope.testing',
+ 'zope.testbrowser',
+ ]),
+ include_package_data = True,
+ zip_safe = False
+ )
Property changes on: z3ext.controlpanel/trunk/setup.py
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/__init__.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/__init__.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/__init__.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,6 @@
+# namespace package boilerplate
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError, e:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
Property changes on: z3ext.controlpanel/trunk/src/z3ext/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/README.txt
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/README.txt (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/README.txt 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,302 @@
+=============
+Control Panel
+=============
+
+In many cases programm modules needs configuration and some common way
+of managing configuration. Control panel very similar with zope.app.preference,
+it stores all data in site annotation, in BTrees. so you can removeing
+and add any configlet without problem with zodb.
+
+We need load zcml configuration
+
+ >>> from zope.configuration import xmlconfig
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+ ... <include package="z3ext.controlpanel" file="meta.zcml" />
+ ... </configure>""")
+
+ >>> from zope import interface, component
+ >>> from z3ext.controlpanel import tests, interfaces
+
+We can register configlet with z3ext:configlet directive.
+
+Let's create simple configlet
+
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"
+ ... i18n_domain="zope">
+ ... <z3ext:configlet
+ ... name="configlet1"
+ ... schema="z3ext.controlpanel.tests.ITestConfiglet1"
+ ... title="Test configlet1"
+ ... description="Test configlet1 description" />
+ ... </configure>""", context)
+
+That's all. now we can get configlet as utility.
+
+As named IConfiglet
+
+ >>> cl = component.getUtility(interfaces.IConfiglet, name='configlet1')
+ >>> cl.__name__ == 'configlet1'
+ True
+ >>> cl.__title__ == 'Test configlet1'
+ True
+ >>> cl.__description__ == 'Test configlet1 description'
+ True
+
+As schema
+
+ >>> cl1 = component.getUtility(tests.ITestConfiglet1)
+ >>> cl is cl1
+ True
+
+ >>> cl.__schema__
+ <InterfaceClass z3ext.controlpanel.tests.ITestConfiglet1>
+
+We can't change __schema__ at runtime
+
+ >>> cl.__schema__ = tests.ITestConfiglet2
+ Traceback (most recent call last):
+ ...
+ AttributeError: Can't set __schema__
+
+
+IConfiglet
+----------
+
+Let's access the settings:
+
+ >>> cl.param1
+ u'default param1'
+
+ >>> cl.param2
+ 10
+
+which is the default value, since we have not set it yet. We can now reassign
+the value:
+
+ >>> cl.param1 = u'test'
+ >>> cl.param1
+ u'test'
+
+However, you cannot just enter any value, since it is validated before the
+assignment:
+
+ >>> cl.param2 = 'str'
+ Traceback (most recent call last):
+ ...
+ WrongType: ...
+
+You can delete attribute, default value would restored
+
+ >>> del cl.param1
+ >>> cl.param1
+ u'default param1'
+
+You can set/remove any attributes to configlet, but this attributes won't
+be persistent.
+
+ >>> cl.test = 1
+ >>> cl.test
+ 1
+
+ >>> del cl.test
+
+Configlet is ILocation object so it can't be used in traversing
+
+ >>> cl.__parent__
+ <z3ext.controlpanel.root.RootConfiglet object at ...>
+
+ >>> cl.__name__
+ u'configlet1'
+
+
+Configlet security
+------------------
+
+Read/Write access to configlet same as for <class> directive. By default
+all fields in IConfiglet interface and schema protected by 'z3ext.Configure'
+permission. We can define default permission by 'permission' attribute.
+We can use <require/> and <allow/> subdirectives inside <z3ext:configlet>
+directive.
+
+ >>> xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"
+ ... i18n_domain="zope">
+ ... <include package="z3ext.controlpanel" file="meta.zcml" />
+ ... <z3ext:configlet
+ ... name="configlet2"
+ ... schema="z3ext.controlpanel.tests.ITestConfiglet2"
+ ... title="Test configlet2"
+ ... permission="zope.Public">
+ ... <require />
+ ... </z3ext:configlet>
+ ... </configure>""")
+ Traceback (most recent call last):
+ ...
+ ZopeXMLConfigurationError: ...Nothing required...
+
+ >>> xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"
+ ... i18n_domain="zope">
+ ... <include package="z3ext.controlpanel" file="meta.zcml" />
+ ... <z3ext:configlet
+ ... name="configlet2"
+ ... schema="z3ext.controlpanel.tests.ITestConfiglet2"
+ ... title="Test configlet2"
+ ... permission="zope.Public">
+ ... <require attributes="param1" />
+ ... </z3ext:configlet>
+ ... </configure>""")
+ Traceback (most recent call last):
+ ...
+ ZopeXMLConfigurationError: ...No permission specified...
+
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"
+ ... i18n_domain="zope">
+ ... <include package="z3ext.controlpanel" file="meta.zcml" />
+ ... <z3ext:configlet
+ ... name="configlet2"
+ ... schema="z3ext.controlpanel.tests.ITestConfiglet2"
+ ... title="Test configlet2"
+ ... permission="zope.Public">
+ ... <require attributes="param1" permission="zope.Public" />
+ ... <allow attributes="param2" />
+ ... <require set_attributes="param3" permission="zope.Public" />
+ ... </z3ext:configlet>
+ ... </configure>""", context)
+
+
+Custom class implementation
+---------------------------
+
+We can use custom configlet implementation, but it should subclass
+original Configlet class
+
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"
+ ... i18n_domain="zope">
+ ... <include package="z3ext.controlpanel" file="meta.zcml" />
+ ... <z3ext:configlet
+ ... name="configlet3"
+ ... class="z3ext.controlpanel.tests.TestConfiglet1"
+ ... schema="z3ext.controlpanel.tests.ITestConfiglet2"
+ ... title="Test configlet3">
+ ... </z3ext:configlet>
+ ... </configure>""")
+
+ >>> configlet = component.getUtility(interfaces.IConfiglet, 'configlet3')
+ >>> isinstance(configlet, tests.TestConfiglet1)
+ True
+
+
+Configlet groups
+----------------
+
+The configlet would not be very powerful, if you could create a full
+settingss. So let's create a sub-configlet for settings:
+
+ >>> len(configlet)
+ 0
+
+ >>> 'configlet' in configlet
+ False
+
+ >>> configlet.get('configlet') is None
+ True
+
+ >>> configlet['configlet']
+ Traceback (most recent call last):
+ ...
+ KeyError: 'configlet'
+
+ >>> def testConfiglet(configlet):
+ ... return True
+
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"
+ ... i18n_domain="zope">
+ ... <include package="z3ext.controlpanel" file="meta.zcml" />
+ ... <z3ext:configlet
+ ... name="configlet3.configlet"
+ ... schema="z3ext.controlpanel.tests.ITestConfiglet1"
+ ... tests="z3ext.controlpanel.tests.testConfiglet1"
+ ... title="Test configlet4">
+ ... </z3ext:configlet>
+ ... </configure>""", context)
+
+ >>> configlet['configlet'].__parent__ is configlet
+ True
+
+ >>> len(configlet)
+ 1
+
+ >>> 'configlet' in configlet
+ True
+
+ >>> configlet['configlet'].__id__
+ u'configlet3.configlet'
+
+ >>> configlet.items()
+ [(u'configlet', <z3ext.controlpanel.configlettype.Configlet<configlet3.configlet> ...)]
+
+ >>> configlet.values()
+ [<z3ext.controlpanel.configlettype.Configlet<configlet3.configlet> ...>]
+
+ >>> list(iter(configlet))
+ [<z3ext.controlpanel.configlettype.Configlet<configlet3.configlet> ...>]
+
+
+Configlet availability
+----------------------
+
+We can check availability
+
+ >>> c1 = configlet['configlet']
+ >>> c1.isAvailable()
+ True
+
+ >>> c1.__tests__ = (tests.testConfiglet2,)
+ >>> c1.isAvailable()
+ False
+
+Avialability automaticly checks in parent configlet
+
+ >>> c1.__tests__ = (tests.testConfiglet1,)
+ >>> c1.isAvailable()
+ True
+
+ >>> configlet.__tests__ = (tests.testConfiglet2,)
+
+ >>> c1.isAvailable()
+ False
+
+ >>> c1.__tests__ = (tests.testConfiglet1, False)
+ >>> c1.isAvailable()
+ False
+
+ >>> configlet.remove('configlet')
+ >>> len(configlet)
+ 0
+
+
+Root configlet
+--------------
+
+There is root configlet. You can access any other configlets from root configlet.
+This configlet has no name, so it's available as nameless IConfiglet utility:
+
+ >>> from zope.app.component.hooks import getSite
+
+ >>> root = component.getUtility(interfaces.IConfiglet)
+ >>> root
+ <z3ext.controlpanel.root.RootConfiglet object at ...>
+
+Root configlet parent is ISite object
+
+ >>> root.__parent__ is getSite()
+ True
+
+ >>> tests.ITestConfiglet1.providedBy(root['configlet1'])
+ True
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/__init__.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/__init__.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/__init__.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/__init__.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/__init__.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/__init__.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/breadcrumb.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/breadcrumb.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/breadcrumb.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,29 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" custom IBreadcrumb implementation for IConfiglet
+
+$Id$
+"""
+from zope import interface, component
+from z3c.breadcrumb.interfaces import IBreadcrumb
+from z3c.breadcrumb.browser import GenericBreadcrumb
+from z3ext.controlpanel.interfaces import IConfiglet
+
+
+class ConfigletBreadcrumb(GenericBreadcrumb):
+ component.adapts(IConfiglet, interface.Interface)
+
+ @property
+ def name(self):
+ return self.context.__title__ or self.context.__name__
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/breadcrumb.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/category.pt
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/category.pt (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/category.pt 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,25 @@
+<div class="topframe" tal:define="configlets view/data" i18n:domain="z3ext">
+ <h1 tal:content="context/__title__">Configlet category</h1>
+ <div class="pageDescription"
+ tal:content="context/__description__">Description</div>
+
+ <div tal:condition="not:configlets" i18n:translate="">
+ There are no configlets in this category.
+ </div>
+
+ <ul class="listing" tal:condition="configlets" metal:define-macro="configlets">
+ <li tal:repeat="configlet configlets">
+ <div class="icon">
+ <tal:block tal:content="structure configlet/icon|nothing" />
+ </div>
+ <div class="details">
+ <a tal:attributes="href string:${configlet/configlet/@@absolute_url}/"
+ tal:content="configlet/title"></a>
+ <div><tal tal:content="configlet/description" /> </div>
+ <tal:block define="configlets configlet/items" condition="configlets">
+ <metal:block use-macro="view/template/macros/configlets" />
+ </tal:block>
+ </div>
+ </li>
+ </ul>
+</div>
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/category.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/category.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/category.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,60 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" category view
+
+$Id$
+"""
+from zope import interface
+from zope.component import queryMultiAdapter
+from z3ext.controlpanel.interfaces import ICategory, IConfiglet
+
+
+class CategoryView(object):
+
+ def update(self):
+ super(CategoryView, self).update()
+
+ request = self.request
+ context = self.context
+
+ data = self.process(context, request)
+
+ configlets = []
+ for info in data:
+ info['items'] = self.process(info['configlet'], request)
+ if ICategory.providedBy(info['configlet']) and not info['items']:
+ continue
+ configlets.append(info)
+ self.data = configlets
+
+ def process(self, context, request):
+ data = []
+ for configlet in context.values():
+ if not IConfiglet.providedBy(configlet) or \
+ not configlet.isAvailable():
+ continue
+
+ info = {'name': configlet.__name__,
+ 'title': configlet.__title__,
+ 'description': configlet.__description__,
+ 'icon': queryMultiAdapter(
+ (configlet, request), name='zmi_icon'),
+ 'items': (),
+ 'selected': False,
+ 'configlet': configlet}
+
+ data.append((configlet.__title__, info))
+
+ data.sort()
+ return [info for t, info in data]
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/category.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet.pt
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet.pt (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet.pt 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,25 @@
+<div class="topframe">
+ <form method="post" class="edit-form" enctype="multipart/form-data"
+ tal:attributes="action request/URL">
+ <h1 tal:content="view/label|nothing">Do something</h1>
+ <div class="discreet" tal:content="view/description|nothing"></div>
+ <br />
+
+ <div class="fieldset">
+ <div>
+ <tal:block tal:repeat="widget view/widgets">
+ <metal:block use-macro="context/@@form_macros/widget_row"/>
+ </tal:block>
+ </div>
+ </div>
+
+ <div id="formControls">
+ <hr />
+ <span class="actionButtons"
+ tal:condition="view/availableActions">
+ <input tal:repeat="action view/actions"
+ tal:replace="structure action/render" />
+ </span>
+ </div>
+ </form>
+</div>
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,35 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Default view for IConfiglet
+
+$Id$
+"""
+from zope.cachedescriptors.property import Lazy
+from z3ext.layoutform import Fields, PageletEditForm
+
+
+class Configlet(PageletEditForm):
+ """ configlet view """
+
+ @property
+ def label(self):
+ return self.context.__title__
+
+ @property
+ def description(self):
+ return self.context.__description__
+
+ @Lazy
+ def fields(self):
+ return Fields(self.context.__schema__)
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet_icon.gif
===================================================================
(Binary files differ)
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configlet_icon.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configure.zcml
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configure.zcml (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/configure.zcml 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,72 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:zcml="http://namespaces.zope.org/zcml"
+ xmlns:z3ext="http://namespaces.zope.org/z3ext"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="z3ext">
+
+ <z3ext:layout
+ layout="portal"
+ name="workspace"
+ for="..interfaces.IRootConfiglet"
+ template="layout.pt"
+ hidden="yes" />
+
+ <browser:icon
+ name="zmi_icon"
+ for="..interfaces.IConfiglet"
+ file="preferences-system.png" />
+
+ <browser:defaultView
+ name="index.html"
+ for="..interfaces.IConfiglet" />
+
+ <browser:menuItem
+ for="..interfaces.IConfiglet"
+ title="View"
+ menu="zmi_views"
+ action="index.html"
+ permission="zope.Public" />
+
+ <z3ext:pagelet
+ name="index.html"
+ for="..interfaces.IConfiglet"
+ class=".configlet.Configlet"
+ permission="zope.Public" />
+
+ <z3ext:pagelet
+ name="index.html"
+ for="..interfaces.ICategory"
+ template="category.pt"
+ class=".category.CategoryView"
+ permission="zope.Public" />
+
+ <!-- navigation -->
+ <browser:viewletManager
+ name="z3ext.controlpanel-navigation"
+ provides=".interfaces.IConfigletNavigation"
+ template="navigation.pt"
+ class=".navigation.Navigation"
+ permission="zope.Public" />
+
+ <!-- for ILocalSiteManager -->
+ <browser:menuItem
+ for="zope.app.component.interfaces.ISite"
+ menu="zmi_actions"
+ title="System settings"
+ action="settings/"
+ permission="z3ext.Configure" />
+
+ <browser:menuItem
+ for="zope.app.component.interfaces.ILocalSiteManager"
+ menu="zmi_actions"
+ title="System settings"
+ action="../settings/"
+ permission="z3ext.Configure" />
+
+ <!-- configlet breadcrumb -->
+ <adapter
+ zcml:condition="installed z3c.breadcrumb"
+ factory=".breadcrumb.ConfigletBreadcrumb" />
+
+</configure>
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/interfaces.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/interfaces.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/interfaces.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,22 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+from zope.viewlet.interfaces import IViewletManager
+
+
+class IConfigletNavigation(IViewletManager):
+ """ extra configlet navigation viewlet manager """
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/interfaces.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/layout.pt
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/layout.pt (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/layout.pt 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,14 @@
+<div id="z-portal-workspace"
+ tal:define="context nocall:maincontext;
+ nav provider:z3ext.controlpanel-navigation;
+ noNav not:nav; rendered view/render">
+ <div class="page">
+ <table class="wide" tal:omit-tag="noNav">
+ <tr style="vertical-align: top" tal:omit-tag="noNav">
+ <td style="padding-right: 1em; width: 200px"
+ tal:condition="nav" tal:content="structure nav"></td>
+ <td tal:omit-tag="noNav" tal:content="structure rendered"></td>
+ </tr>
+ </table>
+ </div>
+</div>
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/navigation.pt
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/navigation.pt (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/navigation.pt 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,23 @@
+<tal:block tal:repeat="viewlet view/viewlets"
+ tal:content="structure viewlet/render" />
+
+<div class="x-listing box small">
+ <tal:block tal:repeat="item view/data">
+ <metal:block metal:define-macro="level">
+ <div class="x-listing-item"
+ tal:attributes="class python:item['selected'] and 'x-listing-item-selected'
+ or 'x-listing-item'">
+ <div tal:omit-tag="not:item/level|nothing"
+ tal:attributes="class string:level${item/level|nothing}">
+ <a tal:attributes="href string:${item/configlet/@@absolute_url}/">
+ <al:block tal:content="structure item/icon" />
+ <tal:block tal:content="item/title" />
+ </a>
+ </div>
+ </div>
+ <tal:block tal:repeat="item item/items">
+ <metal:block use-macro="view/template/macros/level"/>
+ </tal:block>
+ </metal:block>
+ </tal:block>
+</div>
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/navigation.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/navigation.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/navigation.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,80 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+from zope.component import queryMultiAdapter
+from zope.viewlet.manager import ViewletManagerBase
+from z3ext.controlpanel.interfaces import IConfiglet, IRootConfiglet
+
+
+class Navigation(ViewletManagerBase):
+
+ def update(self):
+ super(Navigation, self).update()
+
+ context = self.context
+
+ self.isRoot = IRootConfiglet.providedBy(context)
+ if self.isRoot:
+ return
+
+ path = []
+ parent = context
+ while IConfiglet.providedBy(parent):
+ path.insert(0, parent)
+ parent = parent.__parent__
+
+ self.root, path = path[0], path[1:]
+
+ self.data = self._process(self.root, path)
+
+ def _process(self, context, path, level=1):
+ request = self.request
+
+ if path:
+ data = []
+ for name, configlet in context.items():
+ if not IConfiglet.providedBy(configlet) or \
+ not configlet.isAvailable():
+ continue
+
+ info = {'name': name,
+ 'title': configlet.__title__,
+ 'icon': queryMultiAdapter(
+ (configlet, request), name='zmi_icon'),
+ 'items': (),
+ 'selected': False,
+ 'configlet': configlet,
+ 'level': level}
+
+ if configlet.__id__ == path[0].__id__:
+ info['items'] = self._process(configlet, path[1:], level+1)
+
+ if configlet.__id__ == self.context.__id__:
+ info['selected'] = True
+ info['items'] = self._process(configlet, [configlet], level+1)
+
+ data.append((configlet.__title__, info))
+
+ data.sort()
+ data = [info for t, info in data]
+ return data
+
+ def render(self):
+ if self.isRoot:
+ return u''
+ else:
+ return super(Navigation, self).render()
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/navigation.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/preferences-system.png
===================================================================
(Binary files differ)
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/preferences-system.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/README.txt
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/README.txt (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/README.txt 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,85 @@
+=============
+Control Panel
+=============
+
+We can access controlpanel with following url http://localhost/settings/
+'setting' name availabel for every ISite object.
+
+Let's demonstrate how we can access controlpanel.
+
+ >>> from zope import component
+ >>> from zope.testbrowser.testing import Browser
+
+ >>> browser = Browser()
+ >>> browser.handleErrors = False
+ >>> browser.open("http://localhost/settings/")
+ Traceback (most recent call last):
+ ...
+ Unauthorized: settings
+
+ >>> browser.open("http://localhost/settings/system/")
+ Traceback (most recent call last):
+ ...
+ Unauthorized: settings
+
+ >>> browser = Browser()
+ >>> browser.addHeader("Authorization", "Basic mgr:mgrpw")
+ >>> browser.handleErrors = False
+
+We should have 'System settings' link in ISite actions menu
+
+ >>> browser.open("http://localhost/@@contents.html")
+ >>> print browser.contents
+ <!DOCTYPE html PUBLIC...
+ ...<li><a href="settings/">System settings</a></li>...
+ <BLANKLINE>
+
+ >>> browser.getLink('System settings').click()
+ >>> print browser.contents
+ <!DOCTYPE html PUBLIC...
+ ...System settings...
+ <BLANKLINE>
+
+Configlet categories, by default only first level of categories is
+shown. And only categories that have visible configlets.
+
+ >>> 'Category1' in browser.contents
+ False
+
+ >>> 'Category2' in browser.contents
+ True
+
+Also controlponal show configlets in toplevel categories
+
+ >>> 'Configlet1' in browser.contents
+ True
+
+Category shows only its configlets
+
+ >>> browser.open("http://localhost/settings/category1/")
+ >>> print browser.contents
+ <!DOCTYPE html PUBLIC...
+ ...Category1...
+ ...Category 1 area...
+ ...There are no configlets in this category...
+ <BLANKLINE>
+
+ >>> browser.open("http://localhost/settings/category2/")
+ >>> print browser.contents
+ <!DOCTYPE html PUBLIC...
+ ...Category2...
+ ...Category 2 area...
+ ...http://localhost/settings/category2/configlet1/...Configlet1...
+ ...http://localhost/settings/category2/configlet2/...Configlet2...
+ <BLANKLINE>
+
+But it should not show not available configlets.
+
+ >>> 'Configlet3' in browser.contents
+ False
+
+By default control panel create edit for each configlet, form name 'index.html'
+
+ >>> browser.getLink('Configlet1').click()
+ >>> browser.getControl(name='form.buttons.save').click()
+ >>> browser.getControl(name='form.buttons.cancel').click()
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/__init__.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/__init__.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/__init__.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/configure.zcml
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/configure.zcml (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/configure.zcml 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,46 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:z3ext="http://namespaces.zope.org/z3ext"
+ xmlns:browser="http://namespaces.zope.org/browser">
+
+ <interface
+ name="MySkin"
+ interface=".interfaces.MySkin"
+ type="zope.publisher.interfaces.browser.IBrowserSkinType" />
+
+ <z3ext:configlet
+ name="category1"
+ schema=".interfaces.ICategory1"
+ title="Category1"
+ description="Category 1 area."
+ provides="z3ext.controlpanel.interfaces.ICategory"
+ permission="zope.Public" />
+
+ <z3ext:configlet
+ name="category2"
+ schema=".interfaces.ICategory2"
+ title="Category2"
+ description="Category 2 area."
+ provides="z3ext.controlpanel.interfaces.ICategory"
+ permission="zope.Public" />
+
+ <z3ext:configlet
+ name="category2.configlet1"
+ schema=".interfaces.IConfiglet1"
+ title="Configlet1"
+ permission="zope.Public" />
+
+ <z3ext:configlet
+ name="category2.configlet2"
+ schema=".interfaces.IConfiglet2"
+ title="Configlet2"
+ permission="zope.Public" />
+
+ <z3ext:configlet
+ name="category2.configlet3"
+ schema=".interfaces.IConfiglet3"
+ title="Configlet3"
+ tests=".interfaces.notAvailable"
+ permission="zope.Public" />
+
+</configure>
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/interfaces.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/interfaces.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/interfaces.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,66 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+from zope import schema, interface
+from zope.app.rotterdam import Rotterdam
+from z3ext.layoutform.interfaces import ILayoutFormLayer
+
+
+class MySkin(ILayoutFormLayer, Rotterdam):
+ """ my skin """
+
+
+class ICategory1(interface.Interface):
+ """ test category 1 """
+
+
+class ICategory2(interface.Interface):
+ """ test category 2 """
+
+
+class IConfiglet1(interface.Interface):
+
+ param1 = schema.TextLine(
+ title = u'param1',
+ default = u'default param1')
+
+ param2 = schema.Int(
+ title = u'param2',
+ default = 10)
+
+
+class IConfiglet2(interface.Interface):
+
+ param1 = schema.TextLine(
+ title = u'param1',
+ default = u'default param1')
+
+ param2 = schema.Int(
+ title = u'param2',
+ default = 10)
+
+ param3 = schema.TextLine(
+ title = u'param3',
+ default = u'default param3')
+
+
+class IConfiglet3(interface.Interface):
+ pass
+
+
+def notAvailable(*args):
+ return False
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/interfaces.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/test_functional.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/test_functional.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/test_functional.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,35 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+import unittest, doctest
+from zope import interface
+from zope.app.testing import functional
+from zope.publisher.browser import BrowserRequest
+from z3ext.controlpanel.testing import z3extControlPanelLayer
+
+from interfaces import MySkin
+
+
+def test_suite():
+ interface.classImplements(BrowserRequest, MySkin)
+
+ controlpanel = functional.FunctionalDocFileSuite(
+ "README.txt",
+ optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE)
+ controlpanel.layer = z3extControlPanelLayer
+
+ return unittest.TestSuite((controlpanel,))
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/browser/tests/test_functional.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/configlet.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/configlet.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/configlet.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,114 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Configlet implementation
+
+$Id$
+"""
+from zope import schema, interface
+from zope.location import Location
+from zope.component import getUtility, queryUtility
+from zope.security.proxy import removeSecurityProxy
+from zope.interface.common.mapping import IEnumerableMapping
+
+from interfaces import IConfiglet, IDataStorage
+
+_marker = object()
+
+
+class Configlet(Location):
+ interface.implements(IConfiglet, IEnumerableMapping)
+
+ def __init__(self, tests=()):
+ self.__name__ = self.__id__.rsplit('.', 1)[-1]
+ self.__tests__ = tests
+ self.__subgroups__ = ()
+
+ @property
+ def data(self):
+ data = getUtility(IDataStorage)
+ return removeSecurityProxy(data)[self.__name__]
+
+ def isAvailable(self):
+ for test in self.__tests__:
+ if callable(test):
+ if not test(self):
+ return False
+ elif not bool(test):
+ return False
+
+ if IConfiglet.providedBy(self.__parent__):
+ if not self.__parent__.isAvailable():
+ return False
+
+ return True
+
+ def add(self, name):
+ if name not in self.__subgroups__:
+ self.__subgroups__ = self.__subgroups__ + (name,)
+
+ def remove(self, name):
+ if name in self.__subgroups__:
+ names = list(self.__subgroups__)
+ names.remove(name)
+ self.__subgroups__ = tuple(names)
+
+ # implementation of IEnumerableMapping interface
+ def __getitem__(self, key):
+ obj = self.get(key, _marker)
+ if obj is _marker:
+ raise KeyError(key)
+ return obj
+
+ def get(self, key, default=None):
+ id = self.__id__ and self.__id__ + '.' + key or key
+ configlet = queryUtility(IConfiglet, id, default)
+ if configlet is default:
+ return default
+ return configlet
+
+ def __contains__(self, key):
+ return key in self.keys()
+
+ def keys(self):
+ return self.__subgroups__
+
+ def __iter__(self):
+ id = self.__id__
+ if id:
+ id = id + '.'
+
+ for key in self.keys():
+ name = id + key
+ configlet = queryUtility(IConfiglet, name)
+ if configlet is not None:
+ yield configlet
+
+ def values(self):
+ return [group for id, group in self.items()]
+
+ def items(self):
+ id = self.__id__
+ if id:
+ id = id + '.'
+
+ items = []
+ for key in self.keys():
+ name = id + key
+ configlet = queryUtility(IConfiglet, name)
+ if configlet is not None:
+ items.append((key, configlet))
+ return items
+
+ def __len__(self):
+ return len(self.keys())
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/configlet.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/configlettype.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/configlettype.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/configlettype.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,192 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Configlet metaclass
+
+$Id$
+"""
+import sys
+from zope.schema import getFields
+
+from z3ext.controlpanel.i18n import _
+from z3ext.controlpanel.configlet import Configlet
+
+_marker = object()
+
+
+class ConfigletType(type):
+ """ Metaclass for all configlets
+
+ >>> from zope import interface, schema
+ >>> from z3ext.controlpanel import configlettype
+
+ >>> class IMyConfiglet(interface.Interface):
+ ... title = schema.TextLine(title = u'Title')
+
+ >>> class MyConfiglet(object):
+ ... pass
+
+ >>> ConfigletClass = configlettype.ConfigletType(
+ ... 'myconfiglet', IMyConfiglet, MyConfiglet, 'MyConfiglet', '')
+
+ New class avilable by it's cname in z3ext.controlpanel.configlettype module
+
+ >>> getattr(configlettype, 'Configlet<myconfiglet>') is ConfigletClass
+ True
+
+ Automaticly generate schema fields to ConfigletProperty
+
+ >>> ConfigletClass.title
+ <z3ext.controlpanel.configlettype.ConfigletProperty object at ...>
+
+ >>> configlet = ConfigletClass()
+ >>> configlet
+ <z3ext.controlpanel.configlettype.Configlet<myconfiglet> object at ...>
+
+ >>> isinstance(configlet, MyConfiglet)
+ True
+
+ >>> isinstance(configlet, configlettype.Configlet)
+ True
+
+ We also can use number of base classes
+
+ >>> class MyConfiglet2(object):
+ ... pass
+
+ >>> ConfigletClass = configlettype.ConfigletType(
+ ... 'myconfiglet', IMyConfiglet,
+ ... (MyConfiglet, MyConfiglet2), 'MyConfiglet', '')
+
+ """
+
+ def __new__(cls, name, schema, class_=None, *args, **kw):
+ cname = 'Configlet<%s>'%name
+ if type(class_) is tuple:
+ bases = class_ + (Configlet,)
+ elif class_ is not None:
+ bases = (class_, Configlet)
+ else:
+ bases = (Configlet,)
+
+ tp = type.__new__(cls, str(cname), bases, {})
+ setattr(sys.modules['z3ext.controlpanel.configlettype'], cname, tp)
+
+ return tp
+
+ def __init__(cls, name, schema, class_=None, title='', description=''):
+ for f_id in getFields(schema):
+ if not hasattr(cls, f_id):
+ setattr(cls, f_id, ConfigletProperty(schema[f_id]))
+
+ cls.__id__ = unicode(name)
+ cls.__title__ = title
+ cls.__description__ = description
+ cls.__schema__ = DataProperty(schema)
+
+
+class DataProperty(object):
+
+ def __init__(self, schema):
+ self.schema = schema
+
+ def __get__(self, inst, klass):
+ return self.schema
+
+ def __set__(self, inst, value):
+ raise AttributeError("Can't set __schema__")
+
+
+class ConfigletProperty(object):
+ """ Special property thats reads and writes values from
+ instance's 'data' attribute
+
+ Let's define simple schema field
+
+ >>> from zope import schema
+ >>> field = schema.TextLine(
+ ... title = u'Test',
+ ... default = u'default value')
+ >>> field.__name__ = 'attr1'
+
+ Now we need content class
+
+ >>> from z3ext.controlpanel.configlettype import ConfigletProperty
+ >>> class Content(object):
+ ...
+ ... attr1 = ConfigletProperty(field)
+
+ Lets create class instance and add field values storage
+
+ >>> ob = Content()
+ >>> ob.data = {}
+
+ By default we should get field default value
+
+ >>> ob.attr1
+ u'default value'
+
+ We can set only valid value
+
+ >>> ob.attr1 = 'value1'
+ Traceback (most recent call last):
+ ...
+ WrongType: ('value1', <type 'unicode'>)
+
+ >>> ob.attr1 = u'value1'
+ >>> ob.attr1
+ u'value1'
+
+ If storage contains field value we shuld get it
+
+ >>> ob.data['attr1'] = u'value2'
+ >>> ob.attr1
+ u'value2'
+
+ We can't set value for readonly fields
+
+ >>> field.readonly = True
+ >>> ob.attr1 = u'value1'
+ Traceback (most recent call last):
+ ...
+ ValueError: ('attr1', 'field is readonly')
+
+ """
+
+ def __init__(self, field, name=None):
+ if name is None:
+ name = field.__name__
+
+ self.__field = field
+ self.__name = name
+
+ def __get__(self, inst, klass):
+ if inst is None:
+ return self
+
+ value = inst.data.get(self.__name, _marker)
+ if value is _marker:
+ return self.__field.default
+
+ return value
+
+ def __set__(self, inst, value):
+ field = self.__field.bind(inst)
+ field.validate(value)
+ if field.readonly and self.__name in inst.data:
+ raise ValueError(self.__name, _(u'Field is readonly'))
+ inst.data[self.__name] = value
+
+ def __delete__(self, inst):
+ if self.__name in inst.data:
+ del inst.data[self.__name]
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/configlettype.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/configure.zcml
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/configure.zcml (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/configure.zcml 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,83 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:z3ext="http://namespaces.zope.org/z3ext"
+ i18n_domain="z3ext">
+
+ <autoinclude package="z3ext.controlpanel" />
+
+ <permission
+ id="z3ext.Configure"
+ title="Configure control panel's configlets." />
+
+ <utility
+ provides=".interfaces.IConfiglet"
+ factory=".root.RootConfiglet" />
+
+ <class class=".root.RootConfiglet">
+ <require
+ permission="zope.Public"
+ interface=".interfaces.IConfiglet
+ zope.interface.common.mapping.IEnumerableMapping" />
+ </class>
+
+ <z3ext:configlet
+ name="system"
+ schema=".interfaces.ISystemConfiglet"
+ title="System configuration"
+ description="This area allows you to configure system."
+ provides=".interfaces.ICategory"
+ permission="zope.Public" />
+
+ <z3ext:configlet
+ name="principals"
+ schema=".interfaces.IPrincipalsConfiglet"
+ title="Portal principals"
+ description="Portal principals related settings."
+ provides=".interfaces.ICategory"
+ permission="zope.Public" />
+
+ <z3ext:configlet
+ name="ui"
+ schema=".interfaces.IUIConfiguration"
+ title="Portal ui configuration"
+ description="This area allows you to configure portal look&feel."
+ provides=".interfaces.ICategory"
+ permission="zope.Public" />
+
+ <utility factory=".storage.DataStorage" />
+
+ <!-- settings view -->
+ <adapter
+ name="settings"
+ for="zope.app.component.interfaces.ISite *"
+ provides="zope.interface.Interface"
+ factory=".root.getSettings" />
+
+ <!-- Configlet publisher -->
+ <adapter
+ for=".interfaces.IConfiglet *"
+ factory="z3c.traverser.traverser.PluggableTraverser"
+ provides="zope.publisher.interfaces.IPublishTraverse" />
+
+ <subscriber
+ for=".interfaces.IConfiglet *"
+ provides="z3c.traverser.interfaces.ITraverserPlugin"
+ factory="z3c.traverser.traverser.ContainerTraverserPlugin" />
+
+ <include package=".browser" />
+
+ <!-- Registering documentation with API doc -->
+ <configure
+ xmlns:apidoc="http://namespaces.zope.org/apidoc"
+ xmlns:zcml="http://namespaces.zope.org/zcml"
+ zcml:condition="have apidoc">
+
+ <apidoc:bookchapter
+ id="z3ext-controlpanel"
+ title="z3ext.controlpanel - Control Panel"
+ doc_path="README.txt"
+ parent="z3ext" />
+
+ </configure>
+
+</configure>
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/ftesting.zcml
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/ftesting.zcml (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/ftesting.zcml 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,58 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ i18n_domain="z3ext" package="z3ext.controlpanel">
+
+ <!-- This file is the equivalent of site.zcml and it is -->
+ <!-- used for functional testing setup -->
+
+ <include package="zope.component" file="meta.zcml" />
+ <include package="zope.securitypolicy" file="meta.zcml" />
+ <include package="zope.viewlet" file="meta.zcml" />
+ <include package="zope.app.component" file="meta.zcml" />
+ <include package="zope.app.security" file="meta.zcml" />
+ <include package="zope.app.pagetemplate" file="meta.zcml" />
+
+ <include package="zope.securitypolicy" />
+ <include package="zope.contentprovider" />
+ <include package="zope.app.security" />
+ <include package="zope.app.zcmlfiles" />
+ <include package="zope.app.authentication" />
+ <include package="zope.session" />
+
+ <include package="z3c.autoinclude" file="meta.zcml" />
+ <include package="z3ext.controlpanel" file="meta.zcml" />
+ <include package="z3ext.controlpanel" />
+ <include package="z3ext.controlpanel.browser.tests" />
+ <include package="z3ext.portalmessage" />
+
+ <securityPolicy
+ component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
+
+ <role id="zope.Anonymous" title="Everybody"
+ description="All users have this role implicitly" />
+ <role id="zope.Manager" title="Site Manager" />
+
+ <!-- Replace the following directive if you don't want public access -->
+ <grant permission="zope.View"
+ role="zope.Anonymous" />
+
+ <grant permission="zope.app.dublincore.view"
+ role="zope.Anonymous" />
+
+ <!-- Principals -->
+ <unauthenticatedPrincipal
+ id="zope.anybody"
+ title="Unauthenticated User" />
+
+ <!-- Principal that tests generally run as -->
+ <principal
+ id="zope.mgr"
+ title="Manager"
+ login="mgr"
+ password="mgrpw" />
+
+ <grant role="zope.Manager" principal="zope.mgr" />
+
+ <grantAll role="zope.Manager" />
+
+</configure>
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/i18n.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/i18n.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/i18n.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" i18n
+
+$Id$
+"""
+from zope.i18nmessageid import MessageFactory
+_ = MessageFactory('z3ext')
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/i18n.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/interfaces.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/interfaces.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/interfaces.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,73 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" z3ext.controlpanel interfaces
+
+$Id$
+"""
+from zope import schema, interface
+from zope.location.interfaces import ILocation
+
+
+class ICategory(interface.Interface):
+ """ settings category """
+
+
+class IRootConfiglet(interface.Interface):
+ """ root settings configlet """
+
+
+class ISystemConfiglet(interface.Interface):
+ """This area allows you to configure system."""
+
+
+class IPrincipalsConfiglet(interface.Interface):
+ """ Portal principals related settings """
+
+
+class IUIConfiguration(interface.Interface):
+ """ Portal UI related settings """
+
+
+class IDataStorage(interface.Interface):
+ """ data storage """
+
+ def get(name):
+ """ get named data """
+
+ def __getitem__(name):
+ """ get named data """
+
+
+class IConfiglet(ILocation):
+ """A group of settings."""
+
+ __id__ = schema.TextLine(
+ title = u"Id",
+ description = u"The id of the configlet.",
+ required = True)
+
+ __title__ = schema.TextLine(
+ title = u"Title",
+ description = u"The title of the configlet used in the UI.",
+ required = True)
+
+ __description__ = schema.TextLine(
+ title = u"Description",
+ description = u"The description of the configlet used in the UI.",
+ required = False)
+
+ __schema__ = interface.Attribute('Configlet schema (readonly)')
+
+ def isAvailable():
+ """ is configlet available in current site """
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/interfaces.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/meta.zcml
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/meta.zcml (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/meta.zcml 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,22 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:meta="http://namespaces.zope.org/meta">
+
+ <meta:directives namespace="http://namespaces.zope.org/z3ext">
+ <meta:complexDirective
+ name="configlet"
+ schema=".zcml.IConfigletDirective"
+ handler=".zcml.ConfigletDirective">
+
+ <meta:subdirective
+ name="allow"
+ schema="zope.app.component.metadirectives.IAllowSubdirective" />
+
+ <meta:subdirective
+ name="require"
+ schema="zope.app.component.metadirectives.IRequireSubdirective" />
+ </meta:complexDirective>
+
+ </meta:directives>
+
+</configure>
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/root.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/root.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/root.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Root configlet
+
+$Id$
+"""
+from zope import interface, component
+from zope.component import getUtility
+from zope.security import checkPermission
+from zope.security.interfaces import Unauthorized
+
+from zope.app.component.hooks import getSite
+from zope.app.component.interfaces import ISite
+
+from i18n import _
+from configlet import Configlet
+from interfaces import IConfiglet, IRootConfiglet, ICategory
+
+
+class RootConfiglet(Configlet):
+ interface.implements(ICategory, IRootConfiglet)
+
+ __id__ = ''
+ __name__ = 'settings'
+ __title__ = _(u'System settings')
+ __description__ = ''
+ __schema__ = IRootConfiglet
+
+ def __init__(self):
+ self.__subgroups__ = ()
+
+ def isAvailable(self):
+ return True
+
+ @property
+ def __parent__(self):
+ return getSite()
+
+
+ at interface.implementer(interface.Interface)
+ at component.adapter(ISite, interface.Interface)
+def getSettings(site, request):
+ if not checkPermission('z3ext.Configure', site):
+ raise Unauthorized('settings')
+ return getUtility(IConfiglet)
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/root.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/storage.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/storage.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/storage.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,50 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" IDataStorage implementation
+
+$Id$
+"""
+from BTrees.OOBTree import OOBTree
+
+from zope import interface
+from zope.app.component.hooks import getSite
+from zope.annotation.interfaces import IAnnotations
+from z3ext.controlpanel.interfaces import IDataStorage
+
+key = 'z3ext.controlpanel.Settings'
+_temp = {}
+
+class DataStorage(object):
+ interface.implements(IDataStorage)
+
+ @property
+ def _data(self):
+ site = getSite()
+ ann = IAnnotations(site, None)
+ if ann is None:
+ return _temp
+
+ storage = ann.get(key)
+ if storage is None:
+ storage = OOBTree()
+ ann[key] = storage
+
+ return storage
+
+ def __getitem__(self, name):
+ try:
+ return self._data[name]
+ except KeyError:
+ self._data[name] = OOBTree()
+ return self._data[name]
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/storage.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/testing.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/testing.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/testing.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,40 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" setup z3ext.controlpanel
+
+$Id$
+"""
+import os
+from zope import component
+from zope.app.testing import setup
+from zope.annotation.attribute import AttributeAnnotations
+from zope.app.component.hooks import getSite, setSite
+from zope.app.testing.functional import ZCMLLayer
+
+from z3ext.controlpanel import storage, root, interfaces
+
+
+def setUpControlPanel():
+ setup.setUpTraversal()
+ setup.setUpSiteManagerLookup()
+
+ component.provideAdapter(root.getSettings, name='settings')
+ component.provideAdapter(AttributeAnnotations)
+ component.provideUtility(storage.DataStorage())
+ component.provideUtility(root.RootConfiglet(), interfaces.IConfiglet)
+
+
+z3extControlPanelLayer = ZCMLLayer(
+ os.path.join(os.path.split(__file__)[0], 'ftesting.zcml'),
+ __name__, 'z3extControlPanelLayer', allow_teardown=True)
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/testing.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/tests.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/tests.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/tests.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,81 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" z3ext Control Panel tests
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import unittest, doctest
+from zope import interface, schema
+from zope.app.testing import setup
+from z3ext.controlpanel.configlet import Configlet
+from z3ext.controlpanel.testing import setUpControlPanel
+
+def testConfiglet1(configlet):
+ return True
+
+def testConfiglet2(configlet):
+ return False
+
+
+class ITestConfiglet1(interface.Interface):
+
+ param1 = schema.TextLine(
+ title = u'param1',
+ default = u'default param1')
+
+ param2 = schema.Int(
+ title = u'param2',
+ default = 10)
+
+
+class ITestConfiglet2(interface.Interface):
+
+ param1 = schema.TextLine(
+ title = u'param1',
+ default = u'default param1')
+
+ param2 = schema.Int(
+ title = u'param2',
+ default = 10)
+
+ param3 = schema.TextLine(
+ title = u'param3',
+ default = u'default param3')
+
+
+class TestConfiglet1(Configlet):
+ pass
+
+
+class TestConfiglet2(object):
+ pass
+
+
+def setUp(test):
+ setup.placefulSetUp(True)
+ setUpControlPanel()
+
+
+def test_suite():
+ return unittest.TestSuite((
+ doctest.DocFileSuite(
+ 'README.txt',
+ setUp=setUp, tearDown=setup.placefulTearDown(),
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS),
+ doctest.DocTestSuite(
+ 'z3ext.controlpanel.configlettype',
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS),
+ ))
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/tests.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3ext.controlpanel/trunk/src/z3ext/controlpanel/zcml.py
===================================================================
--- z3ext.controlpanel/trunk/src/z3ext/controlpanel/zcml.py (rev 0)
+++ z3ext.controlpanel/trunk/src/z3ext/controlpanel/zcml.py 2008-03-21 09:09:54 UTC (rev 84833)
@@ -0,0 +1,219 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" z3ext:configlet directive
+
+$Id$
+"""
+from zope import interface
+from zope.schema import getFields
+from zope.interface.common.mapping import IEnumerableMapping
+
+from zope.component import getUtility
+from zope.component.zcml import utility
+from zope.component.interface import provideInterface
+
+from zope.schema.interfaces import IField
+
+from zope.security import checkPermission
+from zope.security.zcml import Permission
+from zope.security.checker import Checker, CheckerPublic
+
+from zope.configuration import fields
+from zope.configuration.exceptions import ConfigurationError
+
+from zope.app.security.protectclass import protectName, protectSetAttribute
+
+from configlet import Configlet
+from configlettype import ConfigletType
+from interfaces import IConfiglet
+
+
+class IConfigletDirective(interface.Interface):
+
+ name = fields.PythonIdentifier(
+ title = u"Name",
+ description = u"Name of the configlet used to access the settings.",
+ required = True)
+
+ schema = fields.GlobalInterface(
+ title = u"Configlet schema",
+ description = u"This attribute specifies the schema of the configlet",
+ required = True)
+
+ title = fields.MessageID(
+ title = u"Title",
+ description = u"Title of the configlet used in UIs.",
+ required = True)
+
+ description = fields.MessageID(
+ title = u"Description",
+ description = u"Description of the configlet used in UIs.",
+ required = False)
+
+ class_ = fields.GlobalObject(
+ title = u"Class",
+ description = u'Custom configlet class',
+ required = False)
+
+ provides = fields.Tokens(
+ title = u'Provides',
+ required = False,
+ value_type = fields.GlobalInterface())
+
+ permission = Permission(
+ title = u'Permission',
+ description = u'Default access permission.',
+ required = False)
+
+ tests = fields.Tokens(
+ title = u"Tests",
+ description = u'Tests for check availability.',
+ value_type = fields.GlobalObject(),
+ required = False)
+
+
+class ConfigletDirective(object):
+
+ def __init__(self, _context, name, schema, title,
+ description='', class_=None, provides=(),
+ permission='z3ext.Configure', tests=(), install_schema_utility=True):
+
+ ConfigletClass = ConfigletType(
+ str(name), schema, class_, title, description)
+
+ if permission == 'zope.Public':
+ configlet = ConfigletClass(tuple(tests))
+ else:
+ configlet = ConfigletClass(
+ (PermissionChecker(permission),) + tuple(tests))
+
+ utility(_context, IConfiglet, configlet, name=name)
+
+ if install_schema_utility:
+ utility(_context, schema, configlet)
+
+ interface.classImplements(ConfigletClass, schema, *provides)
+
+ self._class = ConfigletClass
+ self._context = _context
+ self._configlet = configlet
+ self._permission = permission
+
+ self.require(_context, permission,
+ interface=(IConfiglet, schema), set_schema=(schema,))
+ self.require(_context, CheckerPublic, interface=(IEnumerableMapping,))
+ self.require(_context, CheckerPublic, attributes=('isAvailable',))
+
+ _context.action(
+ discriminator=('z3ext:controlpanel', configlet),
+ callable=addSubgroup, args=(configlet,))
+
+ def require(self, _context,
+ permission=None, attributes=None, interface=None,
+ like_class=None, set_attributes=None, set_schema=None):
+ """Require a permission to access a specific aspect"""
+ if not (interface or attributes or set_attributes or set_schema):
+ raise ConfigurationError("Nothing required")
+
+ if not permission:
+ raise ConfigurationError("No permission specified")
+
+ if interface:
+ for i in interface:
+ if i:
+ self.__protectByInterface(i, permission)
+
+ if attributes:
+ self.__protectNames(attributes, permission)
+
+ if set_attributes:
+ self.__protectSetAttributes(set_attributes, permission)
+
+ if set_schema:
+ for s in set_schema:
+ self.__protectSetSchema(s, permission)
+
+ def allow(self, _context, attributes=None, interface=None):
+ """Like require, but with permission_id zope.Public"""
+ return self.require(_context, self._permission, attributes, interface)
+
+ def __protectByInterface(self, interface, permission_id):
+ "Set a permission on names in an interface."
+ for n, d in interface.namesAndDescriptions(1):
+ self.__protectName(n, permission_id)
+
+ self._context.action(
+ discriminator = None,
+ callable = provideInterface,
+ args = (interface.__module__+'.'+interface.getName(), interface))
+
+ def __protectName(self, name, permission_id):
+ "Set a permission on a particular name."
+ self._context.action(
+ discriminator = ('z3ext:controlpanel:protectName',
+ self._class, name, object()),
+ callable = protectName,
+ args = (self._class, name, permission_id))
+
+ def __protectNames(self, names, permission_id):
+ "Set a permission on a bunch of names."
+ for name in names:
+ self.__protectName(name, permission_id)
+
+ def __protectSetAttributes(self, names, permission_id):
+ "Set a permission on a bunch of names."
+ for name in names:
+ self._context.action(
+ discriminator = ('z3ext:controlpanel:protectSetAttribute',
+ self._class, name, object()),
+ callable = protectSetAttribute,
+ args = (self._class, name, permission_id))
+
+ def __protectSetSchema(self, schema, permission_id):
+ "Set a permission on a bunch of names."
+ _context = self._context
+
+ for name in schema:
+ field = schema[name]
+ if IField.providedBy(field) and not field.readonly:
+ _context.action(
+ discriminator = ('z3ext:controlpanel:protectSetAttribute',
+ self._class, name, object()),
+ callable = protectSetAttribute,
+ args = (self._class, name, permission_id))
+
+ _context.action(
+ discriminator = None,
+ callable = provideInterface,
+ args = (schema.__module__+'.'+schema.getName(), schema))
+
+
+def addSubgroup(configlet):
+ if '.' in configlet.__id__:
+ parentId = configlet.__id__.rsplit('.', 1)[0]
+ else:
+ parentId = ''
+
+ parent = getUtility(IConfiglet, parentId)
+ parent.add(configlet.__name__)
+ configlet.__parent__ = parent
+
+
+class PermissionChecker(object):
+
+ def __init__(self, permission):
+ self.permission = permission
+
+ def __call__(self, configlet):
+ return checkPermission(self.permission, configlet)
Property changes on: z3ext.controlpanel/trunk/src/z3ext/controlpanel/zcml.py
___________________________________________________________________
Name: svn:keywords
+ Id
More information about the Checkins
mailing list