All pastes #792325 Raw Edit

ploneview.py

public python v1 · immutable
·published 2007-11-21 09:16 UTC
rendered paste body
from urllib import unquotefrom Acquisition import aq_innerfrom Products.Five import BrowserViewfrom Products.CMFCore.permissions import AddPortalContentfrom Products.CMFCore.permissions import DeleteObjectsfrom Products.CMFCore.permissions import ListFolderContentsfrom Products.CMFCore.permissions import ModifyPortalContentfrom Products.CMFCore.permissions import ReviewPortalContentfrom Products.CMFCore.utils import _checkPermissionfrom Products.CMFCore.utils import getToolByNamefrom Products.CMFPlone import utilsfrom Products.CMFPlone.browser.interfaces import IPlonefrom Products.CMFPlone.interfaces import ITranslationServiceToolfrom zope.deprecation import deprecate, deprecatedfrom zope.interface import implements, alsoProvidesfrom zope.component import getMultiAdapter, queryMultiAdapter, getUtilityimport ZTUtilsimport sysfrom plone.memoize.view import memoizefrom plone.portlets.interfaces import IPortletManager, IPortletManagerRendererfrom plone.app.layout.globals.interfaces import IViewViewfrom plone.app.layout.icons.interfaces import IContentIconfrom plone.app.content.browser.folderfactories import _allowedTypesdeprecated(    ('IndexIterator'),    "This reference to IndexIterator will be removed in Plone 3.5. Please "    "import it from Products.CMFPlone.utils instead.")IndexIterator = utils.IndexIterator_marker = []import zope.deferredimportzope.deferredimport.deprecated(    "It has been replaced by plone.memoize.instance.memoize. This alias will "     "be removed in Plone 3.5.",    cache_decorator = 'plone.memoize.instance:memoize',    )class Plone(BrowserView):    implements(IPlone)    def globalize(self):        """        Pure optimization hack, globalizes entire view for speed. Yes        it's evil, but this hack will eventually be removed after        globals are officially deprecated.        YOU CAN ONLY CALL THIS METHOD FROM A PAGE TEMPLATE AND EVEN        THEN IT MIGHT DESTROY YOU!        """        context = sys._getframe(2).f_locals['econtext']        # Some of the original global_defines used 'options' to get parameters        # passed in through the template call, so we need this to support        # products which may have used this little hack        options = context.vars.get('options',{})        view = context.vars.get('view', None)        template = context.vars.get('template', None)        state = {}        self._initializeData(options=options, view=view, template=template)        for name, v in self._data.items():            state[name] = v            context.setGlobal(name, v)    def __init__(self, context, request):        super(Plone, self).__init__(context, request)        self._data = {}    def _initializeData(self, options=None, view=None, template=None):        # We don't want to do this in __init__ because the view provides        # methods which are useful outside of globals.  Also, performing        # actions during __init__ is dangerous because instances are usually        # created during traversal, which means authentication hasn't yet        # happened.        context = aq_inner(self.context)        if options is None:            options = {}        if view is None:            view = self        show_portlets = not options.get('no_portlets', False)        def_actions = options.get('actions', None)        # XXX: Can't store data as attributes directly because it will        # insert the view into the acquisition chain. Someone should        # come up with a way to prevent this or get rid of the globals        # view altogether        tools = getMultiAdapter((context, self.request), name=u'plone_tools')        portal_state = getMultiAdapter((context, self.request), name=u'plone_portal_state')        context_state = getMultiAdapter((context, self.request), name=u'plone_context_state')        self._data['utool'] = utool = tools.url()        self._data['portal'] = portal = portal_state.portal()        self._data['portal_url'] =  portal_state.portal_url()        self._data['mtool'] = mtool = tools.membership()        self._data['atool'] = atool = tools.actions()        self._data['putils'] = putils = getToolByName(context, "plone_utils")        self._data['acl_users'] = getToolByName(context, 'acl_users')        self._data['wtool'] = wtool = tools.workflow()        self._data['ifacetool'] = tools.interface()        self._data['syntool'] = tools.syndication()        self._data['portal_title'] = portal_state.portal_title()        self._data['object_title'] = context_state.object_title()        self._data['checkPermission'] = checkPermission = mtool.checkPermission        self._data['member'] = portal_state.member()        self._data['membersfolder'] =  mtool.getMembersFolder()        self._data['isAnon'] =  portal_state.anonymous()        self._data['actions'] = actions = def_actions or context_state.actions()        self._data['keyed_actions'] =  def_actions or context_state.keyed_actions()        self._data['user_actions'] =  actions['user']        self._data['workflow_actions'] =  actions['workflow']        self._data['folder_actions'] =  actions['folder']        self._data['global_actions'] =  actions['global']        portal_tabs_view = getMultiAdapter((context, context.REQUEST), name='portal_tabs_view')        self._data['portal_tabs'] =  portal_tabs_view.topLevelTabs(actions=actions)        self._data['wf_state'] =  context_state.workflow_state()        self._data['portal_properties'] = props = tools.properties()        self._data['site_properties'] = site_props = props.site_properties        self._data['ztu'] =  ZTUtils        self._data['isFolderish'] =  context_state.is_folderish()                self._data['sl'] = have_left_portlets = show_portlets and self.have_portlets('plone.leftcolumn', view)        self._data['sr'] = have_right_portlets = show_portlets and self.have_portlets('plone.rightcolumn', view)        self._data['hidecolumns'] =  self.hide_columns(have_left_portlets, have_right_portlets)                self._data['here_url'] =  context_state.object_url()        self._data['default_language'] = portal_state.default_language()        self._data['language'] =  portal_state.language()        self._data['is_editable'] = context_state.is_editable()        self._data['isLocked'] = context_state.is_locked()        self._data['isRTL'] =  portal_state.is_rtl()        self._data['visible_ids'] =  self.visibleIdsEnabled() or None        self._data['current_page_url'] =  context_state.current_page_url()        self._data['normalizeString'] = putils.normalizeString        self._data['toLocalizedTime'] = self.toLocalizedTime        self._data['isStructuralFolder'] = context_state.is_structural_folder()        self._data['isContextDefaultPage'] = context_state.is_default_page()        self._data['navigation_root_url'] = portal_state.navigation_root_url()        self._data['Iterator'] = utils.IndexIterator        self._data['tabindex'] = utils.IndexIterator(pos=30000, mainSlot=False)        self._data['uniqueItemIndex'] = utils.RealIndexIterator(pos=0)        template_id = options.get('template_id', None)        if template_id is None and template is not None:            template_id = template.getId()        self._data['template_id'] = template_id                isViewTemplate = context_state.is_view_template()        if isViewTemplate and not IViewView.providedBy(view):            # Mark the view as being "the" view            alsoProvides(view, IViewView)                    self._data['isViewTemplate'] = isViewTemplate    # XXX: This is lame    def hide_columns(self, column_left, column_right):        if not column_right and not column_left:            return "visualColumnHideOneTwo"        if column_right and not column_left:            return "visualColumnHideOne"        if not column_right and column_left:            return "visualColumnHideTwo"        return "visualColumnHideNone"    # Utility methods        def toLocalizedTime(self, time, long_format=None):        """Convert time to localized time        """        context = aq_inner(self.context)        util = getToolByName(context, 'translation_service')        return util.ulocalized_time(time, long_format, context=context,                                    domain='plonelocales', request=self.request)        @memoize    def visibleIdsEnabled(self):        """Determine if visible ids are enabled        """        context = aq_inner(self.context)        props = getToolByName(context, "portal_properties").site_properties        if not props.getProperty('visible_ids', False):            return False        pm = getToolByName(context, "portal_membership")        if pm.isAnonymousUser():            return False        user = pm.getAuthenticatedMember()        if user is not None:            return user.getProperty('visible_ids', False)        return False        @memoize    def prepareObjectTabs(self, default_tab='view', sort_first=frozenset(['folderContents'])):        """Prepare the object tabs by determining their order and working        out which tab is selected. Used in global_contentviews.pt        """        context = aq_inner(self.context)        context_url = context.absolute_url()        context_fti = context.getTypeInfo()                site_properties = getToolByName(context, "portal_properties").site_properties        context_state = getMultiAdapter((context, self.request), name=u'plone_context_state')        actions = context_state.actions()        action_list = []        if context_state.is_structural_folder():            action_list = actions['folder'] + actions['object']        else:            action_list = actions['object']        first_tabs = []        tabs = []                found_selected = False        fallback_action = None        request_url = self.request['ACTUAL_URL']        request_url_path = request_url[len(context_url):]                if request_url_path.startswith('/'):            request_url_path = request_url_path[1:]        for action in action_list:                        item = {'title'    : action['title'],                    'id'       : action['id'],                    'url'      : '',                    'selected' : False}            action_url = action['url'].strip()            if action_url.startswith('http') or action_url.startswith('javascript'):                item['url'] = action_url            else:                item['url'] = '%s/%s'%(context_url, action_url)            action_method = item['url'].split('/')[-1]            # Action method may be a method alias: Attempt to resolve to a template.            action_method = context_fti.queryMethodID(action_method, default=action_method)            if action_method:                request_action = unquote(request_url_path)                request_action = context_fti.queryMethodID(request_action, default=request_action)                    if action_method == request_action:                    item['selected'] = True                    found_selected = True            current_id = item['id']            if current_id == default_tab:                fallback_action = item            if current_id in sort_first:                first_tabs.append(item)            else:                tabs.append(item)        if not found_selected and fallback_action is not None:            fallback_action['selected'] = True        return first_tabs + tabs    # XXX: This can't be request-memoized, because it won't necessarily remain    # valid across traversals. For example, you may get tabs on an error     # message. :)    #     # @memoize    def showEditableBorder(self):        """Determine if the editable border should be shown        """        request = self.request                if request.has_key('disable_border'): #short circuit            return False        if request.has_key('enable_border'): #short circuit            return True                context = aq_inner(self.context)                portal_membership = getToolByName(context, 'portal_membership')        checkPerm = portal_membership.checkPermission        if checkPerm('Modify portal content', context) or \               checkPerm('Add portal content', context)  or \               checkPerm('Review portal content', context):            return True        if portal_membership.isAnonymousUser():            return False        context_state = getMultiAdapter((context, request), name="plone_context_state")        actions = context_state.actions()                    if actions.get('workflow', ()):            return True        if actions.get('batch', []):            return True                    for action in actions.get('object', []):            if action.get('id', '') != 'view':                return True        template_id = self._data.get('template_id', None)        if template_id is None and 'PUBLISHED' in request:            if hasattr(request['PUBLISHED'], 'getId'):                template_id=request['PUBLISHED'].getId()        idActions = {}        for obj in actions.get('object', ()) + actions.get('folder', ()):            idActions[obj.get('id', '')] = 1        if idActions.has_key('edit'):            if (idActions.has_key(template_id) or \                template_id in ['synPropertiesForm', 'folder_contents', 'folder_listing']) :                return True        # Check to see if the user is able to add content or change workflow state        if _allowedTypes(request, context):            return True        return False        @memoize    def displayContentsTab(self):        """Whether or not the contents tabs should be displayed        """        context = aq_inner(self.context)        modification_permissions = (ModifyPortalContent,                                    AddPortalContent,                                    DeleteObjects,                                    ReviewPortalContent)        contents_object = context        # If this object is the parent folder's default page, then the        # folder_contents action is for the parent, we check permissions        # there. Otherwise, if the object is not folderish, we don not display        # the tab.        if self.isDefaultPageInFolder():            contents_object = self.getCurrentFolder()        elif not self.isStructuralFolder():            return 0        # If this is not a structural folder, stop.        plone_view = getMultiAdapter((contents_object, self.request),                                     name='plone')        if not plone_view.isStructuralFolder():            return 0        show = 0        # We only want to show the 'contents' action under the following        # conditions:        # - If you have permission to list the contents of the relavant        #   object, and you can DO SOMETHING in a folder_contents view. i.e.        #   Copy or Move, or Modify portal content, Add portal content,        #   or Delete objects.        # Require 'List folder contents' on the current object        if _checkPermission(ListFolderContents, contents_object):            # If any modifications are allowed on object show the tab.            for permission in modification_permissions:                if _checkPermission(permission, contents_object):                    show = 1                    break        return show    @memoize    def icons_visible(self):        context = aq_inner(self.context)        membership = getToolByName(context, "portal_membership")        properties = getToolByName(context, "portal_properties")        site_properties = getattr(properties, 'site_properties')        icon_visibility = site_properties.getProperty('icon_visibility', 'enabled')        if icon_visibility == 'enabled':            return True        elif icon_visibility == 'authenticated' and not membership.isAnonymousUser():            return True        else:            return False    def getIcon(self, item):        """Returns an object which implements the IContentIcon interface and           provides the informations necessary to render an icon.           The item parameter needs to be adaptable to IContentIcon.           Icons can be disabled globally or just for anonymous users with           the icon_visibility property in site_properties."""        context = aq_inner(self.context)        if not self.icons_visible():            icon = getMultiAdapter((context, self.request, None), IContentIcon)        else:            icon = getMultiAdapter((context, self.request, item), IContentIcon)        return icon    def normalizeString(self, text, relaxed=False):        """Normalizes a title to an id.        """        return utils.normalizeString(text, context=self, relaxed=relaxed)    def cropText(self, text, length, ellipsis='...'):        """Crop text on a word boundary        """        converted = False        if not isinstance(text, unicode):            encoding = utils.getSiteEncoding(aq_inner(self.context))            text = unicode(text, encoding)            converted = True        if len(text)>length:            text = text[:length]            l = text.rfind(' ')            if l > length/2:                text = text[:l+1]            text += ellipsis        if converted:            # encode back from unicode            text = text.encode(encoding)        return text    # Deprecated in favour of the @@plone_context_state and @@plone_portal_state views    @deprecate("The keyFilteredActions method of the Plone view has been "               "deprecated and will be removed in Plone 3.5. Use the "               "keyed_actions method of the plone_context_state adapter "               "instead.")    def keyFilteredActions(self, actions=None):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.keyed_actions()    def getCurrentUrl(self):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.current_page_url()    @deprecate("The isRightToLeft method of the Plone view has been "               "deprecated and will be removed in Plone 3.5. Use the "               "is_rtl method of the plone_portal_state adapter instead.")    def isRightToLeft(self, domain='plone'):        portal_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_portal_state')        return portal_state.is_rtl()    def isDefaultPageInFolder(self):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.is_default_page()    def isStructuralFolder(self):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.is_structural_folder()    def navigationRootPath(self):        portal_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_portal_state')        return portal_state.navigation_root_path()    def navigationRootUrl(self):        portal_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_portal_state')        return portal_state.navigation_root_url()    def getParentObject(self):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.parent()    def getCurrentFolder(self):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.folder()    def getCurrentFolderUrl(self):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.folder().absolute_url()    @memoize    def getCurrentObjectUrl(self):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.canonical_object_url()    @memoize    def isFolderOrFolderDefaultPage(self):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.is_structural_folder() or context_state.is_default_page()    @memoize    def isPortalOrPortalDefaultPage(self):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.is_portal_root()            @memoize    def getViewTemplateId(self):        context_state = getMultiAdapter((aq_inner(self.context), self.request), name=u'plone_context_state')        return context_state.view_template_id()    # Helper methods    def have_portlets(self, manager_name, view=None):        """Determine whether a column should be shown.        The left column is called plone.leftcolumn; the right column is called        plone.rightcolumn. Custom skins may have more portlet managers defined        (see portlets.xml).        """                context = aq_inner(self.context)        if view is None:            view = self        manager = getUtility(IPortletManager, name=manager_name)        renderer = queryMultiAdapter((context, self.request, view, manager), IPortletManagerRenderer)        if renderer is None:            renderer = getMultiAdapter((context, self.request, self, manager), IPortletManagerRenderer)        return renderer.visible