[Checkins] SVN: five.grokkers/trunk/five/grokkers/ Views work (without security).

Lennart Regebro regebro at gmail.com
Sat Apr 26 04:33:18 EDT 2008


Log message for revision 85742:
  Views work (without security).
  

Changed:
  A   five.grokkers/trunk/five/grokkers/components.py
  U   five.grokkers/trunk/five/grokkers/configure.zcml
  U   five.grokkers/trunk/five/grokkers/grok.py
  A   five.grokkers/trunk/five/grokkers/meta.py
  U   five.grokkers/trunk/five/grokkers/tests/test_all.py
  U   five.grokkers/trunk/five/grokkers/tests/utilities.py
  A   five.grokkers/trunk/five/grokkers/tests/views.py
  A   five.grokkers/trunk/five/grokkers/util.py

-=-
Added: five.grokkers/trunk/five/grokkers/components.py
===================================================================
--- five.grokkers/trunk/five/grokkers/components.py	                        (rev 0)
+++ five.grokkers/trunk/five/grokkers/components.py	2008-04-26 08:33:18 UTC (rev 85742)
@@ -0,0 +1,7 @@
+from Products.Five import BrowserView
+
+from zope.publisher.browser import BrowserPage
+
+class View(BrowserView):
+    pass
+


Property changes on: five.grokkers/trunk/five/grokkers/components.py
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: five.grokkers/trunk/five/grokkers/configure.zcml
===================================================================
--- five.grokkers/trunk/five/grokkers/configure.zcml	2008-04-26 07:46:02 UTC (rev 85741)
+++ five.grokkers/trunk/five/grokkers/configure.zcml	2008-04-26 08:33:18 UTC (rev 85742)
@@ -2,4 +2,6 @@
     xmlns="http://namespaces.zope.org/zope"
     xmlns:grok="http://namespaces.zope.org/grok">
 
+    <grok:grok package=".meta" />
+    
 </configure>

Modified: five.grokkers/trunk/five/grokkers/grok.py
===================================================================
--- five.grokkers/trunk/five/grokkers/grok.py	2008-04-26 07:46:02 UTC (rev 85741)
+++ five.grokkers/trunk/five/grokkers/grok.py	2008-04-26 08:33:18 UTC (rev 85742)
@@ -1,3 +1,6 @@
+# Import adapter and utility support from grokcore.component.
 from grokcore.component.components import GlobalUtility, Adapter
 from grokcore.component.directive import name, provides, context
 from zope.interface import implements
+
+from components import View

