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)))
Beispiel #2
0
    def workspace_search(self):
        """ Search in workspace section, based on views from bungeni.ui.viewlets.workspace
        """
        application = common.get_application()
        parliament = get_current_parliament(None)
        parliament.__parent__ = application
        principal = get_principal()
        roles = common.get_context_roles(parliament, principal)

        # minister role, filtering by states and object_type and ministry_id
        if not roles:
            user_id = get_db_user_id()
            government_id = get_current_parliament_governments(
                parliament)[0].group_id
            ministries = get_ministries_for_user_in_government(
                user_id, government_id)
            if ministries:
                states = workspace.MinistryArchiveViewlet.states + \
                         workspace.OralMinistryQuestionsViewlet.states + \
                         workspace.WrittenMinistryQuestionsViewlet.states + \
                         workspace.InProgressMinistryItemsViewlet.states
                states = set(states)

                ministry_ids = [m.group_id for m in ministries]

                # filter by object_type (questions only)
                type_query = self.searcher.query_field('object_type',
                                                       "Question")
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, type_query,))

                subqueries = []

                for state in states:
                    subqueries.append(
                        self.searcher.query_field('status', state))

                state_query = self.searcher.query_composite(
                    self.searcher.OP_OR, subqueries)
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                           (query, state_query,))

                #filter for ministries
                ministries_queries = []

                for mid in ministry_ids:
                    ministries_queries.append(
                        self.searcher.query_field('ministry_id', str(mid)))

                m_query = self.searcher.query_composite(
                    self.searcher.OP_OR, ministries_queries)
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                           (query, m_query,))

                try:
                    results = self.searcher.search(
                        query, 0, self.searcher.get_doccount())
                except:
                    results = []

                return list(results)

        # filtering by states and owner
        if 'bungeni.MP' in roles:
            states = workspace.MPItemActionRequiredViewlet.states + \
                     workspace.MPItemDraftViewlet.states + \
                     workspace.MPItemInProgressViewlet.states + \
                     workspace.ItemArchiveViewlet.states
            states = set(states)
            # filter by owner of PI
            owner_query = self.searcher.query_field('owner',
                                                    str(get_db_user_id()))
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, owner_query,))

            subqueries = []

            for state in states:
                subqueries.append(self.searcher.query_field('status', state))

            state_query = self.searcher.query_composite(
                self.searcher.OP_OR, subqueries)
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (query, state_query,))

            try:
                results = self.searcher.search(query, 0,
                                               self.searcher.get_doccount())
            except:
                results = []

            return list(results)

        # filtering by states
        if 'bungeni.Clerk' in roles:
            states = workspace.ClerkItemActionRequiredViewlet.states + \
                     workspace.ClerkItemsWorkingDraftViewlet.states + \
                     workspace.ClerkReviewedItemViewlet.states + \
                     workspace.ItemsApprovedViewlet.states + \
                     workspace.ItemsPendingScheduleViewlet.states + \
                     workspace.ItemsScheduledViewlet.states + \
                     workspace.AllItemArchiveViewlet.states

            states = set(states)

            subqueries = []

            for state in states:
                subqueries.append(self.searcher.query_field('status', state))

            state_query = self.searcher.query_composite(
                self.searcher.OP_OR, subqueries)
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, state_query,))

            try:
                results = self.searcher.search(query, 0,
                                               self.searcher.get_doccount())
            except:
                results = []

            return list(results)
        # no results
        return False
Beispiel #3
0
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.Authenticated", 
    "bungeni.Anonymous"
        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_context_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 = common.get_context_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)))
Beispiel #4
0
    def workspace_search(self):
        """ Search in workspace section, based on views from bungeni.ui.viewlets.workspace
        """
        application = common.get_application()
        parliament = get_current_parliament(None)
        parliament.__parent__ = application
        principal = get_principal()
        roles = common.get_context_roles(parliament, principal)

        # minister role, filtering by states and object_type and ministry_id
        if not roles:
            user_id = get_db_user_id()
            government_id = get_current_parliament_governments(parliament)[0].group_id
            ministries = get_ministries_for_user_in_government(user_id, government_id)
            if ministries:
                states = workspace.MinistryArchiveViewlet.states + \
                         workspace.OralMinistryQuestionsViewlet.states + \
                         workspace.WrittenMinistryQuestionsViewlet.states + \
                         workspace.InProgressMinistryItemsViewlet.states
                states = set(states)
                
                ministry_ids = [m.group_id for m in ministries]
                
                # filter by object_type (questions only)
                type_query = self.searcher.query_field('object_type', "Question")
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, type_query,))
                
                subqueries = []

                for state in states:
                    subqueries.append(self.searcher.query_field('status', state))
                    
                state_query = self.searcher.query_composite(self.searcher.OP_OR, subqueries)
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                           (query, state_query,))
                
                #filter for ministries
                ministries_queries = []
                
                for mid in ministry_ids:
                    ministries_queries.append(self.searcher.query_field('ministry_id', str(mid)))
                    
                m_query = self.searcher.query_composite(self.searcher.OP_OR, ministries_queries)
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                           (query, m_query,))
                
                try:
                    results = self.searcher.search(query, 0, self.searcher.get_doccount())
                except:
                    results = []
                
                return list(results)
        
        # filtering by states and owner
        if 'bungeni.MP' in roles:
            states = workspace.MPItemActionRequiredViewlet.states + \
                     workspace.MPItemDraftViewlet.states + \
                     workspace.MPItemInProgressViewlet.states + \
                     workspace.ItemArchiveViewlet.states
            states = set(states)
            # filter by owner of PI
            owner_query = self.searcher.query_field('owner', str(get_db_user_id()))
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, owner_query,))
            
            subqueries = []

            for state in states:
                subqueries.append(self.searcher.query_field('status', state))
                
            state_query = self.searcher.query_composite(self.searcher.OP_OR, subqueries)
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (query, state_query,))
            
            try:
                results = self.searcher.search(query, 0,
                self.searcher.get_doccount())
            except:
                results = []
                
            return list(results)
            
        # filtering by states
        if 'bungeni.Clerk' in roles:
            states = workspace.ClerkItemActionRequiredViewlet.states + \
                     workspace.ClerkItemsWorkingDraftViewlet.states + \
                     workspace.ClerkReviewedItemViewlet.states + \
                     workspace.ItemsApprovedViewlet.states + \
                     workspace.ItemsPendingScheduleViewlet.states + \
                     workspace.ItemsScheduledViewlet.states + \
                     workspace.AllItemArchiveViewlet.states
                     
            states = set(states)
            
            subqueries = []

            for state in states:
                subqueries.append(self.searcher.query_field('status', state))
                
            state_query = self.searcher.query_composite(self.searcher.OP_OR, subqueries)
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, state_query,))
            
            try:
                results = self.searcher.search(query, 0,
                self.searcher.get_doccount())
            except:
                results = []
                
            return list(results)
        # no results
        return False