Source code for ploneintranet.workspace.browser.tiles.workspaces

# -*- coding: utf-8 -*-
from Acquisition import aq_parent
from logging import getLogger
from plone import api
from plone.memoize import ram
from ploneintranet.layout.memoize.view import memoize
from ploneintranet.layout.memoize.view import memoize_contextless
from plone.tiles import Tile
from ploneintranet.core import ploneintranetCoreMessageFactory as _
from ploneintranet.layout.utils import shorten
from ploneintranet.workspace.interfaces import IWorkspaceFolder
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from time import time
from urllib import urlencode
from zc.relation.interfaces import ICatalog
from zope.component import getUtility
from zope.interface import implementer
from zope.interface import Interface


logger = getLogger(__name__)


[docs]@implementer(Interface) class AdaptableWSDict(object): def __init__(self, ws_dict): """ Transforms a dict in to a traversable object """ self.ws_dict = ws_dict
[docs] def UID(self): return self.ws_dict["uid"]
[docs] def absolute_url(self): return self.ws_dict["url"]
def __getattribute__(self, value): """ """ if value != "ws_dict" and value in self.ws_dict: return self.ws_dict[value] return super(AdaptableWSDict, self).__getattribute__(value)
[docs]class WorkspacesTile(Tile): index = ViewPageTemplateFile("templates/workspaces.pt") @property @memoize def available_workspace_types(self): """ The workspace types defined in the registry """ workspace_type_filters = api.portal.get_registry_record( "ploneintranet.workspace.workspace_type_filters" ) return workspace_type_filters.keys() @property @memoize def workspace_type(self): """ A tile should show either Workspacefolders or Cases, not both. """ return self.request.form.get("workspace_type", self.available_workspace_types) @property def title(self): """ The tile title. If we have an homonymous request parameter, use it Otherwise return a default based on the workspace type """ title = self.request.form.get("title", "") if title: return _(title) workspace_type = self.workspace_type if isinstance(workspace_type, basestring): return _("tile_" + workspace_type) return _("tile_workspaces_default_tile", u"Workspaces") @property @memoize def workspace_container(self): """ The object we are looking workspaces in """ portal = api.portal.get() workspace_path = self.request.form.get("workspace_path", "workspaces") return portal.get(workspace_path) @property def workspaces_url(self): """ The URL to get to the workspaces overview Add the workspace_type parameter if it is a string """ workspaces_url = self.workspace_container.absolute_url() workspace_type = self.workspace_type if not isinstance(workspace_type, basestring): return workspaces_url return "{workspaces_url}/?workspace_type={workspace_type}".format( workspaces_url=workspaces_url, workspace_type=workspace_type )
[docs] def shorten(self, text, length=60): return shorten(text, length)
[docs] @memoize def workspaces(self): """ The list of my workspaces """ view = api.content.get_view( "workspaces.html", self.workspace_container, self.request ) return view.workspaces()
[docs]class WorkspaceTile(Tile): index = ViewPageTemplateFile("templates/workspace.tile.pt")
[docs] def shorten(self, text, length=60): return shorten(text, length)
@property @memoize def tile_uid(self): """ return the tile uid """ return self.context.UID()[:6] @property @memoize_contextless def plone_view(self): """ The plone_view called in the context of the portal """ return api.content.get_view("plone", api.portal.get(), self.request) @property @memoize_contextless def workspace_type_mapping(self): """ Return the mapping between workspace types and css types as defined in the registry record ploneintranet.workspace.workspace_types_css_mapping """ workspace_types_css_mapping = api.portal.get_registry_record( "ploneintranet.workspace.workspace_types_css_mapping", default="ploneintranet.workspace.case|type-case", ) css_mapping = dict( line.partition("|")[::2] for line in workspace_types_css_mapping ) return css_mapping @property def workspace_type(self): """ Return, if found the workspace type mapping """ return self.workspace_type_mapping.get(self.context.portal_type, "workspace")
[docs] def get_css_classes(self): """ Return the css classes for this tile """ classes = [ "workspace-" + self.context.id.replace(".", "-"), getattr(self.context, "class", ""), self.workspace_type, ] if self.context.division and self.context.division in self._division_ids: classes.append("division-" + self._division_ids[self.context.division]) if getattr(self.context, "is_division", False): classes.append("division-name-{0} division-{0}".format(self.context.id)) if getattr(self.context, "is_archived", False) or getattr( self.context, "archival_date", False ): classes.append("state-archived") return " ".join(classes)
@property @memoize_contextless def _division_ids(self): """ cached mapping of division uids to ids to not need to query catalog for each workspace tile with a division """ brains = api.content.find(is_division=True, object_provides=IWorkspaceFolder) return {brain.UID: brain.id for brain in brains}
[docs] @memoize def is_superspace(self): return "superspace" in self.context.portal_type
[docs] @memoize def is_expandable(self): """ Check if the tile can be expanded to show subspaces """ # Only superspaces may be expanded if not self.is_superspace(): return False # We do not want wo expand superspaces in the bookmark tile if "@@bookmarks.workspaces.tile" in self.request.getURL(): return False # We do not want wo expand superspaces in the bookmark app orig_env = getattr(self.request, "_orig_env", {}) if "@@app-bookmarks" in orig_env.get("PATH_TRANSLATED"): return False return True
[docs] @ram.cache(lambda *args: time() // 30) def subspace_uids(self): """ A subspace has a superspace assigned to it. """ relcatalog = getUtility(ICatalog) rels = relcatalog.findRelations({"from_attribute": "superspace"}) with api.env.adopt_roles(["Manager"]): objs = [rel.from_object for rel in rels] return [obj.UID() for obj in objs if obj]
@property @memoize def workspaces_view(self): """ Return the workspace container view """ if isinstance(self.context, AdaptableWSDict): context = aq_parent(self.context.item.getObject()) else: context = aq_parent(self.context) if not context: context = api.portal.get()["workspaces"] return api.content.get_view("workspaces.html", context, self.request)
[docs] @memoize def superspace_qs(self): """ Format the qs for superspaces in order to properly expand the tile """ if self.is_superspace(): params = {"in_superspace": self.context.UID()} else: params = {} form = self.request.form for key in ("archived", "SearchableText", "member", "userid"): value = form.get(key) if value: params[key] = value return urlencode(params)
[docs] @memoize def superspace_overview_url(self): """ Format the qs for superspaces in order to properly expand the tile """ url = self.workspaces_view.context.absolute_url() return "{url}?{qs}".format(url=url, qs=self.superspace_qs())
[docs] def can_view(self): """ Check if the user can actually view this tile If it is a search result, check for the absolute_url, otherwise check if the user has the view permission on the context """ if isinstance(self.context, AdaptableWSDict): return "@@panel-request-access" not in self.context.absolute_url() return api.user.has_permission(permission="View", obj=self.context)
[docs]class WorkspaceTileSmall(WorkspaceTile): index = ViewPageTemplateFile("templates/workspace.tile.small.pt")