Added: five.grokkers/trunk/five/grokkers/meta.py
===================================================================
--- five.grokkers/trunk/five/grokkers/meta.py	                        (rev 0)
+++ five.grokkers/trunk/five/grokkers/meta.py	2008-04-26 08:33:18 UTC (rev 85742)
@@ -0,0 +1,85 @@
+import martian
+from martian import util
+from zope import interface, component
+from five.grokkers import grok
+from five.grokkers.util import get_default_permission, make_checker
+from grokcore.component.meta import get_context, get_name_classname
+from grokcore.component.util import determine_class_directive
+
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+                                               #IBrowserRequest,
+                                               #IBrowserPublisher,
+                                               #IBrowserSkinType)
+
+class ViewGrokker(martian.ClassGrokker):
+    component_class = grok.View
+
+    def grok(self, name, factory, module_info, config, **kw):
+        view_context = get_context(module_info, factory)
+
+        factory.module_info = module_info
+
+        #if util.check_subclass(factory, components.GrokForm):
+            ## setup form_fields from context class if we've encountered a form
+            #if getattr(factory, 'form_fields', None) is None:
+                #factory.form_fields = formlib.get_auto_fields(view_context)
+
+            #if not getattr(factory.render, 'base_method', False):
+                #raise GrokError(
+                    #"It is not allowed to specify a custom 'render' "
+                    #"method for form %r. Forms either use the default "
+                    #"template or a custom-supplied one." % factory,
+                    #factory)
+
+        # find templates
+        templates = module_info.getAnnotation('grok.templates', None)
+        if templates is not None:
+            config.action(
+                discriminator=None,
+                callable=self.checkTemplates,
+                args=(templates, module_info, factory)
+            )
+
+        # safety belt: make sure that the programmer didn't use
+        # @grok.require on any of the view's methods.
+        methods = util.methods_from_class(factory)
+        for method in methods:
+            if getattr(method, '__grok_require__', None) is not None:
+                raise GrokError('The @grok.require decorator is used for '
+                                'method %r in view %r. It may only be used '
+                                'for XML-RPC methods.'
+                                % (method.__name__, factory), factory)
+
+        # grab layer from class or module
+        view_layer = determine_class_directive('grok.layer',
+                                               factory, module_info,
+                                               default=IDefaultBrowserLayer)
+
+        view_name = get_name_classname(factory)
+        # __view_name__ is needed to support IAbsoluteURL on views
+        factory.__view_name__ = view_name
+        adapts = (view_context, view_layer)
+
+        config.action(
+            discriminator=('adapter', adapts, interface.Interface, view_name),
+            callable=component.provideAdapter,
+            args=(factory, adapts, interface.Interface, view_name),
+            )
+
+        permission = get_default_permission(factory)
+        config.action(
+            discriminator=('protectName', factory, '__call__'),
+            callable=make_checker,
+            args=(factory, factory, permission),
+            )
+
+        return True
+
+    def checkTemplates(self, templates, module_info, factory):
+        def has_render(factory):
+            return (getattr(factory, 'render', None) and
+                    not util.check_subclass(factory, grok.components.GrokForm))
+        def has_no_render(factory):
+            return not getattr(factory, 'render', None)
+        templates.checkTemplates(module_info, factory, 'view',
+                                 has_render, has_no_render)


Property changes on: five.grokkers/trunk/five/grokkers/meta.py
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: five.grokkers/trunk/five/grokkers/tests/test_all.py
===================================================================
--- five.grokkers/trunk/five/grokkers/tests/test_all.py	2008-04-26 07:46:02 UTC (rev 85741)
+++ five.grokkers/trunk/five/grokkers/tests/test_all.py	2008-04-26 08:33:18 UTC (rev 85742)
@@ -4,11 +4,15 @@
 from zope.component import testing
 from Testing import ZopeTestCase
 from Products.Five import zcml
+import Products.Five
 import five.grokkers
 
 def setUp(test=None):
     testing.setUp(test)
+    zcml.load_config('meta.zcml', package=Products.Five)
+    zcml.load_config('configure.zcml', package=Products.Five)
     zcml.load_config('meta.zcml', package=five.grokkers)
+    zcml.load_config('configure.zcml', package=five.grokkers)
     zcml.load_config('configure.zcml', package=five.grokkers.tests)
 
 def test_suite():
@@ -27,9 +31,9 @@
             module='five.grokkers.tests.utilities',
             setUp=setUp, tearDown=testing.tearDown),
 
-        #doctestunit.DocTestSuite(
-            #module='five.grokkers.tests.views',
-            #setUp=setUp, tearDown=testing.tearDown),
+        doctestunit.DocTestSuite(
+            module='five.grokkers.tests.views',
+            setUp=setUp, tearDown=testing.tearDown),
             
         # Integration tests that use ZopeTestCase
         #ztc.ZopeDocFileSuite(

Modified: five.grokkers/trunk/five/grokkers/tests/utilities.py
===================================================================
--- five.grokkers/trunk/five/grokkers/tests/utilities.py	2008-04-26 07:46:02 UTC (rev 85741)
+++ five.grokkers/trunk/five/grokkers/tests/utilities.py	2008-04-26 08:33:18 UTC (rev 85742)
@@ -1,4 +1,4 @@
-"""Testing that grokcore adapters work under Zope2
+"""Testing that grokcore utilities work under Zope2
 
   >>> from zope import component
   >>> club = component.getUtility(IFiveClub, 'five_inch')

