# Flon is a package for enabling hand picked Five features in Plone # Copyright (C) 2004 Enfold Systems, LLC # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ $Id: __init__.py,v 1.2 2004/07/14 22:23:16 dreamcatcher Exp $ """ from Acquisition import aq_base from Products.Five.browser import BrowserView from Products.Five.viewable import BrowserDefault as BaseDefault, IBrowserDefault from Products.CMFCore.utils import getToolByName from Products.Flon.interfaces import IDynamicType from zope.component import getView, ComponentLookupError from zope.app.apidoc.viewmodule.browser import SkinLayer as _SkinLayer from zope.app.apidoc.viewmodule.browser import ViewsDetails as _ViewsDetails class SkinLayer(BrowserView): getSkins = _SkinLayer.getSkins.im_func class ViewsDetails(BrowserView): __init__ = _ViewsDetails.__init__.im_func getViewsByLayers = _ViewsDetails.getViewsByLayers.im_func class DirectlyProvided(BrowserView): def __call__(self): it = getToolByName(self.context, 'portal_interface') return it.getDirectlyProvidedNames(self.context) class Provided(BrowserView): def __call__(self): it = getToolByName(self.context, 'portal_interface') return it.getProvidedNames(self.context) class BrowserDefault(BaseDefault): def defaultView(self, request): context = self.context # Try to detect if it's a WebDAV request, and if # so, return immediately. if request and request.has_key('REQUEST_METHOD'): if request['REQUEST_METHOD'] not in ['GET', 'HEAD', 'POST']: return context, [request['REQUEST_METHOD']] # Use plone_utils tool for finding browserDefault putils = getToolByName(context, 'plone_utils', None) plone_context, plone_path = context, None if putils is not None: plone_context, plone_path = putils.browserDefault(context) ids = {} if hasattr(aq_base(plone_context), 'has_key'): ids = plone_context else: for id in plone_context.objectIds(): ids[id] = None for id in dir(plone_context): ids[id] = None # If it's an object inside the current folder, then # return immediatly. This is so we can override the # defaultView with index_html. if plone_path: if len(plone_path) == 1 and ids.has_key(plone_path[0]): return plone_context, plone_path # Otherwise, try to find a defaultView. context, path = super(BrowserDefault, self).defaultView(request) if path and len(path) == 1: try: getView(context, path[0], request) except ComponentLookupError: pass else: return context, path action = getActionFor(context) if action is not None: return context, action # If the defaultView is not found, return None # and let the fallback method take his chance. return plone_context, None # The method below is highly based on CMFCore._utils._getViewFor, # however instead of traversing to a view, it does return the # name to be used by browserDefault from Products.CMFCore.utils import getActionContext, _verifyActionPermissions def getActionFor(obj, view='view'): obj = IDynamicType(obj, None) if obj is None: return None ti = obj.getTypeInfo() if ti is not None: context = getActionContext(obj) actions = ti.listActions() d_actions = dict([(a.getId(), a) for a in actions]) v_action = d_actions.get(view, None) if v_action is not None: if _verifyActionPermissions(obj, v_action): return extractAction(context, v_action, obj) # "view" action is not present or not allowed. # Find something that's allowed. for action in d_actions.values(): if _verifyActionPermissions(obj, action): return extractAction(context, action, obj) return None def extractAction(context, action, obj): target = action.action(context).strip() __traceback_info__ = (action, target) if target.startswith('/'): target = target[1:] obj_url = obj.absolute_url() if target.startswith(obj_url): target = target[len(obj_url):] if not target: return None return target.split('/')