[z3-checkins] r8674 - z3/Five/branch/menu_refactoring

regebro at codespeak.net regebro at codespeak.net
Fri Jan 28 18:44:57 MET 2005


Author: regebro
Date: Fri Jan 28 18:44:56 2005
New Revision: 8674

Removed:
   z3/Five/branch/menu_refactoring/globalbrowsermenuservice.py
Modified:
   z3/Five/branch/menu_refactoring/browserconfigure.py
   z3/Five/branch/menu_refactoring/meta.zcml
   z3/Five/branch/menu_refactoring/traversable.py
Log:
Refactoring the menu support to use Zope3s native support. Requires a monkey-patch, but it MUCH cleaner otherwise.

Modified: z3/Five/branch/menu_refactoring/browserconfigure.py
==============================================================================
--- z3/Five/branch/menu_refactoring/browserconfigure.py	(original)
+++ z3/Five/branch/menu_refactoring/browserconfigure.py	Fri Jan 28 18:44:56 2005
@@ -23,6 +23,7 @@
 from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
 from zope.app.pagetemplate.viewpagetemplatefile import ViewMapper
 from zope.app.publisher.browser.viewmeta import pages as zope_app_pages
+from zope.app.publisher.browser.globalbrowsermenuservice import menuItemDirective
 from zope.app.component.metaconfigure import handler
 from zope.app.component.interface import provideInterface
 from zope.app.form.browser.metaconfigure import BaseFormDirective
@@ -33,7 +34,6 @@
 from browser import BrowserView, EditView
 from metaclass import makeClass
 from security import getSecurityInfo, protectClass, protectName, initializeClass
-from globalbrowsermenuservice import menuItemDirective
 
 class FivePageTemplateFile(ViewPageTemplateFile):
 

Deleted: /z3/Five/branch/menu_refactoring/globalbrowsermenuservice.py
==============================================================================
--- /z3/Five/branch/menu_refactoring/globalbrowsermenuservice.py	Fri Jan 28 18:44:56 2005
+++ (empty file)
@@ -1,242 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.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.
-#
-##############################################################################
-"""Global Browser Menu Service
-
-$Id: globalbrowsermenuservice.py 27079 2004-08-12 19:45:55Z srichter $
-"""
-import sys
-from zope.exceptions import DuplicationError
-from zope.security.interfaces import Unauthorized, Forbidden
-from zope.interface import implements, implementedBy
-from zope.security.checker import CheckerPublic
-from security import checkPermission
-from zope.app.component.metaconfigure import handler
-from zope.app.publisher.interfaces.browser import IBrowserMenuService
-from zope.app.publisher.interfaces.browser import IGlobalBrowserMenuService
-from zope.app.publisher.interfaces.browser import IBrowserMenu
-from zope.app.publisher.browser import BrowserView
-from zope.app.pagetemplate.engine import Engine
-from zope.app.publication.browser import PublicationTraverser
-from zope.security.proxy import ProxyFactory
-from zope.app import zapi
-from zope.app.component.interface import provideInterface
-from zope.app.servicenames import BrowserMenu
-
-# TODO: This was copied and trimmed down from zope.interface.
-# Eventually, this will be eliminated when the browser menu
-# service is changed to use adapters.
-from zope.interface.interfaces import IInterface
-from zope.interface import providedBy
-import types
-
-from zope.app.publisher.browser.globalbrowsermenuservice import \
-    Menu, MenuItem
-
-
-class BaseBrowserMenuService(object):
-    """Global Browser Menu Service"""
-
-    implements(IBrowserMenuService)
-
-    def __init__(self):
-        self._registry = {}
-
-    def getAllMenuItems(self, menu_id, object):
-        return self._registry[menu_id].getMenuItems(object)
-
-    def getMenu(self, menu_id, object, request, max=999999):
-        traverser = PublicationTraverser()
-
-        result = []
-        seen = {}
-        # stuff for figuring out the selected view
-        request_url = request.URL # Diff
-
-        for item in self.getAllMenuItems(menu_id, object):
-            # Make sure we don't repeat a specification for a given title
-            title = item.title
-            if title in seen:
-                continue
-            seen[title] = 1
-
-            if item.filter is not None:
-
-                try:
-                    include = item.filter(Engine.getContext(
-                        context = object,
-                        nothing = None,
-                        request = request,
-                        modules = ProxyFactory(sys.modules),
-                        ))
-                except Unauthorized:
-                    include = 0
-
-                if not include:
-                    continue
-
-            permission = item.permission
-            action = item.action
-
-            if permission:
-                # If we have an explicit permission, check that we
-                # can access it.
-                if not checkPermission(permission, object):
-                    continue
-
-            elif action:
-                # Otherwise, test access by attempting access
-                path = action
-                l = action.find('?')
-                if l >= 0:
-                   path = action[:l]
-                try:
-                    path = str(path)
-                    v = object.restrictedTraverse(path)
-                    # TODO:
-                    # tickle the security proxy's checker
-                    # we're assuming that view pages are callable
-                    # this is a pretty sound assumption
-                    #v.__call__
-                except (Unauthorized, Forbidden):
-                    continue # Skip unauthorized or forbidden
-
-            normalized_action = action
-            if action.startswith('@@'):
-                normalized_action = action[2:]
-
-            if request_url.endswith('/'+normalized_action):
-                selected='selected'
-            elif request_url.endswith('/++view++'+normalized_action):
-                selected='selected'
-            elif request_url.endswith('/@@'+normalized_action):
-                selected='selected'
-            else:
-                selected=''
-
-            result.append({
-                'title': title,
-                'description': item.description,
-                'action': "%s" % action,
-                'selected': selected,
-                'extra': item.extra,
-                })
-
-            if len(result) >= max:
-                return result
-        return result
-
-    def getFirstMenuItem(self, menu_id, object, request):
-        r = self.getMenu(menu_id, object, request, max=1)
-        if r:
-            return r[0]
-        return None
-
-
-class GlobalBrowserMenuService(BaseBrowserMenuService):
-    """Global Browser Menu Service that can be manipulated by adding new menus
-    and menu entries."""
-
-    implements(IGlobalBrowserMenuService)
-
-    def __init__(self):
-        self._registry = {}
-
-    _clear = __init__
-
-    def menu(self, menu_id, title, description=u''):
-        s = zapi.getGlobalService(zapi.servicenames.Presentation)
-        if menu_id in self._registry:
-            raise DuplicationError("Menu %s is already defined." % menu_id)
-
-        self._registry[menu_id] = Menu(title, description)
-
-    def menuItem(self, menu_id, interface, action, title,
-                 description='', filter_string=None, permission=None,
-                 extra=None,
-                 ):
-
-        registry = self._registry[menu_id].registry
-
-        if filter_string:
-            filter = Engine.compile(filter_string)
-        else:
-            filter = None
-
-        if permission:
-            if permission == 'zope.Public':
-                permission = CheckerPublic
-
-
-        if interface is not None and not IInterface.providedBy(interface):
-            if isinstance(interface, (type, types.ClassType)):
-                interface = implementedBy(interface)
-            else:
-                raise TypeError(
-                    "The interface argument must be an interface (or None) "
-                    "or a class.")
-
-        data = registry.get(interface) or []
-        data.append(
-            MenuItem(action, title, description, filter, permission, extra)
-            )
-        registry.register(interface, data)
-
-
-def menuDirective(_context, id, title, description=''):
-    _context.action(
-        discriminator = ('browser:menu', id),
-        callable = globalBrowserMenuService.menu,
-        args = (id, title, description),
-        )
-
-def menuItemDirective(_context, menu, for_,
-                      action, title, description='', filter=None,
-                      permission=None, extra=None):
-    return menuItemsDirective(_context, menu, for_).menuItem(
-        _context, action, title, description, filter, permission, extra)
-
-
-class menuItemsDirective(object):
-
-    def __init__(self, _context, menu, for_):
-        self.interface = for_
-        self.menu = menu
-
-    def menuItem(self, _context, action, title, description='',
-                 filter=None, permission=None, extra=None):
-        _context.action(
-            discriminator = ('browser:menuItem',
-                             self.menu, self.interface, title),
-            callable = globalBrowserMenuService.menuItem,
-            args = (self.menu, self.interface,
-                    action, title, description, filter, permission, extra),
-            ),
-
-    def __call__(self, _context):
-        _context.action(
-            discriminator = None,
-            callable = provideInterface,
-            args = (self.interface.__module__+'.'+self.interface.getName(),
-                    self.interface)
-            )
-
-
-globalBrowserMenuService = GlobalBrowserMenuService()
-
-_clear = globalBrowserMenuService._clear
-
-# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
-from zope.testing.cleanup import addCleanUp
-addCleanUp(_clear)
-del addCleanUp

