[Checkins] SVN: Sandbox/ulif/grok-adminui-experimental/ Merged
trunk into adminui-experimental branch.
Uli Fouquet
uli at gnufix.de
Thu Aug 30 19:53:55 EDT 2007
Log message for revision 79388:
Merged trunk into adminui-experimental branch.
Changed:
A Sandbox/ulif/grok-adminui-experimental/CHANGES.txt
U Sandbox/ulif/grok-adminui-experimental/CREDITS.txt
U Sandbox/ulif/grok-adminui-experimental/README.txt
U Sandbox/ulif/grok-adminui-experimental/buildout.cfg
A Sandbox/ulif/grok-adminui-experimental/doc/examples/MOVED.txt
D Sandbox/ulif/grok-adminui-experimental/doc/examples/adder/
D Sandbox/ulif/grok-adminui-experimental/doc/examples/animaltree/
D Sandbox/ulif/grok-adminui-experimental/doc/examples/bookshelf/
D Sandbox/ulif/grok-adminui-experimental/doc/examples/todolist/
U Sandbox/ulif/grok-adminui-experimental/doc/grok2html.py
U Sandbox/ulif/grok-adminui-experimental/doc/index.txt
U Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/index.txt
U Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/macros.txt
A Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/permissions.txt
A Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/xmlrpc.txt
U Sandbox/ulif/grok-adminui-experimental/doc/reference/directives.tex
U Sandbox/ulif/grok-adminui-experimental/doc/reference/reference.tex
U Sandbox/ulif/grok-adminui-experimental/grokwiki/src/grokwiki/wiki.py
D Sandbox/ulif/grok-adminui-experimental/setup.cfg
U Sandbox/ulif/grok-adminui-experimental/setup.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/__init__.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/_grok.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/README.txt
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/__init__.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.txt
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/objectinfo.txt
D Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/GROK_Logo.jpg
D Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok-relax.jpg
D Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok-relax5.png
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok.css
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/tests/test_grokadmin.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokclassview.pt
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokgrokapplicationview.pt
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokinterfaceview.pt
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokmoduleview.pt
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokpackageview.pt
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgroktextfileview.pt
D Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/loginform.pt
D Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/logout.pt
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/macros.pt
U Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/server.pt
U Sandbox/ulif/grok-adminui-experimental/src/grok/components.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/directive.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftesting.zcml
D Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/README.txt
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/apps.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/brokenobjs.py
D Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/loginlogout.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/objectbrowser.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/catalog.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_app_interface.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_attribute.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_class.py
D Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_module.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple_conflict.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_name.py
D Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_no_app.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_nonexistent.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_set.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_site.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/setuporder.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/actions.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_applydata.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_catalog.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_classfields.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_schema.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/form.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/templateform.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/update.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/grant.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/handle_exception.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/json.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/require.py
A Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/roles.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/xmlrpc.py
D Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/static/
A Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/staticdir/
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/test_grok_functional.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverse.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverser.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/items_before_views.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/modeltraverse.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser_sets_parent.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/application.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/redirect.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url_function.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local_override.py
D Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_class.py
D Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_directive.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/public.py
D Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/publicnoncontainer.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/subclass.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/argument.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/index.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/macros.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/view.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc/xmlrpc.py
D Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc_helper.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/interfaces.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/meta.py
A Sandbox/ulif/grok-adminui-experimental/src/grok/tests/catalog/
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json2.py
A Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_name.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc2.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc3.py
A Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_role_name.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_json.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_xmlrpc.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/view_decorator.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/test_grok.py
A Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_class.py
A Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_directive.py
A Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/publicnoncontainer.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/view/dirtemplatesonly.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/tests/zcml/directiveerror.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/util.py
U Sandbox/ulif/grok-adminui-experimental/src/grok/zcml.py
-=-
Copied: Sandbox/ulif/grok-adminui-experimental/CHANGES.txt (from rev 79383, grok/trunk/CHANGES.txt)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/CHANGES.txt (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/CHANGES.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,64 @@
+Grok changes
+************
+
+0.11 (unreleased)
+=================
+
+Feature changes
+---------------
+
+* Removed grok.define_permission in favor of the grok.Permission
+ component base class
+
+* Add the grok.Role component base class.
+
+Restructuring
+-------------
+
+* The <grok:grok /> ZCML directive now emits a configuration action
+ instead of grokking right away at XML parsing time. That way
+ grokkers can depend on components that are set up using regular ZCML
+ (e.g. checking for a permission that's defined in ZCML).
+
+* Changed the way grok's functional tests are set up. Instead of each
+ test case doing its own test setup, it is now done once by the
+ ftesting layer. This avoids ordering problems when some ftests
+ would influence the environment of other ftests that were run later
+ in time.
+
+0.10 (2007-08-21)
+=================
+
+Feature changes
+---------------
+
+* Integrated admin user interface.
+
+* Configuration using Martian (http://pypi.python.org/pypi/martian).
+
+* Flash message infrastructure included.
+
+* Adjust dependencies for Grok so that grokproject should work on
+ Windows.
+
+Bug fixes
+---------
+
+* A fix in Martian where multiple grok.Model or grok.Container classes
+ could result in something being found as a context twice.
+
+0.9 series (early 2007 until july 2007)
+=======================================
+
+Feature changes
+---------------
+
+Grok was released in "continuous release" mode from SVN during this period.
+
+0.1 series (september 2006 until early 2007)
+============================================
+
+Feature changes
+---------------
+
+Grok was created in september 2006.
Modified: Sandbox/ulif/grok-adminui-experimental/CREDITS.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/CREDITS.txt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/CREDITS.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -11,6 +11,8 @@
* Jan-Wijbrand Kolman (Grok Zwei sprint, meta grokker improvements)
+* Uli Fouquet (admin interface, summer of code student)
+
* Darryl Cousins (website, admin interface)
* Kevin Teague (website)
@@ -25,6 +27,8 @@
* Mikhail Kashkin
+* Wim Boucqaert (admin interface layout improvements)
+
* ME GROK (team mascot)
Thank you
Modified: Sandbox/ulif/grok-adminui-experimental/README.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/README.txt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/README.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,3 +1,6 @@
+Grok
+****
+
What is grok?
=============
@@ -10,6 +13,9 @@
configuration language like ZCML nor a lot of repetition are needed to
create a web application with grok.
+You can find out much more about Grok at our http://grok.zope.org
+website.
+
Who is grok?
============
Modified: Sandbox/ulif/grok-adminui-experimental/buildout.cfg
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/buildout.cfg 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/buildout.cfg 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,7 +2,12 @@
develop = . doc grokwiki
parts = docs grokwiki zopectl data test
find-links = http://download.zope.org/distribution/
+index = http://download.zope.org/ppix
+versions = release-0.10
+[release-0.10]
+ZODB3 = 3.8.0b2
+
[docs]
recipe = zc.recipe.egg
eggs = grokdocs
@@ -52,5 +57,5 @@
[test]
recipe = zc.recipe.testrunner
-eggs = grok
+eggs = grok
defaults = ['--tests-pattern', '^f?tests$', '-v']
Copied: Sandbox/ulif/grok-adminui-experimental/doc/examples/MOVED.txt (from rev 79383, grok/trunk/doc/examples/MOVED.txt)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/examples/MOVED.txt (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/doc/examples/MOVED.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,3 @@
+The examples were moved to the grokapps dir at the root of this repository:
+
+http://svn.zope.org/grokapps/
Modified: Sandbox/ulif/grok-adminui-experimental/doc/grok2html.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/grok2html.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/grok2html.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -178,6 +178,12 @@
rest_files.append(RestFile('testing',
os.path.join(source_dir, 'minitutorials', 'testing.txt'),
os.path.join(www_dir, 'minitutorials', 'testing.html')))
+ rest_files.append(RestFile('xmlrpc',
+ os.path.join(source_dir, 'minitutorials', 'xmlrpc.txt'),
+ os.path.join(www_dir, 'minitutorials', 'xmlrpc.html')))
+ rest_files.append(RestFile('permissions',
+ os.path.join(source_dir, 'minitutorials', 'permissions.txt'),
+ os.path.join(www_dir, 'minitutorials', 'permissions.html')))
rest_files.append(RestFile('zc.buildout',
'http://svn.zope.org/*checkout*/zc.buildout/trunk/doc/tutorial.txt',
os.path.join(www_dir, 'minitutorials', 'buildout.html')))
Modified: Sandbox/ulif/grok-adminui-experimental/doc/index.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/index.txt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/index.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -53,7 +53,7 @@
* `Introduction to Grok`_ is a talk given by Philipp von Weitershausen to a group of Zope developers.
.. _Simple ToDo: http://www.archive.org/details/grok_todo_part1
-.. _Introduction to Grok: http://comlounge.tv/blog/archive/2007/02/11/cltv23-snow-sprint-2007-grok-presentation
+.. _Introduction to Grok: http://comlounge.tv/blog/zope/cltv23-snow-sprint-2007-grok-presentation
What does Grok code look like?
@@ -108,8 +108,9 @@
ME GROK MINI-TUTORIALS!
-----------------------
-* `Newbie Search HowTo <minitutorials/searching.html>`_
-* `Newbie Macros HowTo <minitutorials/macros.html>`_
+* `Newbie Search HowTo <minitutorials/searching.html>`_ Sebastian Ware
+* `Newbie Macros HowTo <minitutorials/macros.html>`_ Uli Fouquet
+* `Newbie XMLRPC HowTo <minitutorials/xmlrpc.html>`_ Kushal Das
ME GROK SPRINTS AND BLOGS!
--------------------------
Modified: Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/index.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/index.txt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/index.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -26,6 +26,14 @@
Author: Uli Fouquet
+* `XMLRPC With Grok </minitutorials/xmlrpc.html>`_:
+
+ XMLRPC (http://xmlrpc.com) is a spec and a set of implementations
+ that allow software running on disparate operating systems, running in
+ different environments to make procedure calls over the Internet.
+
+ Author: Kushal Das
+
Buildout
========
Modified: Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/macros.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/macros.txt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/macros.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -71,7 +71,7 @@
metal:define-slot=<slot-name>
-Let's define a very plain page macro:
+Let's define a very plain page macro in ``app_templates/mymacros.pt``:
.. code-block:: html
@@ -140,8 +140,8 @@
<html metal:use-macro="context/@@mymacros/mypage">
<body>
- <!-- slot 'mybody' was defined in the macro above -->
- <div metal:fill-slot="mybody">
+ <!-- slot 'mycontent' was defined in the macro above -->
+ <div metal:fill-slot="mycontent">
My content from index.pt
</div>
</body>
Copied: Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/permissions.txt (from rev 79383, grok/trunk/doc/minitutorials/permissions.txt)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/permissions.txt (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/permissions.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,245 @@
+===========================
+Newbie Permissions Tutorial
+===========================
+
+:Author: Luis De la Parra; Uli Fouquet; Jan-Wijbrand Kolman
+
+Intended Audience:
+
+ * Python Developers
+
+ * Zope 2 Developers
+
+ * Zope 3 Developers
+
+Introduction
+-------------
+
+Zope3 and Grok come with authorization capabilities out of the box. While a
+vanilla Zope3 application protects all content by default and performs
+authorization checks on the content objects themselves, Grok allows access to
+everything unless you explicitly restrict it. The authorization checks here
+are done based on the ``Views`` used to access (display/manipulate) the
+content.
+
+Setup
+-----
+
+.. code-block:: python
+
+ #contact.py
+ from zope import component, interface, schema
+ import grok
+
+ class IContactInfo(interface.Interface):
+ """ Interface/Schema for Contact Information """
+ first_name = schema.Text(title=u'First Name')
+ last_name = schema.Text(title=u'Last Name')
+ email = schema.Text(title=u'E-mail')
+
+
+ class ContactInfo(grok.Model):
+ interface.implements(IContactInfo)
+
+ first_name = ''
+ last_name = ''
+ email = ''
+
+ class ViewContact(grok.View)
+ """Display Contact Info, without e-mail.
+
+ Anyone can use this view, even unauthenticated users
+ over the internet
+ """
+ def render(self):
+ contact = self.context
+ return 'Contact: ' + contact.first_name + contact.last_name
+
+Defining Permissions and restricting access
+-------------------------------------------
+
+As all Views in Grok default to public access, anyone can use the
+``ViewContact``-view defined above. If you want to restrict access to a view,
+you have to explicitly protect it with a permission:
+
+.. code-block:: python
+
+ # Define Permissions. The grok.name can be any string, but it is strongly
+ # recommended to make them unique by prefixing them with the application
+ # name.
+ class ViewContacts(grok.Permission):
+ grok.name('mysite.ViewContacts')
+ grok.title('View Contacts') # optional
+
+ class AddContacts(grok.Permission):
+ grok.name('mysite.AddContacts')
+
+ class EditContacts(grok.Permission):
+ grok.name('mysite.EditContacts')
+
+ class ViewContactComplete(grok.View)
+ """Display Contact Info, including email.
+
+ Only users which have the permission 'mysite.ViewContacts'
+ can use this view.
+ """"
+ grok.require('mysite.ViewContacts') #this is the security declaration
+
+ def render(self):
+ contact = self.context
+ return 'Contact: %s%s%s' % (contact.first_name,
+ contact.last_name,
+ contact.email)
+
+*Note* The ``grok.Permission`` component base class was introduced *after* the
+release 0.10. In earlier versions of Grok a permission was defined using a
+module level directive, like so:
+
+.. code-block:: python
+
+ grok.define_permission('mysite.ViewContacts')
+
+If you are using ``grokproject`` this change currently does not affect your
+installation. In this case use ``grok.define_permission`` as described above.
+
+Granting Permissions
+--------------------
+
+You can grant permissions to principals with a ``PermissionManager``. For
+example, if all registered users should have permission to view contact
+details and to create new contacts, you could grant them the permissions when
+the user account is created:
+
+.. code-block:: python
+
+ from zope.app.security.interfaces import IAuthentication
+ from zope.app.securitypolicy.interfaces import IPrincipalPermissionManager
+
+ def addUser(username, password, realname):
+ """Create a new user.
+
+ create a new user and give it the authorizations,
+ ``ViewContacts`` and ``EditContacts``. This example assumes
+ you are using a Pluggable Authentication Utility (PAU) /
+ PrincipalFolder, which you have to create and register when
+ creating your Application.
+ """
+
+ pau = component.getUtility(IAuthentication)
+ principals = pau['principals']
+ principals[username] = InternalPrincipal(username, password, realname)
+
+ # grant the user permission to view and create contacts
+ # everywhere in the site
+ permission_man = IPrincipalPermissionManager(grok.getSite())
+
+ # NOTE that you need a principal ID. If you are
+ # authenticating users with a PAU this is normally the user
+ # name prepended with the principals-folder prefix (and the
+ # PAU-prefix as well, if set)
+ permission_man.grantPermissionToPrincipal (
+ 'mysite.ViewContacts',
+ principals.prefix + username)
+ permission_man.grantPermissionToPrincipal(
+ 'mysite.AddContacts',
+ principals.prefix + username)
+
+Permissions are granted for the context for which the PermissionManager is
+created, and -- if not explicitly overridden -- all its children. The above
+example grants ``View`` and ``Add`` permissions for the complete site, unless
+a folder down in the hierarchy revokes the permission.
+
+If you want users to be able to edit only their own ``ContactInfos``, you have
+to give them the ``Edit`` permission only within the context of the
+``ContactInfo``-object itself
+
+.. code-block:: python
+
+ class AddContact(grok.AddForm):
+ """Add a contact.
+ """
+
+ # Only users with permission 'mysite.AddContacts' can use
+ # this.
+ #
+ # NOTE that if you don't protect this Form, anyone -- even
+ # anonymous/unauthenticated users -- could add ``Contacts``
+ # to the site.
+ grok.require('mysite.AddContacts')
+
+ #automagically generate form fields
+ form_fields = grok.AutoFields(IContactInfo)
+
+ @grok.action('Create')
+ def create(self, **kw):
+ # Create and add the ``ContactInfo`` to our context
+ # (normally a folder/container)
+ contact = ContactInfo()
+ self.applyData(contact, **kw)
+ self.context[contact.first_name] = contact
+
+ # Grant the current user the Edit permission, but only in
+ # the context of the newly created object.
+ permission_man = IPrincipalPermissionManager(contact)
+ permission_man.grantPermissionToPrincipal(
+ 'mysite.EditContacts',
+ self.request.principal.id)
+ self.redirect(self.url(contact))
+
+ class EditContact(grok.EditForm):
+ """Edit a contact.
+ """
+
+ #only users with permission 'mysite.EditContacts' can use this
+ grok.require('mysite.EditContacts')
+
+ form_fields = grok.AutoFields(IContactInfo)
+
+ @grok.action('Save Changes')
+ def edit(self, **data):
+ self.applyData(self.context, **data)
+ self.redirect(self.url(self.context))
+
+Checking Permissions
+--------------------
+
+[FIXME How to check permissions in a page template and from python
+code? User Interfaces should not contain any links/actions which
+users cannot access / for which users don't have authorizations]
+
+Defining Roles
+--------------
+
+Permissions can be grouped together in ``Roles``, which makes granting all the
+permissions for a particular type of user much easier. Defining roles is
+similar to defining permissions.
+
+As an example, let's group all permissions in two roles: one for normal site
+members, and one for administrators:
+
+.. code-block:: python
+
+ class MemberRole(grok.Role):
+ grok.name('mysite.Member')
+ grok.title('Contacts Member') # optional
+ grok.permissions(
+ 'mysite.ViewContacts',
+ 'mysite.AddContacts')
+
+ class AdministratorRole(grok.Role):
+ grok.name('mysite.Editor')
+ grok.title('Contacts Administrator') # optional
+ grok.permissions(
+ 'mysite.ViewContacts',
+ 'mysite.AddContacts',
+ 'mysite.EditContacts')
+
+Now, if the context here is the site/application, users with the administrator
+role can edit all ContactInfos, regardless of who the creator is.
+
+.. code-block:: python
+
+ from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
+
+ role_man = IPrincipalRoleManager(context)
+ role_man.assignRoleToPrincipal('mysite.Administrator', principalID)
Copied: Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/xmlrpc.txt (from rev 79383, grok/trunk/doc/minitutorials/xmlrpc.txt)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/xmlrpc.txt (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/xmlrpc.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,149 @@
+====================
+XML-RPC using Grok
+====================
+
+:Author: Kushal Das
+
+What is XML-RPC ?
+------------------
+
+From the site (http://xmlrpc.com): it's a spec and a set of implementations
+that allow software running on disparate operating systems, running in
+different environments to make procedure calls over the Internet.
+
+So, What is Grok?
+------------------
+
+From the site: Grok is a web application framework for Python developers. It
+is aimed at both beginners and very experienced web developers. Grok has an
+emphasis on agile development. Grok is easy and powerful.
+
+Grok accomplishes this by being based on Zope 3, an advanced object-oriented
+web framework. While Grok is based on Zope 3, and benefits a lot from it, you
+do not need to know Zope at all in order to get productive with Grok.
+
+So, it is cool, isn't it? :)
+
+Installation
+--------------
+
+To install the latest grok, give the following command::
+
+ $ sudo easy_install grokproject
+
+This will download and install grok for you. After this we are ready to rock...
+
+Creating our first project
+-----------------------------
+
+Let's create the project named "Foo". For that give the command::
+
+ $ grokproject Foo
+
+This will create a subdirectory in the current directory named "Foo", then it
+will download Zope3 and install Grok with that which you can start working
+with. It will ask you a few questions like::
+
+ Enter module (Name of a demo Python module placed into the package) ['app.py']:
+
+Press Enter for the default value. Then::
+
+ Enter user (Name of an initial administrator user): grok
+ Enter passwd (Password for the initial administrator user): grok
+
+We typed "grok" for both the user and password.
+
+Starting up Zope
+--------------------
+
+Switch to the Foo directory, and give the command::
+
+ $ bin/zopectl fg
+
+This will startup Zope for you, you can access it through a web browser
+pointing to http://localhost:8080/ . Then add an application named *foo*.
+
+You can access it by http://localhost:8080/foo, it will show::
+
+ Congratulations!
+
+ Your Grok application is up and running. Edit foo/app_templates/index.pt to
+ change this page.
+
+Now we are going to write our xmlrpc stuffs inside it.
+
+XML-RPC class
+-----------------
+
+Now you can open the file src/foo/app.py in a text editor. The default is
+shown below::
+
+ import grok
+
+ class Foo(grok.Application, grok.Container):
+ pass
+
+ class Index(grok.View):
+ pass # see app_templates/index.pt
+
+We will another class which will be available through this application class,
+the new class should inherit ``grok.XMLRPC for this``, and we will write a
+``say()`` method. It will return "Hello World!". So, the changed file::
+
+ import grok
+
+ class Foo(grok.Application, grok.Container):
+ pass
+
+ class Index(grok.View):
+ pass # see app_templates/index.pt
+
+ class FooXMLRPC(grok.XMLRPC):
+ """The methods in this class will be available as XMLRPC methods
+ on 'Foo' applications."""
+
+ def say(self):
+ return 'Hello world!'
+
+The name of the class doesn't matter, so you can give it any name.
+Restart the Zope in the console, and you can connect to it through any xmlrpc
+client. Below is an example (fooclient.py)::
+
+ #!/usr/bin/env python
+ import xmlrpclib
+
+ s = xmlrpclib.Server('http://localhost:8080/foo')
+ print s.say()
+
+Run this and see !!
+
+Class in a different file
+---------------------------
+
+What if you want to write the class in a different file in the src/foo
+directory and still want to have the methods to be available under Foo
+application. For that you need to tell grok explicitly that the new class to
+associate it to the Foo model by using the grok.context class annotation.
+
+What is a class annotation?
+-----------------------------
+
+A class annotation is a declarative way to tell grok something about a Python
+class. Let's see the example, we write a Boom.py with a Boom class::
+
+ import grok
+ from app import Foo
+
+ class Boom(grok.XMLRPC):
+ grok.context(Foo)
+
+ def dance(self):
+ return "Boom is dancing!!"
+
+Look at the line where it says ``grok.context(Foo)`` this is doing all the
+magic. In the fooclient.py you just need to call ``s.dance()`` instead of
+``s.say()``.
+
+So, now write your dream system...
+
+
Modified: Sandbox/ulif/grok-adminui-experimental/doc/reference/directives.tex
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/reference/directives.tex 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/reference/directives.tex 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,38 +1,194 @@
\chapter{Directives}
The \module{grok} module defines a set of directives that allow you to
-configure and register your components. Most directives assume a default, based
-on the environment of a module. (For example, a view will be automatically
-associated with a model if the association can be made unambigously.)
+configure and register your components. Most directives assume a
+default, based on the environment of a module. (For example, a view
+will be automatically associated with a model if the association can
+be made unambigously.)
-If no default can be assumed for a value, grok will explicitly tell you what is
-missing and how you can provide a default or explicit assignment for the value
-in question.
+If no default can be assumed for a value, grok will explicitly tell
+you what is missing and how you can provide a default or explicit
+assignment for the value in question.
- \section{\function{grok.AutoFields}}
- \begin{funcdesc}{grok.AutoFields}{*arg}
- foobar
+ \section{\function{grok.AutoFields} -- deduce schema fields automatically}
+
+ \begin{funcdesc}{grok.AutoFields}{class_or_interface}
+ A class level directive, which can be used inside
+ \class{Form} classes to automatically deduce the form fields
+ from the schema of the context \var{class_or_interface}.
+
+ Different to most other directives,
+ \function{grok.AutoFields} is used more like a function and
+ less like a pure declaration.
+
+ The following example makes use of the
+ \function{grok.AutoFields} directive, in that one field is
+ omitted from the form before rendering:
+
+ \strong{Example:}
+
+ \begin{verbatim}
+import grok
+from zope import interface, schema
+
+class IMammoth(interface.Interface):
+ name = schema.TextLine(title=u"Name")
+ size = schema.TextLine(title=u"Size", default=u"Quite normal")
+
+class Mammoth(grok.Model):
+ interface.implements(IMammoth)
+
+class Edit(grok.EditForm):
+ grok.context(Mammoth)
+
+ form_fields = grok.AutoFields(Mammoth).omit('size')
+ \end{verbatim}
+
+ In this example the \code{size} attribute will not show up
+ in the resulting edit view.
+
+ \begin{seealso}
+ \class{grok.EditForm}, \class{grok.Fields}
+ \end{seealso}
+
\end{funcdesc}
- \section{\function{grok.adapts}}
+ \section{\function{grok.adapts} -- declare that a class adapts
+ certain objects}
- \begin{funcdesc}{grok.adapts}{*interfaces}
- foobar
+ \begin{funcdesc}{grok.adapts}{*classes_or_interfaces}
+ A class-level directive to declare that a class adapts
+ objects of the classes or interfaces given in
+ \var{*classes_or_interfaces}.
+
+ This directive accepts several arguments.
+
+ It works much like the \module{zope.component}s
+ \function{adapts()}, but you do not have to make a ZCML
+ entry to register the adapter.
+
+ \strong{Example:}
+
+ \begin{verbatim}
+import grok
+from zope import interface, schema
+from zope.size.interfaces import ISized
+
+class IMammoth(interface.Interface):
+ name = schema.TextLine(title=u"Name")
+ size = schema.TextLine(title=u"Size", default=u"Quite normal")
+
+class Mammoth(grok.Model):
+ interface.implements(IMammoth)
+
+class MammothSize(object):
+ grok.implements(ISized)
+ grok.adapts(IMammoth)
+
+ def __init__(self, context):
+ self.context = context
+
+ def sizeForSorting(self):
+ return ('byte', 1000)
+
+ def sizeForDisplay(self):
+ return ('1000 bytes')
+ \end{verbatim}
+
+ Having \class{MammothSize} available, you can register it as
+ an adapter, without a single line of ZCML:
+
+ \begin{verbatim}
+>>> manfred = Mammoth()
+>>> from zope.component import provideAdapter
+>>> provideAdapter(MammothSize)
+>>> from zope.size.interfaces import ISized
+>>> size = ISized(manfred)
+>>> size.sizeForDisplay()
+'1000 bytes'
+ \end{verbatim}
+
+ \begin{seealso}
+ \class{grok.implements}
+ \end{seealso}
+
\end{funcdesc}
- \section{\function{grok.baseclass}}
+ \section{\function{grok.baseclass} -- declare a class as base}
- \begin{funcdesc}{grok.baseclass}{*interfaces}
- foobar
+ \begin{funcdesc}{grok.baseclass}{}
+ A class-level directive without argument to mark something
+ as a base class. Base classes are are not grokked.
+
+ Another way to indicate that something is a base class, is
+ by postfixing the classname with \code{'Base'}.
+
+ The baseclass mark is not inherited by subclasses, so those
+ subclasses will be grokked (except they are explicitly
+ declared as baseclasses as well).
+
+ \strong{Example:}
+
+ \begin{verbatim}
+import grok
+
+class ModelBase(grok.Model):
+ pass
+
+class ViewBase(grok.View):
+ def render(self):
+ return "hello world"
+
+class AnotherView(grok.View):
+ grok.baseclass()
+
+ def render(self):
+ return "hello world"
+
+class WorkingView(grok.View):
+ pass
+ \end{verbatim}
+
+ Using this example, only the \class{WorkingView} will serve
+ as a view, while calling the \class{ViewBase} or
+ \class{AnotherView} will lead to a
+ \exception{ComponentLookupError}.
+
+
\end{funcdesc}
- \section{\function{grok.define_permission}}
+ \section{\function{grok.define_permission} -- define a permission}
- \begin{funcdesc}{grok.define_permission}{*arg}
- foobar
+ \begin{funcdesc}{grok.define_permission}{name}
+
+ A module-level directive to define a permission with name
+ \var{name}. Usually permission names are prefixed by a
+ component- or application name and a dot to keep them
+ unique.
+
+ Because in Grok by default everything is accessible by
+ everybody, it is important to define permissions, which
+ restrict access to certain principals or roles.
+
+ \strong{Example:}
+
+ \begin{verbatim}
+import grok
+grok.define_permission('cave.enter')
+ \end{verbatim}
+
+ \begin{seealso}
+ \function{grok.require()}, \class{grok.Permission},
+ \class{grok.Role}
+ \end{seealso}
+
+ \versionchanged[replaced by \class{grok.Permission}]{0.11}
+
\end{funcdesc}
+
+
\section{\function{grok.Fields}}
\begin{funcdesc}{grok.Fields}{*arg}
Modified: Sandbox/ulif/grok-adminui-experimental/doc/reference/reference.tex
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/reference/reference.tex 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/reference/reference.tex 2007-08-30 23:53:54 UTC (rev 79388)
@@ -15,7 +15,7 @@
% the rest is at your discretion.
\authoraddress{
The grok team\\
- Email: <grok-dev at zope.org>
+ Email: $<$grok-dev at zope.org$>$
}
\date{\today} % update before release!
Modified: Sandbox/ulif/grok-adminui-experimental/grokwiki/src/grokwiki/wiki.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/grokwiki/src/grokwiki/wiki.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/grokwiki/src/grokwiki/wiki.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -18,7 +18,7 @@
import grokwiki.page
class Wiki(grok.Application, grok.Container):
- """This is our wiki application wich contains all wiki pages."""
+ """This is Grok's sample wiki application."""
class Index(grok.View):
def render(self):
Deleted: Sandbox/ulif/grok-adminui-experimental/setup.cfg
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/setup.cfg 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/setup.cfg 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,3 +0,0 @@
-[egg_info]
-tag_build = dev
-tag_svn_revision = true
Modified: Sandbox/ulif/grok-adminui-experimental/setup.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/setup.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/setup.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,16 +1,37 @@
from setuptools import setup, find_packages
+import os
+# some of the dependencies containing C code have been hardcoded to
+# make sure we only depend on versions for which there is a windows
+# binary. In some cases this means we rely on an earlier version than the
+# latest/greatest version as no Windows binary has been released for it yet.
+# in some cases we also need to do this for non-binary dependencies, as
+# more recent versions rely on versions for which no binary eggs exist.
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+long_description = (
+ read('README.txt')
+ + '\n' +
+ read('CHANGES.txt')
+ + '\n' +
+ 'Download\n'
+ '********\n'
+ )
+
+open('doc.txt', 'w').write(long_description)
+
setup(
name='grok',
- version='0.9',
+ version='0.10',
author='Grok Team',
author_email='grok-dev at zope.org',
- url='https://launchpad.net/grok',
- download_url='svn://svn.zope.org/repos/main/grok/trunk#egg=grok-dev',
+ url='http://grok.zope.org',
+ download_url='http://cheeseshop.python.org/pypi/grok/',
description='Grok: Now even cavemen can use Zope 3!',
- long_description=open('README.txt').read(),
+ long_description=long_description,
license='ZPL',
-
packages=find_packages('src'),
package_dir = {'': 'src'},
include_package_data = True,
@@ -19,7 +40,7 @@
'martian',
'simplejson',
'pytz',
- 'ZODB3',
+ 'ZODB3 == 3.8.0b2',
'zope.annotation',
'zope.app.apidoc',
'zope.app.applicationcontrol',
@@ -27,9 +48,11 @@
'zope.app.authentication',
'zope.app.catalog',
'zope.app.component',
- 'zope.app.container',
+ 'zope.app.container == 3.5.0.a1',
'zope.app.folder',
'zope.app.intid',
+ # not binary, but needed for ZODB 3.8.0b2
+ 'zope.app.keyreference == 3.4.0a1',
'zope.app.pagetemplate',
'zope.app.publication',
'zope.app.publisher',
@@ -45,17 +68,19 @@
'zope.deprecation',
'zope.event',
'zope.formlib',
- 'zope.interface',
+ 'zope.hookable',
+ 'zope.i18nmessageid',
+ 'zope.interface == 3.4.0',
'zope.lifecycleevent',
'zope.pagetemplate',
- 'zope.proxy',
+ 'zope.proxy == 3.4.0',
'zope.publisher',
'zope.schema',
- 'zope.security',
+ 'zope.security == 3.4.0b5',
'zope.testing',
'zope.traversing',
'zope.testbrowser',
'zc.catalog',
- 'z3c.flashmessage >=1.0dev-r77761',
+ 'z3c.flashmessage >=1.0b1',
],
)
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/__init__.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/__init__.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/__init__.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -35,9 +35,10 @@
from grok.components import Site, GlobalUtility, LocalUtility, Annotation
from grok.components import Application, Form, AddForm, EditForm, DisplayForm
from grok.components import Indexes
-from grok.directive import (context, name, template, templatedir, provides,
- baseclass, global_utility, local_utility,
- define_permission, require, site)
+from grok.components import Permission, Role
+from grok.directive import (context, name, title, template, templatedir,
+ provides, baseclass, global_utility, local_utility,
+ permissions, require, site)
from grok._grok import do_grok as grok # Avoid name clash within _grok
from grok._grok import grok_component
from grok._grok import SubscribeDecorator as subscribe
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/_grok.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/_grok.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/_grok.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -82,7 +82,6 @@
def grok_component(name, component,
context=None, module_info=None, templates=None):
- #import pdb; pdb.set_trace()
return the_multi_grokker.grok(name, component,
context=context,
module_info=module_info,
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/README.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/README.txt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/README.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,67 +3,110 @@
=====================
The internal name of the admin UI is:
-Grok Application Interface Application or, for short gaia.
+Grok Application Interface Application or, for short GAIA.
-Overview
---------
+GAIA is itself a Grok application and a subproject to the core Grok
+development. Its main goal is making developing of Zope 3 and Grok
+applications a faster and smarter job with more fun for everybody.
-* List of all instanciated applications (grouped by application?)
-* "Add new application" form: drop down for selecting the application
- and a field for the id.
+Login - what is my username/password?
+-------------------------------------
-* "Delete application" form: checkboxes displayed with listed installed
- applications. Selected items may be deleted.
+Before you can use the admin UI, you first must log in.
+The username and password of the manager principal (kind of super
+user) can be found in the file ``buildout.cfg`` in the root of your
+subversion checkout.
-TODO:
------
+In case you do not know, what 'subversion checkout' means, look for a
+file ``site.zcml`` in your installation.
-Layout/Design/Templates:
-........................
+Users of ``grokproject``, might find this file in
+``<installdir>/parts/app/site.zcml``.
-* Get rid of garbage in docgrok-views
-* Get a new layout
+Using the admin-UI
+------------------
-* Rename topics:
+After login you can visit some of the main management topics, as
+described below:
- - z3index -> server
+On top of the admin-UI you can always find three links to the main
+management activities currently possible with GAIA:
- - appsindex -> applications
-* AJAXification using some framework (MojiKit or KSS most probably)
+Applications
+------------
+* List of all instanciated applications
-Functional:
-...........
+* You can add new instances of Grok applications
-* Debugging
+* For each installed application you can directly call:
- - Debugger
+ - the object browser (telling you more about this concrete object)
- - Error Logs, usable for developers
+ - the class browser (telling you more about the class of your app)
-* Profiling
+* For each available application type you can directly call:
-* Object browser / Introspection tool
+ - the class browser (telling you more about the class of your app)
- - Give information concerning installed apps, their containers
- and contained objects.
+* You can delete your installed applications.
-* Better application handling
- - Configure apps.
+Server
+------
-* Display hints for where to find username / password for new users
+* Start/Restart the server. Caution! This does not work, if the server
+ was started in 'foreground mode' (with 'zopectl fg').
-* Login/Logout(?)
+* Get basic information about the running Zope system.
-* Display username(?)
+* Enter a message to be displayed on top. You can, for example, leave
+ a message here for your co-admins. To delete the message, just enter
+ the empty string in the appropriate input box.
-* Error Messages:
- - Give message, when input errors (no appname given etc.) occur
+Documentation
+-------------
- - Customizable error pages(?)
+* From here you get starting points to the more elaborated
+ documentation features of Grok, namely:
+
+ - The object browser:
+
+ helps browsing the ZODB and other objects.
+
+ - The class browser:
+
+ gives documentation to classes, packages and other things, which
+ are not instances.
+
+
+Bugs, Caveats and Ways to Get Help
+----------------------------------
+
+The Grok admin UI was developed basically during a Google Summer of
+Code project.
+
+It is still full of bugs.
+
+For bugreports use:
+
+ https://launchpad.net/grok
+
+For discussions subscribe to the ``grok-dev`` mailing list, hosted on:
+
+ http://lists.zope.org.
+
+The projects' home is the grok subversion repository at:
+
+ http://svn.zope.org/grok/
+
+Grok's cave can be found at
+
+ http://grok.zope.org/
+
+Enjoy!
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/__init__.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/__init__.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/__init__.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,131 +1,14 @@
-"""Initialize grok admin application.
-
-The grok admin application provides a session based login, which
-eventually must be enabled using Pluggable Authentication
-Utilities. This is done here.
-"""
-
-from zope.component import adapter, provideHandler
-from zope.app.appsetup.interfaces import IDatabaseOpenedWithRootEvent
-
-
-def getPrincipalCredentialsFromZCML():
- """Read all principals' attributes from site.zcml.
- """
- import xml.sax
- from zope.app.appsetup.appsetup import getConfigSource
-
- class SAXPrincipalFinder(xml.sax.ContentHandler):
- """Parse an XML file and get attributes of ``principal`` tags.
-
- The principal tags of site.xml contain the credentials of
- principals as attributes. The attributes usually are 'id',
- 'login', 'password', 'title' and other more. And usually only
- one pricipal is defined: the manager.
- """
- result = []
-
- def startElement(self, name, attrs):
- if name != 'principal':
- return
- self.result.append(dict(attrs.copy()))
-
- site_zcml_file = getConfigSource()
- principal_finder = SAXPrincipalFinder()
- xml.sax.parse(site_zcml_file, principal_finder)
- return principal_finder.result
-
-
-def setupSessionAuthentication(root_folder=None,
- principal_credentials=[{u'id': u'zope.manager',
- u'login': u'grok',
- u'password': u'grok',
- u'title': u'Manager'
- }],
- auth_foldername=u'authentication',
- userfolder_name=u'Users',
- userfolder_prefix=u'grokadmin'
- ):
- """Add session authentication PAU to root_folder.
-
- Add a PluggableAuthentication in site manager of
- root_folder. ``auth_foldername`` gives the name of the PAU to
- install, userfolder_prefix the prefix of the authenticator plugin
- (a simple ``PrincipalFolder``), which will be created in the PAU
- and gets name ``userfolder_name``. ``principal_credentials`` is a
- list of dicts with, well, principal_credentials. The keys ``id``,
- ``login``, ``password`` and ``title`` are required for each
- element of this list.
- """
- from zope.component import getUtilitiesFor
- from zope.security.proxy import removeSecurityProxy
- from zope.app.security.interfaces import IAuthentication
- from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
- from zope.app.securitypolicy.interfaces import IRole
- from zope.app.authentication import PluggableAuthentication
- from zope.app.authentication.interfaces import IAuthenticatorPlugin
- from zope.app.authentication.principalfolder import PrincipalFolder
- from zope.app.authentication.principalfolder import InternalPrincipal
-
- sm = root_folder.getSiteManager()
- if auth_foldername in sm.keys():
- # There is already a folder of this name.
- return
-
- pau = PluggableAuthentication()
- users = PrincipalFolder(userfolder_prefix)
-
- # Add users into principals folder to enable login...
- for user in principal_credentials:
- # XXX make sure, the keys exist...
- user['id'] = user['id'].rsplit('.',1)[-1]
- user_title = user['title']
- principal = InternalPrincipal(user['login'],
- user['password'],
- user['title'])
- users[user['id']] = principal
-
- # Configure the PAU...
- pau.authenticatorPlugins = (userfolder_name,)
- pau.credentialsPlugins = ("No Challenge if Authenticated",
- "Session Credentials")
-
- # Add the pau and its plugin to the root_folder...
- sm[auth_foldername] = pau
- sm[auth_foldername][userfolder_name] = users
- pau.authenticatorPlugins = (users.__name__,)
-
- # Register the PAU with the site...
- sm.registerUtility(pau, IAuthentication)
- sm.registerUtility(users, IAuthenticatorPlugin, name=userfolder_name)
-
- # Add manager roles to new users...
- # XXX the real roles could be obtained from site.zcml.
- role_ids = [name for name, util in getUtilitiesFor(IRole, root_folder)]
- user_ids = [users.prefix + p['id'] for p in principal_credentials]
- role_manager = IPrincipalRoleManager(root_folder)
- role_manager = removeSecurityProxy(role_manager)
- for role in role_ids:
- for user_id in user_ids:
- role_manager.assignRoleToPrincipal(role,user_id)
-
-
-
-# If a new database is created, initialize a session based
-# authentication.
+##############################################################################
#
-# First create an eventhandler `adminSetup`, that is
-# called, whenever a database is opened...
- at adapter(IDatabaseOpenedWithRootEvent)
-def adminSetup(event):
- from zope.app.appsetup.bootstrap import getInformationFromEvent
-
- db, connection, root, root_folder = getInformationFromEvent(event)
- principal_credentials = getPrincipalCredentialsFromZCML()
- setupSessionAuthentication(root_folder = root_folder,
- principal_credentials = principal_credentials)
-
-
-# ...then install the event handler:
-provideHandler(adminSetup)
-
+# 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.
+#
+##############################################################################
+# a package
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -55,8 +55,11 @@
DOCGROK_ITEM_NAMESPACE = 'docgrok-obj'
grok.context(IRootFolder)
-grok.define_permission('grok.ManageApplications')
+class ManageApplications(grok.Permission):
+ grok.name('grok.ManageApplications')
+
+
def find_filepath(dotted_path):
"""Find the filepath for a dotted name.
@@ -661,4 +664,3 @@
content = file.read()
file.close()
return content.decode('utf-8')
-
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.txt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -77,7 +77,7 @@
`DocGrokPackage` :
>>> from grok.admin.docgrok import DocGrokPackage
- >>> doctor = DocGrokPackage('grok.admin')
+ >>> doctor = DocGrokPackage('grok')
>>> doctor
<grok.admin.docgrok.DocGrokPackage ...>
@@ -85,7 +85,7 @@
cares for:
>>> doctor.getPath()
- 'grok.admin'
+ 'grok'
Fine. Obviously DocGrokPackages know as much as DocGroks. That's
little. But a ``DocGrokPackage`` knows also about package-things:
@@ -201,7 +201,7 @@
class. But, where can we find the definition of it in file system? Ask
the doc:
- >>> doctor.getFilePath()
+ >>> pnorm(doctor.getFilePath())
'.../grok/__init__.py'
This is not exactly, what we wanted to know, is it? We got the package
@@ -214,7 +214,7 @@
To check it, let's see, what happens, if we give the real dotted path:
>>> doctor = DocGrokGrokView('grok.components.View')
- >>> doctor.getFilePath()
+ >>> pnorm(doctor.getFilePath())
'.../grok/components.py'
Ah, right. This is, what we wanted. Now we can use some of the derived
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/objectinfo.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/objectinfo.txt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/objectinfo.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -141,7 +141,7 @@
>>> filename = ObjectInfo(grok.admin.objectinfo.ObjectInfo).getfile()
>>> filename = filename[-1] == 'c' and filename or filename + 'c'
- >>> filename
+ >>> pnorm(filename)
'.../grok/admin/objectinfo.pyc'
@@ -154,7 +154,7 @@
>>> info.getsourcefile() is None
True
- >>> ObjectInfo(grok.admin.objectinfo.ObjectInfo).getsourcefile()
+ >>> pnorm(ObjectInfo(grok.admin.objectinfo.ObjectInfo).getsourcefile())
'.../grok/admin/objectinfo.py'
>>> info.getsourcelines() is None
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/GROK_Logo.jpg
===================================================================
(Binary files differ)
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok-relax.jpg
===================================================================
(Binary files differ)
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok-relax5.png
===================================================================
(Binary files differ)
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok.css
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok.css 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok.css 2007-08-30 23:53:54 UTC (rev 79388)
@@ -204,6 +204,10 @@
margin-left:1.5em;
}
+.menu-label1 {
+width: 40em;
+}
+
/* ---- docgrok related ---- */
.docgrok-entry {
margin-bottom:0.5em;
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/tests/test_grokadmin.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/tests/test_grokadmin.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/tests/test_grokadmin.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -11,8 +11,9 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Test setup for grok admin UI."""
+"""Setup for tests."""
+import os
import unittest
from pkg_resources import resource_listdir
from zope.testing import doctest, cleanup
@@ -47,13 +48,22 @@
suite.addTest(test)
return suite
+def pnorm(path):
+ """Normalization of paths to use forward slashes. This is needed
+ to make sure the tests work on windows.
+ """
+ return path.replace(os.sep, '/')
+
def test_suite():
suite = unittest.TestSuite()
+ globs = {'pnorm': pnorm}
+
for name in []:
suite.addTest(suiteFromPackage(name))
for name in ['docgrok.txt','objectinfo.txt', 'utilities.py']:
suite.addTest(doctest.DocFileSuite(name,
package='grok.admin',
+ globs=globs,
setUp=setUpZope,
tearDown=cleanUpZope,
optionflags=doctest.ELLIPSIS+
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -32,7 +32,6 @@
import zope.component
from zope.interface import Interface
-from zope.app import zapi
from zope.interface.interface import InterfaceClass
from zope.app.applicationcontrol.interfaces import IServerControl
from zope.app.applicationcontrol.applicationcontrol import applicationController
@@ -56,8 +55,10 @@
grok.context(IRootFolder)
-grok.define_permission('grok.ManageApplications')
+class ManageApplications(grok.Permission):
+ grok.name('grok.ManageApplications')
+
class Add(grok.View):
"""Add an application.
"""
@@ -66,14 +67,16 @@
def update(self, inspectapp=None, application=None):
if inspectapp is not None:
- self.redirect(self.url("docgrok") + "/%s/index"%(
- application.replace('.','/'),))
- return
+ self.redirect(self.url("docgrok") + "/%s/index"%(application.replace('.','/'),))
+ return
- def render(self, application, name):
+ def render(self, application, name, inspectapp=None):
if name is None or name == "":
self.redirect(self.url(self.context))
return
+ if name is None or name == "":
+ self.redirect(self.url(self.context))
+ return
app = zope.component.getUtility(grok.interfaces.IApplication,
name=application)
try:
@@ -307,44 +310,9 @@
self.redirect(self.url('applications'))
-class LoginForm(GAIAView):
- """A login screen for session based authentication.
-
- To activate loginForm, i.e. session based authentication, an
- appropriate PluggableAuthenticationUtility (PAU) must be set up in
- the applications root folder (which happens here to be the global
- root folder). The setup is done for the admin app in __init__.py.
- """
- # 'loginForm.html' is the page template name, that standard
- # session based authentication looks for. The form must provide an
- # input field 'login' for the username and another input field
- # 'password'.
- grok.name('loginForm.html')
-
- def update(self, login=None, password=None, camefrom=None):
- request = self.request
- if (not IUnauthenticatedPrincipal.providedBy(request.principal)):
- camefrom = request.get('camefrom', '.')
- self.redirect(camefrom)
- return
-
-class Logout(GAIAView):
- """Log out screen."""
-
- grok.name('logout')
-
- def update(self):
- auth = zope.component.getUtility(IAuthentication)
- logout = ILogout(auth)
- logout.logout(self.request)
- pass
-
-
-
class Applications(GAIAView):
"""View for application management.
- TODO: Handle broken objects, which are not in root.
"""
grok.name('applications')
@@ -415,7 +383,7 @@
@property
def server_control(self):
- return zapi.getUtility(IServerControl)
+ return zope.component.getUtility(IServerControl)
@property
def runtime_info(self):
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokclassview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokclassview.pt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokclassview.pt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -27,20 +27,12 @@
<span class="docgrok-description1">Python path:</span>
<span class="docgrok-pathvalue"
tal:content="context/path">path.in.python</span>
- <div class="docgrok-annotation2">
- Use <span class="docgrok-pycode1">from <span tal:replace="context/module_path">path</span>
- import <span tal:replace="context/name">path</span></span>
- to use the functionality of this module in your application or component.
- </div>
</div>
<div class="docgrok-entry">
<span class="docgrok-description1">Absolute file path: </span>
<span class="docgrok-pathvalue"
tal:content="context/getFilePath">/absolute/file/path</span>
- <div class="docgrok-annotation2">
- This is the file, wherein this class is defined.
- </div>
</div>
</div>
@@ -70,14 +62,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="item/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
<h2>Interfaces</h2>
@@ -108,14 +92,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="item/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
@@ -158,14 +134,6 @@
tal:condition="iface/doc"
tal:content="structure iface/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: iface/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="iface/path">x</span> import <span
- tal:replace="iface/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
</div>
@@ -202,14 +170,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="context/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make the
- functionality of this function available in your application
- or component.
- </div>
</div>
</div>
@@ -248,14 +208,6 @@
tal:condition="iface/doc"
tal:content="structure iface/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: iface/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="iface/path">x</span> import <span
- tal:replace="iface/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
</div>
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokgrokapplicationview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokgrokapplicationview.pt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokgrokapplicationview.pt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -27,20 +27,12 @@
<span class="docgrok-description1">Python path:</span>
<span class="docgrok-pathvalue"
tal:content="context/path">path.in.python</span>
- <div class="docgrok-annotation2">
- Use <span class="docgrok-pycode1">from <span tal:replace="context/module_path">path</span>
- import <span tal:replace="context/name">path</span></span>
- to use the functionality of this module in your application or component.
- </div>
</div>
<div class="docgrok-entry">
<span class="docgrok-description1">Absolute file path: </span>
<span class="docgrok-pathvalue"
tal:content="context/getFilePath">/absolute/file/path</span>
- <div class="docgrok-annotation2">
- This is the file, wherein this class is defined.
- </div>
</div>
</div>
@@ -70,14 +62,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="item/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
<h2>Interfaces</h2>
@@ -104,14 +88,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="item/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
@@ -156,14 +132,6 @@
tal:condition="iface/doc"
tal:content="structure iface/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: iface/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="iface/path">x</span> import <span
- tal:replace="iface/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
</div>
@@ -201,14 +169,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="context/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make the
- functionality of this function available in your application
- or component.
- </div>
</div>
</div>
@@ -247,14 +207,6 @@
tal:condition="iface/doc"
tal:content="structure iface/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: iface/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="iface/path">x</span> import <span
- tal:replace="iface/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
</div>
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokinterfaceview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokinterfaceview.pt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokinterfaceview.pt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -27,20 +27,12 @@
<span class="docgrok-description1">Python path:</span>
<span class="docgrok-pathvalue"
tal:content="context/path">path.in.python</span>
- <div class="docgrok-annotation2">
- Use <span class="docgrok-pycode1">from <span tal:replace="context/module_path">path</span>
- import <span tal:replace="context/name">path</span></span>
- to use the functionality of this module in your application or component.
- </div>
</div>
<div class="docgrok-entry">
<span class="docgrok-description1">Absolute file path: </span>
<span class="docgrok-pathvalue"
tal:content="context/getFilePath">/absolute/file/path</span>
- <div class="docgrok-annotation2">
- This is the file, wherein this class is defined.
- </div>
</div>
</div>
@@ -70,14 +62,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="item/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
@@ -120,14 +104,6 @@
tal:condition="iface/doc"
tal:content="structure iface/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: iface/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="iface/path">x</span> import <span
- tal:replace="iface/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
</div>
@@ -165,14 +141,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="context/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make the
- functionality of this function available in your application
- or component.
- </div>
</div>
</div>
@@ -211,14 +179,6 @@
tal:condition="iface/doc"
tal:content="structure iface/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: iface/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="iface/path">x</span> import <span
- tal:replace="iface/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
</div>
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokmoduleview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokmoduleview.pt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokmoduleview.pt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -22,20 +22,12 @@
<span class="docgrok-description1">Python path:</span>
<span class="docgrok-pathvalue"
tal:content="context/path">path.in.python</span>
- <div class="docgrok-annotation2">
- Use <span class="docgrok-pycode1">import
- <span tal:replace="context/path">path</span></span>
- to use the functionality of this module in your application or component.
- </div>
</div>
<div class="docgrok-entry">
<span class="docgrok-description1">Absolute file path: </span>
<span class="docgrok-pathvalue"
tal:content="context/getFilePath">/absolute/file/path</span>
- <div class="docgrok-annotation2">
- This is the file, where this module is located in file system.
- </div>
</div>
</div>
@@ -57,14 +49,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="context/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
</div>
@@ -84,14 +68,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="context/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make this
- interface definition available in your application
- or component.
- </div>
</div>
</div>
@@ -111,14 +87,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- Use <span class="docgrok-pycode1">from <span
- tal:replace="context/path">x</span> import <span
- tal:replace="item/name">y</span></span> to make the
- functionality of this class available in your application
- or component.
- </div>
</div>
</div>
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokpackageview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokpackageview.pt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokpackageview.pt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -21,20 +21,12 @@
<span class="docgrok-description1">Python path:</span>
<span class="docgrok-pathvalue"
tal:content="context/path">path.in.python</span>
- <div class="docgrok-annotation2">
- Use <span class="docgrok-pycode1">import
- <span tal:replace="context/path">path</span></span>
- to use the functionality of this package in your application or component.
- </div>
</div>
<div class="docgrok-entry">
<span class="docgrok-description1">Absolute file path: </span>
<span class="docgrok-pathvalue"
tal:content="context/getFilePath">absolute/file/path</span>
- <div class="docgrok-annotation2">
- This is, where this package is located in file system.
- </div>
</div>
<h2>Textfiles:</h2>
@@ -76,14 +68,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- You can use <span class="docgrok-pycode1">import <span
- tal:replace="string: ${context/path}.${item/name}">a.b</span>
- </span>
- to make the elements of this package available in your
- application or component.
- </div>
</div>
</div>
@@ -103,14 +87,6 @@
tal:condition="item/doc"
tal:content="structure item/doc">
</div>
- <div class="docgrok-annotation2"
- tal:condition="not: item/doc">
- You can use <span class="docgrok-pycode1">import <span
- tal:replace="string: ${context/path}.${item/name}">a.b</span>
- </span>
- to make the elements of this module available in your
- application or component.
- </div>
</div>
</div>
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgroktextfileview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgroktextfileview.pt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgroktextfileview.pt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -26,9 +26,6 @@
>
/home/uli/blah...
</span>
- <div class="docgrok-annotation1">
- This is, where this text file can be found.
- </div>
</div>
</div>
<div class="docgrok-sourcetext"
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/loginform.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/loginform.pt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/loginform.pt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,35 +0,0 @@
-<html metal:use-macro="context/@@macros/gaia-page">
- <head>
- <title metal:fill-slot="title">Grok Login</title>
- </head>
- <body>
- <div metal:fill-slot="menu-links" />
- <div metal:fill-slot="content">
- <h1>Welcome to Grok</h1>
- <form method="post">
- <fieldset>
- <legend>Login</legend>
-
- <table>
- <tr>
- <td><label for="login">Username:</label></td>
- <td><input id="login" type="text" name="login" /></td>
- </tr>
- <tr>
- <td><label for="password">Password:</label></td>
- <td><input id="password" type="password" name="password" /></td>
- </tr>
- <tr>
- <td></td>
- <td><input type="submit" value="Login"/></td>
- </tr>
- </table>
- <p>
- Note: To proceed you must have cookies enabled in your browser
- </p>
-
- </fieldset>
- </form>
- </div>
- </body>
-</html>
\ No newline at end of file
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/logout.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/logout.pt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/logout.pt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,8 +0,0 @@
-<html>
-<head>
- <title>Logged out</title>
-</head>
-<body>
- You have been logged out.
-</body>
-</html>
\ No newline at end of file
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/macros.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/macros.pt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/macros.pt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -26,9 +26,7 @@
<span i18n:translate="">User:
<span tal:replace="request/principal/title"
i18n:name="user_title">User</span>
- </span>
- [<a href=""
- tal:attributes="href string:${view/root_url}/logout">log out</a>]
+ </span>
</span>
</div>
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/server.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/server.pt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/server.pt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -16,7 +16,7 @@
<fieldset>
<legend>Admin message</legend>
- <p>Let's you display an administrative message on all pages.<br />
+ <p>Lets you display an administrative message on all pages.<br />
<input
type="text"
@@ -27,8 +27,8 @@
<input type="hidden" name="submitted" value="true"/>
<input type="submit" name="save_message" class="button" value="Save"/>
+ </p>
</fieldset>
-
<span class="header">Server process info</span>
<div id="server-processes">
<dl tal:define="ri view/runtime_info">
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/components.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/components.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/components.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -479,3 +479,9 @@
self.__grok_module__ = martian.util.caller_module()
Indexes = IndexesClass('Indexes')
+
+class Permission(object):
+ pass
+
+class Role(object):
+ pass
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/directive.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/directive.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/directive.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -17,7 +17,8 @@
from zope.interface.interfaces import IInterface
from martian.error import GrokImportError
-from martian.directive import (MultipleTimesDirective, BaseTextDirective,
+from martian.directive import (OnceDirective,
+ MultipleTimesDirective, BaseTextDirective,
SingleValue, SingleTextDirective,
MultipleTextDirective,
MarkerDirective,
@@ -47,7 +48,7 @@
if provides is None:
provides = util.class_annotation(factory, 'grok.provides', None)
self.provides = provides
-
+
if name is u'':
name = util.class_annotation(factory, 'grok.name', u'')
self.name = name
@@ -93,6 +94,14 @@
return func
return decorator
+class MultiValueOnceDirective(OnceDirective):
+
+ def check_arguments(self, *values):
+ pass
+
+ def value_factory(self, *args):
+ return args
+
# Define grok directives
name = SingleTextDirective('grok.name', ClassDirectiveContext())
template = SingleTextDirective('grok.template', ClassDirectiveContext())
@@ -105,8 +114,9 @@
ModuleDirectiveContext())
local_utility = LocalUtilityDirective('grok.local_utility',
ClassDirectiveContext())
-define_permission = MultipleTextDirective('grok.define_permission',
- ModuleDirectiveContext())
require = RequireDirective('grok.require', ClassDirectiveContext())
site = InterfaceOrClassDirective('grok.site',
ClassDirectiveContext())
+title = SingleTextDirective('grok.title', ClassDirectiveContext())
+permissions = MultiValueOnceDirective(
+ 'grok.permissions', ClassDirectiveContext())
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftesting.zcml
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftesting.zcml 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftesting.zcml 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
<configure
xmlns="http://namespaces.zope.org/zope"
+ xmlns:grok="http://namespaces.zope.org/grok"
i18n_domain="grok"
package="grok"
>
<include package="grok" />
+ <grok:grok package="grok.ftests" />
<securityPolicy
component="zope.app.securitypolicy.zopepolicy.ZopeSecurityPolicy"
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/README.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/README.txt 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/README.txt 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,6 +0,0 @@
-Creating functional tests
--------------------------
-
-Unfortunately, functional doctests do not import themselves (as the
-unit-test ones do), so you need to manually import the module in the
-doctest part.
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/apps.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/apps.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/apps.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -13,9 +13,6 @@
##############################################################################
"""
- >>> import grok
- >>> grok.grok('grok.ftests.admin.apps')
-
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
@@ -36,26 +33,21 @@
>>> print browser.contents
<html xmlns="http://www.w3.org/1999/xhtml">
...
- ... <p ...>Currently no working applications are...installed.</p>
+ ... <p ...>Currently no working...applications are installed.</p>
...
We are able to add a mammoth manager...
- >>> browser.getControl('Name your new app:',index=13).value = 'my-mammoth-manager'
- >>> browser.getControl('Create',index=13).click()
+ >>> browser.getControl('Name your new app:', index=2).value = 'my-mammoth-manager'
+ >>> browser.getControl('Create', index=2).click()
>>> print browser.contents
<html xmlns="http://www.w3.org/1999/xhtml">
...
- ... <legend>Installed applications</legend>
- ... <input type="checkbox" class="checkbox" name="items"
- value="my-mammoth-manager" />
- <a href="http://localhost/my-mammoth-manager">
- my-mammoth-manager
- (MammothManager)
- </a>
- ... <legend>Add application</legend>
+ ...<legend>Installed applications</legend>
...
+ ...<a href="http://localhost/my-mammoth-manager">
+ ...
Launch the added mammoth manager
@@ -90,7 +82,7 @@
>>> print browser.contents
<html xmlns="http://www.w3.org/1999/xhtml">
...
- ... <p ...>Currently no working applications are...installed.</p>
+ ... <p ...>Currently no working applications...are installed.</p>
...
...<legend>Add application</legend>
...
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/brokenobjs.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/brokenobjs.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/brokenobjs.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -27,14 +27,12 @@
usual:
>>> browser.open('http://localhost/applications')
- >>> 'broken' not in browser.contents
+ >>> 'Broken applications:' not in browser.contents
True
Now we grok this module, to have a new application type available,
which is intentionally broken:
- >>> import grok
- >>> grok.grok('grok.ftests.admin.brokenobjs')
>>> browser.open('http://localhost/applications')
>>> 'PseudoBroken' in browser.contents
True
@@ -82,6 +80,6 @@
import grok
from ZODB.broken import Broken
class PseudoBroken(grok.Application, grok.Container, Broken):
- """A class intentianally broken.
+ """A class intentionally broken.
"""
pass
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/loginlogout.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/loginlogout.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/loginlogout.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,105 +0,0 @@
-##############################################################################
-#
-# 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.
-#
-##############################################################################
-"""
-
- >>> import grok
- >>> grok.grok('grok.ftests.admin.loginlogout')
-
-First setup the pluggable authentication system for session based
-authentication. This is normaly invoked by an event
-handler. Unfortunately the event handler seems not to be called, if
-the ftesting setup is set up. We therefore set up the PAU manually.
-
- >>> root = getRootFolder()
- >>> root is not None
- True
-
- >>> import grok.admin
- >>> principal_credentials = grok.admin.getPrincipalCredentialsFromZCML()
- >>> principal_credentials
- [{u'login': u'mgr', u'password': u'mgrpw', u'id': u'zope.mgr', u'title': u'Manager'}]
-
- >>> grok.admin.setupSessionAuthentication(root_folder = root, principal_credentials = principal_credentials)
-
-We should get a login page if trying to get something unauthenticated.
-
- >>> from zope.testbrowser.testing import Browser
- >>> browser = Browser()
- >>> browser.handleErrors = True
- >>> browser.open("http://localhost/")
-
- >>> print browser.contents
- <html xmlns="http://www.w3.org/1999/xhtml">
- ... <title>Grok Login</title>
- ...
-
-Now try to log in using *wrong* credentials
-
- >>> browser.getControl(name='login').value = 'dumbtry'
- >>> browser.getControl('Login').click()
- >>> print browser.contents
- <html xmlns="http://www.w3.org/1999/xhtml">
- ... <title>Grok Login</title>
- ...
-
-Okay, we got the login screen again. What about the correct credentials?
-
- >>> browser.getControl(name='login').value = 'mgr'
- >>> browser.getControl(name='password').value = 'mgrpw'
- >>> browser.getControl('Login').click()
- >>> print browser.contents
- <html xmlns="http://www.w3.org/1999/xhtml">
- ... <title>grok administration interface</title>
- ...
-
-The new screen should contain a link for logging out:
-
- >>> print browser.contents
- <html xmlns="http://www.w3.org/1999/xhtml">
- ... <span>User:
- ...Manager
- ...[<a href="http://localhost/logout">log out</a>]
- ...
-
-Fine. Now we are authorized and can do, whatever we want. Let's log out:
-
- >>> outlink = browser.getLink('log out')
- >>> outlink
- <Link text='log out' url='http://localhost/logout'>
-
- >>> outlink.click()
- >>> print browser.contents
- <html>
- ... You have been logged out.
- ...
-
-Looks okay. But are we really logged out? Let's try to fetch a page:
-
- >>> browser.open("http://localhost/")
- >>> print browser.contents
- <html xmlns="http://www.w3.org/1999/xhtml">
- ... <title>Grok Login</title>
- ...
- ... <td><input id="login" type="text" name="login" /></td>
- ...
-
-Yes, we are.
-
- ...
- ... <legend>Add application</legend>
- ...
-
-
-"""
-
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/objectbrowser.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/objectbrowser.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/objectbrowser.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -13,9 +13,6 @@
##############################################################################
"""
- >>> import grok
- >>> grok.grok('grok.ftests.admin.objectbrowser')
-
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/catalog.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/catalog.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/catalog.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,8 +1,4 @@
"""
- >>> import grok
- >>> from grok.ftests.catalog.catalog import Mammoth, Herd
- >>> grok.grok('grok.ftests.catalog.catalog')
-
Let's setup a site in which we manage a couple of objects:
>>> herd = Herd()
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,12 +2,8 @@
Grok allows you to set up catalog indexes in your application with a
special indexes declaration.
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes')
-
Let's set up a site in which we manage a couple of objects::
- >>> from grok.ftests.catalog.indexes import Herd, Herd2, Mammoth
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> from zope.app.component.hooks import setSite
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_app_interface.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_app_interface.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_app_interface.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
special indexes declaration. Here we see how we can register indexes for
an interface instead of an application directly.
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes_app_interface')
-
Let's set up a site in which we manage a couple of objects::
- >>> from grok.ftests.catalog.indexes_app_interface import Herd, Herd2, Mammoth
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> from zope.app.component.hooks import setSite
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_attribute.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_attribute.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_attribute.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,12 +4,8 @@
from the attribute, you can do so, by passing an explicit `attribute`
keyword argument to the field.
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes_attribute')
-
Let's set up a site in which we manage a couple of objects::
- >>> from grok.ftests.catalog.indexes_attribute import Herd, Mammoth
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> from zope.app.component.hooks import setSite
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_class.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_class.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_class.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
special indexes declaration. This can also be done without explicit interface.
The context of the indexes applies to a class in this case.
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes_class')
-
Let's set up a site in which we manage a couple of objects::
- >>> from grok.ftests.catalog.indexes_class import Herd, Mammoth
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> from zope.app.component.hooks import setSite
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_module.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_module.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_module.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,16 +0,0 @@
-"""
-You can create an index on module level, but that should lead to a GrokError:
-
- >>> import grok
- >>> from grok.ftests.catalog.indexes_module import func
- >>> func()
- Traceback (most recent call last):
- ...
- GrokImportError: <class 'grok.index.Field'> can only be instantiated on
- class level.
-"""
-from grok import index
-
-def func():
- foo = index.Field()
-
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
special indexes declaration. In fact, we have multiple grok.Indexes
setting up more than one set of indexes in the same catalog.
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes_multiple')
-
Let's set up a site in which we manage a couple of objects::
- >>> from grok.ftests.catalog.indexes_multiple import Herd
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> from zope.app.component.hooks import setSite
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple_conflict.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple_conflict.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple_conflict.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,12 +4,8 @@
setting up more than one set of indexes in the same catalog. What if these
indexes define the same names?
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes_multiple_conflict')
-
Let's set up a site in which we manage a couple of objects::
- >>> from grok.ftests.catalog.indexes_multiple_conflict import Herd
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
Traceback (most recent call last):
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_name.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_name.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_name.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
special indexes declaration. We can specify the catalog name using
grok.name.
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes_name')
-
Let's set up a site in which we manage a couple of objects::
- >>> from grok.ftests.catalog.indexes_name import Herd, Mammoth
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> from zope.app.component.hooks import setSite
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_no_app.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_no_app.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_no_app.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,30 +0,0 @@
-"""
-Grok allows you to set up catalog indexes in your application with a
-special indexes declaration. We do need to specify a site (such as
-the application) for the Indexes however, otherwise we get a GrokError:
-
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes_no_app')
- Traceback (most recent call last):
- ...
- GrokError: No site specified for grok.Indexes subclass in module
- <module 'grok.ftests.catalog.indexes_no_app' from ...>.
- Use grok.site() to specify.
-
-"""
-import grok
-from grok import index
-
-class Herd(grok.Container, grok.Application):
- pass
-
-class Mammoth(grok.Model):
- pass
-
-class MammothIndexes(grok.Indexes):
- grok.context(Mammoth)
- grok.name('foo_catalog')
-
- name = index.Field()
- age = index.Field()
- message = index.Text()
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_nonexistent.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_nonexistent.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_nonexistent.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
special indexes declaration. Here we show what happens if you try
to set up an index for an attribute that does not exist on the interface.
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes_nonexistent')
-
Let's set up a site in which we manage a couple of objects::
- >>> from grok.ftests.catalog.indexes_nonexistent import Herd
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
Traceback (most recent call last):
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_set.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_set.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_set.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,12 +1,8 @@
"""
We now demonstrate the use of a SetIndex with Grok::
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes_set')
-
Let's set up a site in which we manage a couple of objects::
- >>> from grok.ftests.catalog.indexes_set import Herd, Mammoth
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> from zope.app.component.hooks import setSite
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_site.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_site.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_site.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
special indexes declaration. In fact, these indexes can be set up for
any site::
- >>> import grok
- >>> grok.grok('grok.ftests.catalog.indexes_site')
-
Let's set up a site in which we manage a couple of objects::
- >>> from grok.ftests.catalog.indexes_site import Herd
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> from zope.app.component.hooks import setSite
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/setuporder.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/setuporder.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/setuporder.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,10 +2,6 @@
This is similar to catalog.py, except that the site uses a base class
which also defines a local utility.
- >>> import grok
- >>> from grok.ftests.catalog.setuporder import Mammoth, Herd
- >>> grok.grok('grok.ftests.catalog.setuporder')
-
Let's setup a site in which we manage a couple of objects:
>>> herd = Herd()
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/actions.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/actions.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/actions.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,9 +4,6 @@
'Apply' action) is not available anymore, but it can triggered
manually by calling self.applyData(object, data).
- >>> import grok
- >>> from grok.ftests.form.actions import Mammoth
- >>> grok.grok('grok.ftests.form.actions')
>>> getRootFolder()["manfred"] = Mammoth()
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,9 +1,6 @@
"""
We can use grok.AddForm to render an add form for objects:
- >>> import grok
- >>> from grok.ftests.form.addform import Zoo, Mammoth
- >>> grok.grok('grok.ftests.form.addform')
>>> getRootFolder()["zoo"] = Zoo()
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_applydata.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_applydata.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_applydata.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,9 +3,6 @@
object. The object doesn't yet need to have the attributes that are
going to be set on it.
- >>> import grok
- >>> from grok.ftests.form.addform_applydata import Zoo, Mammoth
- >>> grok.grok('grok.ftests.form.addform_applydata')
>>> getRootFolder()["zoo"] = Zoo()
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_catalog.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_catalog.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_catalog.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,9 +2,6 @@
Thanks to Zope's event system, newly added objects are automatically
catalogued, should a catalog be present.
- >>> import grok
- >>> from grok.ftests.form.addform_catalog import Zoo, Mammoth
- >>> grok.grok('grok.ftests.form.addform_catalog')
>>> getRootFolder()["zoo"] = Zoo()
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,9 +3,6 @@
the object. Update mode means that only those fields are changed on
the object that need to be changed.
- >>> import grok
- >>> from grok.ftests.form.editform_applydata import Mammoth
- >>> grok.grok('grok.ftests.form.editform_applydata')
>>> getRootFolder()["manfred"] = Mammoth('Manfred the Mammoth', 'Really big')
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_classfields.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_classfields.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_classfields.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -6,9 +6,6 @@
This is essentially the same narrative as 'editform_applydata'. Here
we test the whole procedure on fields defined on the model class:
- >>> import grok
- >>> from grok.ftests.form.editform_applydata_classfields import Mammoth
- >>> grok.grok('grok.ftests.form.editform_applydata_classfields')
>>> getRootFolder()["manfred"] = mammoth = Mammoth()
>>> mammoth.name = 'Manfred the Mammoth'
>>> mammoth.size = 'Really big'
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_schema.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_schema.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_schema.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -6,9 +6,6 @@
This is essentially the same narrative as 'editform_applydata'. Here
we test the whole procedure on fields from schemas:
- >>> import grok
- >>> from grok.ftests.form.editform_applydata_schema import Mammoth
- >>> grok.grok('grok.ftests.form.editform_applydata_schema')
>>> getRootFolder()["manfred"] = Mammoth('Manfred the Mammoth', 'Really big')
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/form.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/form.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/form.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,9 +1,6 @@
"""
A grok.EditForm is a special grok.View that renders an edit form.
- >>> import grok
- >>> from grok.ftests.form.form import Mammoth
- >>> grok.grok('grok.ftests.form.form')
>>> getRootFolder()["manfred"] = Mammoth()
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/templateform.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/templateform.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/templateform.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,10 +2,6 @@
If a form does not have a template, a simple default template is
associated with them. Otherwise, the supplied template is used.
- >>> import grok
- >>> from grok.ftests.form.templateform import Mammoth
- >>> grok.grok('grok.ftests.form.templateform')
-
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> from zope import component
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/update.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/update.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/update.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,9 +2,6 @@
Forms can implement an update() method that will be called before any
form processing has happened:
- >>> import grok
- >>> grok.grok('grok.ftests.form.update')
- >>> from grok.ftests.form.update import Mammoth
>>> getRootFolder()["manfred"] = Mammoth()
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/grant.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/grant.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/grant.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,12 +1,8 @@
# -*- coding: latin-1 -*-
"""
-We can define a few permissions with grok.define_permission:
+We can define a few permissions with grok.Permission and then take a
+look at them in Zope 3's grant view:
- >>> import grok
- >>> grok.grok('grok.ftests.security.grant')
-
-and then take a look at them in Zope 3's grant view:
-
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
>>> browser.handleErrors = False
@@ -22,10 +18,10 @@
"""
import grok
-grok.define_permission('grok.ascii-permission')
+class ASCIIPermission(grok.Permission):
+ grok.name('grok.ascii-permission')
+
# TODO Technically, it's absolutely possible to give permissions
# non-ASCII names. However the way Zope 3's grant view uses widgets to
# display form controls for each permission is not unicode-safe.
-
-#grok.define_permission(u'grok.ünicöde-permission')
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/handle_exception.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/handle_exception.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/handle_exception.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,8 +4,6 @@
and cause the grok security to fail, we have a simple test here that assures
that we don't hit this:
- >>> import grok
- >>> grok.grok('grok.ftests.security.handle_exception')
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
>>> browser.open("http://localhost/@@cave")
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/json.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/json.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/json.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,9 +1,6 @@
"""
Let's test whether require decorators work for json methods.
- >>> import grok
- >>> grok.grok('grok.ftests.security.json')
-
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
>>> browser.handleErrors = False
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/require.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/require.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/require.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,7 +1,4 @@
"""
- >>> import grok
- >>> grok.grok('grok.ftests.security.require')
-
Viewing a protected view with insufficient privileges will yield
Unauthorized:
@@ -33,7 +30,8 @@
import grok
import zope.interface
-grok.define_permission('grok.ViewPainting')
+class ViewPainting(grok.Permission):
+ grok.name('grok.ViewPainting')
class CavePainting(grok.View):
Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/roles.py (from rev 79383, grok/trunk/src/grok/ftests/security/roles.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/roles.py (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/roles.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,97 @@
+"""
+Viewing a protected view with insufficient privileges will yield
+Unauthorized:
+
+ >>> from zope.testbrowser.testing import Browser
+ >>> browser = Browser()
+
+ >>> browser.open("http://localhost/@@cavepainting")
+ Traceback (most recent call last):
+ HTTPError: HTTP Error 401: Unauthorized
+
+ >>> browser.open("http://localhost/@@editcavepainting")
+ Traceback (most recent call last):
+ HTTPError: HTTP Error 401: Unauthorized
+
+ >>> browser.open("http://localhost/@@erasecavepainting")
+ Traceback (most recent call last):
+ HTTPError: HTTP Error 401: Unauthorized
+
+Let's now grant anonymous the PaintingOwner role locally (so that we
+don't have to modify the global setup). Then we can access the views
+just fine:
+
+ >>> from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
+ >>> root = getRootFolder()
+ >>> IPrincipalRoleManager(root).assignRoleToPrincipal(
+ ... 'grok.PaintingOwner', 'zope.anybody')
+
+ >>> browser.open("http://localhost/@@cavepainting")
+ >>> print browser.contents
+ What a beautiful painting.
+
+ >>> browser.open("http://localhost/@@editcavepainting")
+ >>> print browser.contents
+ Let's make it even prettier.
+
+ >>> browser.open("http://localhost/@@erasecavepainting")
+ >>> print browser.contents
+ Oops, mistake, let's erase it.
+
+ >>> browser.open("http://localhost/@@approvecavepainting")
+ Traceback (most recent call last):
+ HTTPError: HTTP Error 401: Unauthorized
+"""
+
+import grok
+import zope.interface
+
+class View(grok.Permission):
+ grok.name('grok.ViewPainting')
+
+class Edit(grok.Permission):
+ grok.name('grok.EditPainting')
+
+class Erase(grok.Permission):
+ grok.name('grok.ErasePainting')
+
+class Approve(grok.Permission):
+ grok.name('grok.ApprovePainting')
+
+class PaintingOwner(grok.Role):
+ grok.name('grok.PaintingOwner')
+ grok.title('Painting Owner')
+ grok.permissions(
+ 'grok.ViewPainting', 'grok.EditPainting', 'grok.ErasePainting')
+
+class CavePainting(grok.View):
+
+ grok.context(zope.interface.Interface)
+ grok.require('grok.ViewPainting')
+
+ def render(self):
+ return 'What a beautiful painting.'
+
+class EditCavePainting(grok.View):
+
+ grok.context(zope.interface.Interface)
+ grok.require('grok.EditPainting')
+
+ def render(self):
+ return 'Let\'s make it even prettier.'
+
+class EraseCavePainting(grok.View):
+
+ grok.context(zope.interface.Interface)
+ grok.require('grok.ErasePainting')
+
+ def render(self):
+ return 'Oops, mistake, let\'s erase it.'
+
+class ApproveCavePainting(grok.View):
+
+ grok.context(zope.interface.Interface)
+ grok.require('grok.ApprovePainting')
+
+ def render(self):
+ return 'Painting owners cannot approve their paintings.'
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/xmlrpc.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/xmlrpc.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/xmlrpc.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,9 +1,5 @@
"""
- >>> import grok
- >>> grok.grok('grok.ftests.security.xmlrpc')
-
- >>> from grok.ftests.xmlrpc_helper import ServerProxy
-
+ >>> from zope.app.testing.xmlrpc import ServerProxy
>>> server = ServerProxy("http://localhost/")
>>> mgr_server = ServerProxy("http://mgr:mgrpw@localhost/")
Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/staticdir (from rev 79383, grok/trunk/src/grok/ftests/staticdir)
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/test_grok_functional.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/test_grok_functional.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/test_grok_functional.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -42,7 +42,7 @@
def test_suite():
suite = unittest.TestSuite()
- for name in ['view', 'static', 'xmlrpc', 'traversal', 'form', 'url',
+ for name in ['view', 'staticdir', 'xmlrpc', 'traversal', 'form', 'url',
'security', 'utility', 'catalog','admin']:
suite.addTest(suiteFromPackage(name))
return suite
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverse.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverse.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverse.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,9 +3,6 @@
implementing a 'traverse' method, but the behavior falls back to
basic container traversal if the 'traverse' method returns None:
- >>> import grok
- >>> from grok.ftests.traversal.containertraverse import Herd, Mammoth
- >>> grok.grok('grok.ftests.traversal.containertraverse')
>>> getRootFolder()["herd"] = herd = Herd()
>>> herd['manfred'] = Mammoth('Manfred')
>>> herd['ellie'] = Mammoth('Ellie')
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverser.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverser.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverser.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,9 +3,6 @@
The behavior falls back to basic container traversal if the 'traverse'
method returns None:
- >>> import grok
- >>> from grok.ftests.traversal.containertraverser import Herd, Mammoth
- >>> grok.grok('grok.ftests.traversal.containertraverser')
>>> getRootFolder()["herd"] = herd = Herd()
>>> herd['manfred'] = Mammoth('Manfred')
>>> herd['ellie'] = Mammoth('Ellie')
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/items_before_views.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/items_before_views.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/items_before_views.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,9 +4,6 @@
method returns None. Normal behaviour also means that the standard
Zope 3 paradigm"items before views" is supported in the fallback.
- >>> import grok
- >>> from grok.ftests.traversal.items_before_views import Herd, Mammoth
- >>> grok.grok('grok.ftests.traversal.items_before_views')
>>> getRootFolder()["herd"] = herd = Herd()
>>> herd['manfred'] = Mammoth('Manfred')
>>> herd['ellie'] = Mammoth('Ellie')
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/modeltraverse.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/modeltraverse.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/modeltraverse.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,9 +2,6 @@
Models can determine how they want to be traversed by
implementing a 'traverse' method:
- >>> import grok
- >>> from grok.ftests.traversal.modeltraverse import Herd
- >>> grok.grok('grok.ftests.traversal.modeltraverse')
>>> getRootFolder()["herd"] = Herd('The Big Mammoth Herd')
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,9 +2,6 @@
Apart from using the ``traverse`` method on a model, you can
also create a separate traverser component:
- >>> import grok
- >>> from grok.ftests.traversal.traverser import Herd
- >>> grok.grok('grok.ftests.traversal.traverser')
>>> getRootFolder()["herd"] = Herd('The Big Mammoth Herd')
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser_sets_parent.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser_sets_parent.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser_sets_parent.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,9 +2,6 @@
A traverser can set the __parent__ (and __name__) attributes itself,
in which case Grok's traverser won't interfere:
- >>> import grok
- >>> from grok.ftests.traversal.traverser_sets_parent import Herd
- >>> grok.grok('grok.ftests.traversal.traverser_sets_parent')
>>> getRootFolder()["herd"] = Herd('The Big Mammoth Herd')
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/application.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/application.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/application.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,10 +2,6 @@
Views have an application_url() method to easily retrieve the url of the
application::
- >>> import grok
- >>> grok.grok('grok.ftests.url.application')
-
- >>> from grok.ftests.url.application import Cave, CaveMan
>>> getRootFolder()['cave'] = cave = Cave()
>>> cave['caveman'] = CaveMan()
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/redirect.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/redirect.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/redirect.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,6 @@
"""
Views have a redirect() method to easily create redirects:
- >>> import grok
- >>> grok.grok('grok.ftests.url.redirect')
-
- >>> from grok.ftests.url.redirect import Mammoth
>>> getRootFolder()['manfred'] = manfred = Mammoth()
Since the index view redirects to mammoth, we expect to see the URL
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,10 +2,6 @@
"""
Views have a method that can be used to construct URLs:
- >>> import grok
- >>> grok.grok('grok.ftests.url.url')
-
- >>> from grok.ftests.url.url import Herd, Mammoth
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> manfred = Mammoth()
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url_function.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url_function.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url_function.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,10 +4,7 @@
absolute URL of objects.
>>> from grok import url
- >>> import grok
- >>> grok.grok('grok.ftests.url.url_function')
- >>> from grok.ftests.url.url_function import Herd, Mammoth
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> manfred = Mammoth()
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,15 +2,10 @@
Local Utilities can be registered on subclasses of grok.Site using
grok.local_utility:
- >>> import grok
- >>> from zope import component
- >>> from grok.ftests.utility.local import *
-
- >>> grok.grok('grok.ftests.utility.local')
-
>>> cave = Cave()
>>> getRootFolder()["cave"] = cave
+ >>> from zope import component
>>> from zope.app.component.hooks import getSite, setSite
>>> setSite(cave)
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local_override.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local_override.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local_override.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,15 +2,10 @@
Local Utilities can be registered on subclasses of grok.Site using
grok.local_utility:
- >>> import grok
- >>> from zope import component
- >>> from grok.ftests.utility.local_override import *
-
- >>> grok.grok('grok.ftests.utility.local_override')
-
>>> cave = SpikyCave()
>>> getRootFolder()['cave'] = cave
+ >>> from zope import component
>>> from zope.app.component.hooks import getSite, setSite
>>> setSite(cave)
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_class.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_class.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_class.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,33 +0,0 @@
-"""
-When you try to register multiple classes with the same (interface, name)
-combination multiple times using grok.local_utility, we expect an error:
-
- >>> import grok
- >>> from zope import component
- >>> from grok.ftests.utility.multiple_class import *
-
- >>> grok.grok('grok.ftests.utility.multiple_class')
- Traceback (most recent call last):
- ...
- GrokError: Conflicting local utility registration
- <class 'grok.ftests.utility.multiple_class.Fireplace2'> in site
- <class 'grok.ftests.utility.multiple_class.Cave'>.
- Local utilities are registered multiple times for interface
- <InterfaceClass grok.ftests.utility.multiple_class.IFireplace> and
- name 'Foo'.
-"""
-import grok
-from zope import interface
-
-class IFireplace(interface.Interface):
- pass
-
-class Fireplace(grok.LocalUtility):
- grok.implements(IFireplace)
-
-class Fireplace2(grok.LocalUtility):
- grok.implements(IFireplace)
-
-class Cave(grok.Model, grok.Site):
- grok.local_utility(Fireplace, name='Foo')
- grok.local_utility(Fireplace2, name='Foo')
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_directive.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_directive.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_directive.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,33 +0,0 @@
-"""
-When you call the grok.local_utility directive multiple times specifying
-the same (interface, name) combination, we expect an error:
-
- >>> import grok
- >>> from zope import component
- >>> from grok.ftests.utility.multiple_directive import *
-
- >>> grok.grok('grok.ftests.utility.multiple_directive')
- Traceback (most recent call last):
- ...
- GrokError: Conflicting local utility registration
- <class 'grok.ftests.utility.multiple_directive.Fireplace2'> in site
- <class 'grok.ftests.utility.multiple_directive.Cave'>.
- Local utilities are registered multiple times for interface
- <InterfaceClass grok.ftests.utility.multiple_directive.IFireplace> and
- name u''.
-"""
-import grok
-from zope import interface
-
-class IFireplace(interface.Interface):
- pass
-
-class Fireplace(grok.LocalUtility):
- grok.implements(IFireplace)
-
-class Fireplace2(grok.LocalUtility):
- grok.implements(IFireplace)
-
-class Cave(grok.Model, grok.Site):
- grok.local_utility(Fireplace, provides=IFireplace)
- grok.local_utility(Fireplace2, provides=IFireplace)
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/public.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/public.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/public.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,14 +4,10 @@
that is the site. The name the utility should have in the container can
be controlled using name_in_container:
- >>> import grok
- >>> from zope import component
- >>> from grok.ftests.utility.public import *
- >>> grok.grok('grok.ftests.utility.public')
-
>>> cave = Cave()
>>> getRootFolder()["cave"] = cave
+ >>> from zope import component
>>> from zope.app.component.hooks import getSite, setSite
>>> setSite(cave)
>>> cave['fireplace'] is component.getUtility(IFireplace)
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/publicnoncontainer.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/publicnoncontainer.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/publicnoncontainer.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,26 +0,0 @@
-"""
-You cannot use local_utility with 'public' set to True if the site class
-isn't a container:
-
- >>> import grok
- >>> from zope import component
- >>> from grok.ftests.utility.publicnoncontainer import *
- >>> grok.grok('grok.ftests.utility.publicnoncontainer')
- Traceback (most recent call last):
- ...
- GrokError: Cannot set public to True with grok.local_utility as the site
- (<class 'grok.ftests.utility.publicnoncontainer.Cave'>) is not a container.
-
-"""
-
-import grok
-from zope import interface
-
-class IFireplace(interface.Interface):
- pass
-
-class Fireplace(grok.LocalUtility):
- grok.implements(IFireplace)
-
-class Cave(grok.Model, grok.Site):
- grok.local_utility(Fireplace, public=True, name_in_container='fireplace')
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/subclass.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/subclass.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/subclass.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,15 +1,10 @@
"""
Subclassed sites inherit all local utilities of their base classes:
- >>> import grok
- >>> from zope import component
- >>> from grok.ftests.utility.subclass import *
-
- >>> grok.grok('grok.ftests.utility.subclass')
-
>>> cave = BigCave()
>>> getRootFolder()["cave"] = cave
+ >>> from zope import component
>>> from zope.app.component.hooks import getSite, setSite
>>> setSite(cave)
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/argument.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/argument.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/argument.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,7 +1,4 @@
"""
- >>> import grok
- >>> from grok.ftests.view.argument import Mammoth
- >>> grok.grok('grok.ftests.view.argument')
>>> getRootFolder()["manfred"] = Mammoth()
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/index.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/index.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/index.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,7 +1,4 @@
"""
- >>> import grok
- >>> from grok.ftests.view.index import Mammoth
- >>> grok.grok('grok.ftests.view.index')
>>> getRootFolder()["manfred"] = Mammoth()
The default view name for a model is 'index':
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/macros.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/macros.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/macros.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,7 +1,4 @@
"""
- >>> import grok
- >>> from grok.ftests.view.macros import Mammoth
- >>> grok.grok('grok.ftests.view.macros')
>>> getRootFolder()["manfred"] = Mammoth()
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/view.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/view.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/view.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,7 +1,4 @@
"""
- >>> import grok
- >>> from grok.ftests.view.view import Mammoth
- >>> grok.grok('grok.ftests.view.view')
>>> getRootFolder()["manfred"] = Mammoth()
>>> from zope.testbrowser.testing import Browser
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc/xmlrpc.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc/xmlrpc.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc/xmlrpc.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,12 +1,9 @@
"""
- >>> import grok
- >>> grok.grok('grok.ftests.xmlrpc.xmlrpc')
- >>> from grok.ftests.xmlrpc.xmlrpc import Mammoth
>>> getRootFolder()["Manfred"] = Mammoth()
- >>> from grok.ftests.xmlrpc_helper import ServerProxy
-
+ >>> from zope.app.testing.xmlrpc import ServerProxy
>>> server = ServerProxy("http://localhost/")
+
>>> server.Manfred.stomp()
'Manfred stomped.'
>>> server.Manfred.dance()
Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc_helper.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc_helper.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc_helper.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,77 +0,0 @@
-# XXX This code is duplicated from Zope 3 trunk (future Zope 3.4) as we want to
-# stay compatible with Zope 3.3
-#
-##############################################################################
-#
-# 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.
-#
-##############################################################################
-"""XMLRPC testing helpers for Zope 3.
-
-$Id$
-"""
-
-import StringIO
-import xmlrpclib
-
-from zope.app.testing.functional import HTTPCaller
-
-
-class ZopeTestTransport(xmlrpclib.Transport):
- """xmlrpclib transport that delegates to
- zope.app.testing.functional.HTTPCaller.
-
- It can be used like a normal transport, including support for basic
- authentication.
- """
-
- verbose = False
- handleErrors = True
-
- def request(self, host, handler, request_body, verbose=0):
- request = "POST %s HTTP/1.0\n" % (handler,)
- request += "Content-Length: %i\n" % len(request_body)
- request += "Content-Type: text/xml\n"
-
- host, extra_headers, x509 = self.get_host_info(host)
- if extra_headers:
- request += "Authorization: %s\n" \
- % (dict(extra_headers)["Authorization"],)
-
- request += "\n" + request_body
- response = HTTPCaller()(request, handle_errors=self.handleErrors)
-
- errcode = response.getStatus()
- errmsg = response.getStatusString()
- # This is not the same way that the normal transport deals
- # with the headers.
- headers = response.getHeaders()
-
- if errcode != 200:
- raise xmlrpclib.ProtocolError(
- host + handler,
- errcode, errmsg,
- headers
- )
-
- return self._parse_response(
- StringIO.StringIO(response.getBody()), sock=None)
-
-
-def ServerProxy(uri, transport=ZopeTestTransport(), encoding=None,
- verbose=0, allow_none=0, handleErrors=True):
- """A factory that creates a server proxy using the ZopeTestTransport
- by default.
-
- """
- if isinstance(transport, ZopeTestTransport):
- transport.handleErrors = handleErrors
- return xmlrpclib.ServerProxy(uri, transport, encoding, verbose, allow_none)
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/interfaces.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/interfaces.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/interfaces.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -122,14 +122,15 @@
name_in_container - the name to use for storing the utility
"""
- def define_permission(permission):
- """Defines a new permission with the id ``permission``."""
+ def permissions(permissions):
+ """Specify the permissions that comprise a role.
+ """
def require(permission):
"""Protect a view class or an XMLRPC method with ``permision``.
``permission`` must already be defined, e.g. using
- grok.define_permission.
+ grok.Permission.
grok.require can be used as a class-level directive or as a
method decorator."""
@@ -204,7 +205,7 @@
Note that context, module_info and templates might be required
for some grokkers which rely on them.
"""
-
+
def url(request, obj, name=None):
"""Generate the URL to an object with optional name attached.
"""
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/meta.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/meta.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/meta.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -23,6 +23,9 @@
from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
from zope.security.permission import Permission
from zope.security.interfaces import IPermission
+from zope.app.securitypolicy.role import Role
+from zope.app.securitypolicy.rolepermission import rolePermissionManager
+
from zope.annotation.interfaces import IAnnotations
from zope.app.publisher.xmlrpc import MethodPublisher
@@ -489,26 +492,43 @@
site_manager.registerUtility(utility, provided=provides,
name=name)
+class DefinePermissionGrokker(martian.ClassGrokker):
+ component_class = grok.Permission
+ priority = 1500
-class DefinePermissionGrokker(martian.GlobalGrokker):
+ def grok(self, name, factory, context, module_info, templates):
+ permission_name = util.class_annotation(factory, 'grok.name', None)
+ if permission_name is None:
+ raise GrokError(
+ "A permission needs to have a dotted name for its id. Use "
+ "grok.name to specify one.", factory)
+ permission_name = unicode(permission_name)
+ title = unicode(
+ util.class_annotation(factory, 'grok.title', permission_name))
+ # TODO permission description
+ component.provideUtility(
+ Permission(permission_name, title=title),
+ name=permission_name)
+ return True
- priority = 1500
+class DefineRoleGrokker(martian.ClassGrokker):
+ component_class = grok.Role
+ priority = DefinePermissionGrokker.priority - 1
- def grok(self, name, module, context, module_info, templates):
- permissions = module_info.getAnnotation('grok.define_permission', [])
+ def grok(self, name, factory, context, module_info, templates):
+ role_name = util.class_annotation(factory, 'grok.name', None)
+ if role_name is None:
+ raise GrokError(
+ "A role needs to have a dotted name for its id. Use "
+ "grok.name to specify one.", factory)
+ title = unicode(util.class_annotation(factory, 'grok.title', role_name))
+ component.provideUtility(Role(role_name, title=title), name=role_name)
+
+ permissions = util.class_annotation(factory, 'grok.permissions', ())
for permission in permissions:
- # IPermission.title says that permission ids (and titles,
- # descriptions) *must* be unicode objects. Good news is
- # that the directive handler already made sure we either
- # got pure ASCII or unicode here:
- permission = unicode(permission)
- # TODO permission title and description
- component.provideUtility(Permission(permission, title=permission),
- name=permission)
-
+ rolePermissionManager.grantPermissionToRole(permission, role_name)
return True
-
class AnnotationGrokker(martian.ClassGrokker):
component_class = grok.Annotation
Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/catalog (from rev 79383, grok/trunk/src/grok/tests/catalog)
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
"""
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in grok.require().
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in grok.require().
>>> grok.grok(__name__)
Traceback (most recent call last):
- GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission.MissingPermission'>. Use grok.define_permission first.
+ GrokError: Undefined permission 'doesnt.exist' in <class
+ 'grok.tests.security.missing_permission.MissingPermission'>. Use
+ grok.Permission first.
"""
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
"""
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in grok.require() in an JSON class.
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in grok.require() in an JSON class.
>>> grok.grok(__name__)
Traceback (most recent call last):
- GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission_json.MissingPermission'>. Use grok.define_permission first.
+ GrokError: Undefined permission 'doesnt.exist' in <class
+ 'grok.tests.security.missing_permission_json.MissingPermission'>. Use
+ grok.Permission first.
"""
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json2.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json2.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json2.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
"""
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in @grok.require().
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in @grok.require().
>>> grok.grok(__name__)
Traceback (most recent call last):
- GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission_json2.MissingPermission'>. Use grok.define_permission first.
+ GrokError: Undefined permission 'doesnt.exist' in <class
+ 'grok.tests.security.missing_permission_json2.MissingPermission'>. Use
+ grok.Permission first.
"""
Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_name.py (from rev 79383, grok/trunk/src/grok/tests/security/missing_permission_name.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_name.py (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_name.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,15 @@
+"""
+A role has to have a name to be defined.
+
+ >>> grok.grok(__name__)
+ Traceback (most recent call last):
+ ...
+ GrokError: A permission needs to have a dotted name for its id.
+ Use grok.name to specify one.
+"""
+
+import grok
+import zope.interface
+
+class MissingName(grok.Permission):
+ pass
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
"""
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in grok.require() in an XMLRPC class.
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in grok.require() in an XMLRPC class.
>>> grok.grok(__name__)
Traceback (most recent call last):
- GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission_xmlrpc.MissingPermission'>. Use grok.define_permission first.
+ GrokError: Undefined permission 'doesnt.exist' in <class
+ 'grok.tests.security.missing_permission_xmlrpc.MissingPermission'>. Use
+ grok.Permission first.
"""
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc2.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc2.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc2.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
"""
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in @grok.require().
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in @grok.require().
>>> grok.grok(__name__)
Traceback (most recent call last):
- GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission_xmlrpc2.MissingPermission'>. Use grok.define_permission first.
+ GrokError: Undefined permission 'doesnt.exist' in <class
+ 'grok.tests.security.missing_permission_xmlrpc2.MissingPermission'>. Use
+ grok.Permission first.
"""
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc3.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc3.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc3.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,19 +1,22 @@
"""
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in grok.require() in an XMLRPC class. This
-is even the case for a default permission that is never used.
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in grok.require() in an XMLRPC class. This is even the
+case for a default permission that is never used.
>>> grok.grok(__name__)
Traceback (most recent call last):
...
- GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission_xmlrpc3.MissingPermission'>. Use grok.define_permission first.
+ GrokError: Undefined permission 'doesnt.exist' in <class
+ 'grok.tests.security.missing_permission_xmlrpc3.MissingPermission'>. Use
+ grok.Permission first.
"""
import grok
import zope.interface
-grok.define_permission('foo')
+class Foo(grok.Permission):
+ grok.name('foo')
class MissingPermission(grok.XMLRPC):
grok.context(zope.interface.Interface)
Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_role_name.py (from rev 79383, grok/trunk/src/grok/tests/security/missing_role_name.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_role_name.py (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_role_name.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,14 @@
+"""
+A role has to have a name to be defined.
+
+ >>> grok.grok(__name__)
+ Traceback (most recent call last):
+ GrokError: A role needs to have a dotted name for its id.
+ Use grok.name to specify one.
+"""
+
+import grok
+import zope.interface
+
+class MissingName(grok.Role):
+ pass
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -10,9 +10,12 @@
import grok
import zope.interface
-grok.define_permission('permission.1')
-grok.define_permission('permission.2')
+class One(grok.Permission):
+ grok.name('permission.1')
+class Two(grok.Permission):
+ grok.name('permission.2')
+
class MultipleView(grok.View):
grok.context(zope.interface.Interface)
grok.require('permission.1')
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_json.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_json.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_json.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -5,14 +5,17 @@
Traceback (most recent call last):
...
GrokError: grok.require was called multiple times in <class 'grok.tests.security.multiple_require_json.MultipleJSON'>. It may only be set once for a class.
-
+
"""
import grok
import zope.interface
-grok.define_permission('permission.1')
-grok.define_permission('permission.2')
+class One(grok.Permission):
+ grok.name('permission.1')
+class Two(grok.Permission):
+ grok.name('permission.2')
+
class MultipleJSON(grok.JSON):
grok.context(zope.interface.Interface)
grok.require('permission.1')
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_xmlrpc.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_xmlrpc.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_xmlrpc.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -9,9 +9,12 @@
import grok
import zope.interface
-grok.define_permission('permission.1')
-grok.define_permission('permission.2')
+class One(grok.Permission):
+ grok.name('permission.1')
+class Two(grok.Permission):
+ grok.name('permission.2')
+
class MultipleXMLRPC(grok.XMLRPC):
grok.context(zope.interface.Interface)
grok.require('permission.1')
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/view_decorator.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/view_decorator.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/view_decorator.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -11,7 +11,8 @@
import grok
import zope.interface
-grok.define_permission('bogus.perm')
+class Bogus(grok.Permission):
+ grok.name('bogus.perm')
class BogusView(grok.View):
grok.context(zope.interface.Interface)
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/test_grok.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/test_grok.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/test_grok.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -32,7 +32,7 @@
def test_suite():
suite = unittest.TestSuite()
- for name in ['adapter', 'error', 'view', 'event', 'security',
+ for name in ['adapter', 'error', 'view', 'event', 'security', 'catalog',
'zcml', 'static', 'utility', 'xmlrpc', 'json', 'container',
'traversal', 'form', 'site', 'grokker', 'directive', 'util',
'baseclass', 'annotation', 'application']:
Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_class.py (from rev 79383, grok/trunk/src/grok/tests/utility/multiple_class.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_class.py (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_class.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,29 @@
+"""
+When you try to register multiple classes with the same (interface, name)
+combination multiple times using grok.local_utility, we expect an error:
+
+ >>> grok.grok(__name__)
+ Traceback (most recent call last):
+ ...
+ GrokError: Conflicting local utility registration
+ <class 'grok.tests.utility.multiple_class.Fireplace2'> in site
+ <class 'grok.tests.utility.multiple_class.Cave'>.
+ Local utilities are registered multiple times for interface
+ <InterfaceClass grok.tests.utility.multiple_class.IFireplace> and
+ name 'Foo'.
+"""
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+ pass
+
+class Fireplace(grok.LocalUtility):
+ grok.implements(IFireplace)
+
+class Fireplace2(grok.LocalUtility):
+ grok.implements(IFireplace)
+
+class Cave(grok.Model, grok.Site):
+ grok.local_utility(Fireplace, name='Foo')
+ grok.local_utility(Fireplace2, name='Foo')
Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_directive.py (from rev 79383, grok/trunk/src/grok/tests/utility/multiple_directive.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_directive.py (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_directive.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,29 @@
+"""
+When you call the grok.local_utility directive multiple times specifying
+the same (interface, name) combination, we expect an error:
+
+ >>> grok.grok(__name__)
+ Traceback (most recent call last):
+ ...
+ GrokError: Conflicting local utility registration
+ <class 'grok.tests.utility.multiple_directive.Fireplace2'> in site
+ <class 'grok.tests.utility.multiple_directive.Cave'>.
+ Local utilities are registered multiple times for interface
+ <InterfaceClass grok.tests.utility.multiple_directive.IFireplace> and
+ name u''.
+"""
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+ pass
+
+class Fireplace(grok.LocalUtility):
+ grok.implements(IFireplace)
+
+class Fireplace2(grok.LocalUtility):
+ grok.implements(IFireplace)
+
+class Cave(grok.Model, grok.Site):
+ grok.local_utility(Fireplace, provides=IFireplace)
+ grok.local_utility(Fireplace2, provides=IFireplace)
Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/publicnoncontainer.py (from rev 79383, grok/trunk/src/grok/tests/utility/publicnoncontainer.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/publicnoncontainer.py (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/publicnoncontainer.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,23 @@
+"""
+You cannot use local_utility with 'public' set to True if the site class
+isn't a container:
+
+ >>> grok.grok(__name__)
+ Traceback (most recent call last):
+ ...
+ GrokError: Cannot set public to True with grok.local_utility as the site
+ (<class 'grok.tests.utility.publicnoncontainer.Cave'>) is not a container.
+
+"""
+
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+ pass
+
+class Fireplace(grok.LocalUtility):
+ grok.implements(IFireplace)
+
+class Cave(grok.Model, grok.Site):
+ grok.local_utility(Fireplace, public=True, name_in_container='fireplace')
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/view/dirtemplatesonly.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/view/dirtemplatesonly.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/view/dirtemplatesonly.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -8,7 +8,7 @@
>>> grok.grok(__name__)
From tests.py's showwarning():
- ... UserWarning: File 'invalid.txt' has an unrecognized extension in directory '...dirtemplatesonly_templates'
+ ... UserWarning: File 'invalid.txt' has an unrecognized extension in directory '...dirtemplatesonly_templates'...
>>> warnings.warn = saved_warn
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/zcml/directiveerror.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/zcml/directiveerror.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/zcml/directiveerror.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -14,9 +14,8 @@
... </configure>''', context=context)
Traceback (most recent call last):
...
- ZopeXMLConfigurationError: File "...", line ...
- GrokError: No module-level context for
- <class 'grok.tests.zcml.directiveerror.CavePainting'>, please use grok.context.
+ ConfigurationExecutionError: martian.error.GrokError: No module-level context for <class 'grok.tests.zcml.directiveerror.CavePainting'>, please use grok.context.
+ ...
"""
import grok
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/util.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/util.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/util.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -55,7 +55,7 @@
if component.queryUtility(IPermission,
name=permission) is None:
raise GrokError('Undefined permission %r in %r. Use '
- 'grok.define_permission first.'
+ 'grok.Permission first.'
% (permission, factory), factory)
def get_default_permission(factory):
Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/zcml.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/zcml.py 2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/zcml.py 2007-08-30 23:53:54 UTC (rev 79388)
@@ -30,4 +30,8 @@
def grokDirective(_context, package):
- grok.grok(package.__name__)
+ _context.action(
+ discriminator=('grok', package.__name__),
+ callable=grok.grok,
+ args=(package.__name__,)
+ )
More information about the Checkins
mailing list