def __init__(self, context, request): """self:zope.app.pagetemplate.simpleviewclass.SimpleViewClass -> templates/workspace-index.pt context:bungeni.core.content.Section """ LD = IAnnotations(request)["layer_data"] assert interfaces.IWorkspaceSectionLayer.providedBy(request) assert LD.get("workspaces") is not None super(WorkspaceSectionView, self).__init__(context, request) cls_name = self.__class__.__name__ # NOTE: Zope morphs this class's name to "SimpleViewClass from ..." log.debug("%s.__init__ %s context=%s url=%s" % ( cls_name, self, self.context, request.getURL())) # transfer layer data items, for the view/template self.user_id = LD.user_id self.user_group_ids = LD.user_group_ids self.government_id = LD.government_id # may be None self.ministries = LD.ministries # may be None if self.ministries: # then, ONLY if an ancestor container is actually a Ministry, # this must be a MinisterWorkspace if misc.get_parent_with_interface(self, model_interfaces.IMinistry): interface.alsoProvides(self, interfaces.IMinisterWorkspace) # roles are function of the context, so always recalculate roles = get_roles(self.context) for role_id in roles: iface = self.role_interface_mapping.get(role_id) if iface is not None: interface.alsoProvides(self, iface) log.debug("%s.__init__ %s" % (cls_name, debug.interfaces(self)))
def __init__(self, context, request): """self:zope.app.pagetemplate.simpleviewclass.SimpleViewClass -> templates/workspace-index.pt context:bungeni.core.content.Section """ LD = IAnnotations(request)["layer_data"] assert interfaces.IWorkspaceSectionLayer.providedBy(request) assert LD.get("workspaces") is not None super(WorkspaceSectionView, self).__init__(context, request) cls_name = self.__class__.__name__ # NOTE: Zope morphs this class's name to "SimpleViewClass from ..." log.debug("%s.__init__ %s context=%s url=%s" % (cls_name, self, self.context, request.getURL())) # transfer layer data items, for the view/template self.user_id = LD.user_id self.user_group_ids = LD.user_group_ids self.government_id = LD.government_id # may be None self.ministries = LD.ministries # may be None if self.ministries: interface.alsoProvides(self, interfaces.IMinisterWorkspace) # roles are function of the context, so always recalculate roles = get_roles(self.context) for role_id in roles: iface = self.role_interface_mapping.get(role_id) if iface is not None: interface.alsoProvides(self, iface) log.debug("%s.__init__ %s" % (cls_name, debug.interfaces(self)))
def prepare_user_workspaces(event): """Determine the current principal's workspaces, depending on roles and group memberships. "bungeni.Clerk", "bungeni.Speaker", "bungeni.MP" these roles get a parliament-level workspace "bungeni.Minister" "implied" role (by being a member of a ministry group) gets a ministry-level workspace (for each ministry) "zope.Manager", "bungeni.Admin", "bungeni.Owner", "bungeni.Everybody", "bungeni.Anybody" not relevant for user workspaces, no workspaces !+ should these get an owner-level (user) workspace? """ request = event.request application = event.object # is bungeni.core.app.BungeniApp destination_url_path = url.get_destination_url_path(request) def need_to_prepare_workspaces(obj, req): return ( # need only to do it when traversing "/", # obj should be the BungeniApplication model_interfaces.IBungeniApplication.providedBy(obj) and # user is logged in interfaces.IBungeniAuthenticatedSkin.providedBy(req) and ( # either the request should be for a view within /workspace # note: IWorkspaceSectionLayer is applied to the request by # publication.apply_request_layer_by_url() that therefore must # have already been called interfaces.IWorkspaceSectionLayer.providedBy(req) or interfaces.IWorkspaceSchedulingSectionLayer.providedBy(req) or # or the request is for *the* Home Page (as in this case # we still need to know the user workspaces to be able to # redirect appropriately) interfaces.IHomePageLayer.providedBy(req) ) ) if not need_to_prepare_workspaces(application, request): return # initialize a layer data object, for the views in the layer LD = IAnnotations(request)["layer_data"] = misc.bunch( workspaces=[], # workspace containers !+ unique? # !+ role-based workspaces: (role|group, workspace_container) # these are needed by the views, as we need them also here, we just # remember them to not need to calculate them again user_id=None, user_group_ids=None, government_id=None, ministries=None, # list of ministries (that are also workspaces) ) LD.user_id = get_db_user_id() try: parliament = get_current_parliament(None) assert parliament is not None # force exception # we do get_roles under the current parliament as context, but we # must also ensure that the BungeniApp is present somewhere along # the __parent__ stack: parliament.__parent__ = application roles = get_roles(parliament) # "bungeni.Clerk", "bungeni.Speaker", "bungeni.MP" for role_id in roles: if role_id in ("bungeni.Clerk", "bungeni.Speaker", "bungeni.MP"): log.debug("adding parliament workspace %s (for role %s)" % ( parliament, role_id)) LD.workspaces.append(parliament) # "bungeni.Minister" # need to check for ministry groups to which the principal belongs, and # for each such ministry assign a ministry workspace LD.user_group_ids = get_group_ids_for_user_in_parliament( LD.user_id, parliament.group_id) LD.government_id = get_current_parliament_governments( parliament)[0].group_id # IndexError LD.ministries = get_ministries_for_user_in_government( LD.user_id, LD.government_id) log.debug(""" [prepare_user_workspaces] user_id:%s roles:%s parliament:(%s, %s) government_id:%s ministries:%s""" % ( LD.user_id, roles, parliament.full_name, parliament.group_id, LD.government_id, [(m.full_name, m.group_id) for m in LD.ministries] )) for ministry in LD.ministries: log.debug("adding ministry workspace %s" % ministry) LD.workspaces.append(ministry) except (Exception,): debug.log_exc_info(sys.exc_info(), log_handler=log.info) # ensure unique workspaces, preserving order, retaining same list obj ref LD.workspaces[:] = [ workspace for i,workspace in enumerate(LD.workspaces) if LD.workspaces.index(workspace)==i ] # mark each workspace container with IWorkspaceContainer for workspace in LD.workspaces: interface.alsoProvides(workspace, interfaces.IWorkspaceContainer) log.debug(debug.interfaces(workspace)) log.debug(" [prepare_user_workspaces] %s" % debug.interfaces(request)) log.info(""" [prepare_user_workspaces] DONE: for: [request=%s][path=%s][path_info=%s] request.layer_data: %s""" % ( id(request), destination_url_path, request.get("PATH_INFO"), IAnnotations(request).get("layer_data", None)))
def prepare_user_workspaces(event): """Determine the current principal's workspaces, depending on roles and group memberships. "bungeni.Clerk", "bungeni.Speaker", "bungeni.MP" these roles get a parliament-level workspace "bungeni.Minister" "implied" role (by being a member of a ministry group) gets a ministry-level workspace (for each ministry) "zope.Manager", "bungeni.Admin", "bungeni.Owner", "bungeni.Everybody", "bungeni.Anybody" not relevant for user workspaces, no workspaces !+ should these get an owner-level (user) workspace? """ request = event.request application = event.object # is bungeni.core.app.BungeniApp destination_url_path = url.get_destination_url_path(request) def need_to_prepare_workspaces(obj, req): return ( # need only to do it when traversing "/", # obj should be the BungeniApplication model_interfaces.IBungeniApplication.providedBy(obj) and # user is logged in interfaces.IBungeniAuthenticatedSkin.providedBy(req) and ( # either the request should be for a view within /workspace # note: IWorkspaceSectionLayer is applied to the request by # publication.apply_request_layer_by_url() that therefore must # have already been called interfaces.IWorkspaceSectionLayer.providedBy(req) or # or the request is for *the* Home Page (as in this case # we still need to know the user workspaces to be able to # redirect appropriately) interfaces.IHomePageLayer.providedBy(req))) if not need_to_prepare_workspaces(application, request): return # initialize a layer data object, for the views in the layer LD = IAnnotations(request)["layer_data"] = misc.bunch( workspaces=[], # workspace containers !+ unique? # !+ role-based workspaces: (role|group, workspace_container) # these are needed by the views, as we need them also here, we just # remember them to not need to calculate them again user_id=None, user_group_ids=None, government_id=None, ministries=None, # list of ministries (that are also workspaces) ) LD.user_id = get_db_user_id() try: parliament = get_current_parliament(None) assert parliament is not None # force exception # we do get_roles under the current parliament as context, but we # must also ensure that the BungeniApp is present somewhere along # the __parent__ stack: parliament.__parent__ = application roles = get_roles(parliament) # "bungeni.Clerk", "bungeni.Speaker", "bungeni.MP" for role_id in roles: if role_id in ("bungeni.Clerk", "bungeni.Speaker", "bungeni.MP"): log.debug("adding parliament workspace %s (for role %s)" % (parliament, role_id)) LD.workspaces.append(parliament) # "bungeni.Minister" # need to check for ministry groups to which the principal belongs, and # for each such ministry assign a ministry workspace LD.user_group_ids = get_group_ids_for_user_in_parliament( LD.user_id, parliament.group_id) LD.government_id = get_current_parliament_governments( parliament)[0].group_id # IndexError LD.ministries = get_ministries_for_user_in_government( LD.user_id, LD.government_id) log.debug(""" [prepare_user_workspaces] user_id:%s parliament:(%s, %s) government_id:%s ministries:%s""" % (LD.user_id, parliament.full_name, parliament.group_id, LD.government_id, [(m.full_name, m.group_id) for m in LD.ministries])) for ministry in LD.ministries: log.debug("adding ministry workspace %s" % ministry) LD.workspaces.append(ministry) except (Exception, ): debug.log_exc_info(sys.exc_info(), log_handler=log.info) # ensure unique workspaces, preserving order, retaining same list obj ref LD.workspaces[:] = [ workspace for i, workspace in enumerate(LD.workspaces) if LD.workspaces.index(workspace) == i ] # mark each workspace container with IWorkspaceContainer for workspace in LD.workspaces: interface.alsoProvides(workspace, interfaces.IWorkspaceContainer) log.debug(debug.interfaces(workspace)) log.debug(" [prepare_user_workspaces] %s" % debug.interfaces(request)) log.info(""" [prepare_user_workspaces] DONE: for: [request=%s][path=%s][path_info=%s] request.layer_data: %s""" % (id(request), destination_url_path, request.get("PATH_INFO"), IAnnotations(request).get("layer_data", None)))