Modified: z3/Five/branch/menu_refactoring/meta.zcml
==============================================================================
--- z3/Five/branch/menu_refactoring/meta.zcml	(original)
+++ z3/Five/branch/menu_refactoring/meta.zcml	Fri Jan 28 18:44:56 2005
@@ -143,19 +143,19 @@
     <meta:directive
         name="menu"
         schema="zope.app.publisher.browser.metadirectives.IMenuDirective"
-        handler=".globalbrowsermenuservice.menuDirective"
+        handler="zope.app.publisher.browser.globalbrowsermenuservice.menuDirective"
         />
 
     <meta:directive
         name="menuItem"
         schema="zope.app.publisher.browser.metadirectives.IMenuItemDirective"
-        handler=".globalbrowsermenuservice.menuItemDirective"
+        handler="zope.app.publisher.browser.globalbrowsermenuservice.menuItemDirective"
         />
 
     <meta:complexDirective
         name="menuItems"
         schema="zope.app.publisher.browser.metadirectives.IMenuItemsDirective"
-        handler=".globalbrowsermenuservice.menuItemsDirective"
+        handler="zope.app.publisher.browser.globalbrowsermenuservice.menuItemsDirective"
         >
 
       <meta:subdirective

Modified: z3/Five/branch/menu_refactoring/traversable.py
==============================================================================
--- z3/Five/branch/menu_refactoring/traversable.py	(original)
+++ z3/Five/branch/menu_refactoring/traversable.py	Fri Jan 28 18:44:56 2005
@@ -20,6 +20,9 @@
 from zope.app.traversing.adapters import traversePathElement
 from monkey import DebugFlags
 
+from zope.security.management import thread_local
+from AccessControl import ClassSecurityInfo, getSecurityManager
+
 _marker = object
 
 class FakeRequest:
@@ -33,6 +36,10 @@
     def has_key(self, key):
         return False
 
+def newInteraction():
+    if getattr(thread_local, 'interaction', None) is None:
+        thread_local.interaction = getSecurityManager()
+
 class Traversable:
     """A mixin to make an object traversable using an ITraverser adapter.
     """
@@ -61,6 +68,8 @@
             REQUEST = getattr(self, 'REQUEST', None)
             if not IBrowserRequest.providedBy(REQUEST):
                 REQUEST = FakeRequest()
+
+        newInteraction()
         try:
             kw = dict(path=[name], request=REQUEST)
             return ITraverser(self).traverse(**kw).__of__(self)


More information about the z3-checkins mailing list