Added: five.grokkers/trunk/five/grokkers/tests/views.py
===================================================================
--- five.grokkers/trunk/five/grokkers/tests/views.py	                        (rev 0)
+++ five.grokkers/trunk/five/grokkers/tests/views.py	2008-04-26 08:33:18 UTC (rev 85742)
@@ -0,0 +1,28 @@
+"""Testing five.grokkers Views.
+
+  >>> from OFS.SimpleItem import SimpleItem
+  >>> item = SimpleItem()
+  >>> item.id = 'item'
+
+Setup a fake request:
+
+  >>> from zope.publisher.browser import TestRequest
+  >>> item.REQUEST = TestRequest()
+
+We should now be able to find the view:
+
+  >>> view = item.unrestrictedTraverse('@@theview')
+  >>> view()
+  'item'
+
+"""
+from five.grokkers import grok
+from OFS.interfaces import ISimpleItem
+
+class SimpleItemView(grok.View):
+    grok.context(ISimpleItem)
+    grok.name('theview')
+        
+    def __call__(self):
+        return self.context.getId()
+        
\ No newline at end of file


Property changes on: five.grokkers/trunk/five/grokkers/tests/views.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: five.grokkers/trunk/five/grokkers/util.py
===================================================================
--- five.grokkers/trunk/five/grokkers/util.py	                        (rev 0)
+++ five.grokkers/trunk/five/grokkers/util.py	2008-04-26 08:33:18 UTC (rev 85742)
@@ -0,0 +1,61 @@
+import urllib
+
+import zope.location.location
+from zope import component
+from zope.traversing.browser.interfaces import IAbsoluteURL
+from zope.traversing.browser.absoluteurl import _safe as SAFE_URL_CHARACTERS
+
+from zope.security.checker import NamesChecker, defineChecker
+from zope.security.interfaces import IPermission
+
+from martian.error import GrokError, GrokImportError
+from martian.util import class_annotation, methods_from_class, scan_for_classes
+
+def check_adapts(class_):
+    if component.adaptedBy(class_) is None:
+        raise GrokError("%r must specify which contexts it adapts "
+                        "(use grok.adapts to specify)."
+                        % class_, class_)
+
+def make_checker(factory, view_factory, permission, method_names=None):
+    """Make a checker for a view_factory associated with factory.
+
+    These could be one and the same for normal views, or different
+    in case we make method-based views such as for JSON and XMLRPC.
+    """
+    if method_names is None:
+        method_names = ['__call__']
+    if permission is not None:
+        check_permission(factory, permission)
+    if permission is None or permission == 'zope.Public':
+        checker = NamesChecker(method_names)
+    else:
+        checker = NamesChecker(method_names, permission)
+    defineChecker(view_factory, checker)
+
+def check_permission(factory, permission):
+    """Check whether a permission is defined.
+
+    If not, raise error for factory.
+    """
+    if component.queryUtility(IPermission,
+                              name=permission) is None:
+       raise GrokError('Undefined permission %r in %r. Use '
+                       'grok.Permission first.'
+                       % (permission, factory), factory)
+
+def get_default_permission(factory):
+    """Determine the default permission for a view.
+
+    There can be only 0 or 1 default permission.
+    """
+    permissions = class_annotation(factory, 'grok.require', [])
+    if not permissions:
+        return None
+    if len(permissions) > 1:
+        raise GrokError('grok.require was called multiple times in '
+                        '%r. It may only be set once for a class.'
+                        % factory, factory)
+
+    result = permissions[0]
+    return result
\ No newline at end of file


Property changes on: five.grokkers/trunk/five/grokkers/util.py
___________________________________________________________________
Name: svn:keywords
   + Id



More information about the Checkins mailing list