Example #1
0
    def localize_users_to_org(org, users, sort=False):
        # Set cached state for when the users are viewed from a particular Organization.
        # For each user, set:
        # * user_settings_task, which holds the account project's settings Task, if created
        # * user_settings_dict, which holds that Task's current answers as a dict, if the Task was created
        # * can_see_org_settings, which holds whether the user is in the org's organization project

        org_members = org.get_organization_project().get_members()
        if len(users) > 1: org_members = set(org_members) # pre-load

        # Get the account projects of all of the users in batch.
        account_project_root_tasks = { }
        for pm in ProjectMembership.objects.filter(
            user__in=users,
            project__organization=org,
            project__is_account_project=True)\
            .select_related("project", "project__root_task", "project__root_task__module"):
            account_project_root_tasks[pm.user] = pm.project.root_task

        # Get the account_settings answer object for all of the account projects in batch.
        # Load all TaskAnswerHistory objects that answer the "account_settings" question
        # in each account project. This gives us the whole history of answers. Take the
        # most recent (reverse sort + take first) for each project.
        from guidedmodules.models import TaskAnswerHistory
        account_project_settings = { }
        for ansh in TaskAnswerHistory.objects\
            .filter(
                taskanswer__task__in=account_project_root_tasks.values(),
                taskanswer__question__key="account_settings",
            )\
            .select_related("taskanswer__task__module", "taskanswer__question", "answered_by")\
            .prefetch_related("answered_by_task__module__questions")\
            .order_by('-id'):
            account_project_settings.setdefault(
                ansh.taskanswer.task,
                ansh.answered_by_task.first()
            )

        # Get all of the current answers for the settings tasks.
        from guidedmodules.models import Task
        settings = { }
        for task, question, answer in Task.get_all_current_answer_records(account_project_settings.values()):
            settings.setdefault(task, {})[question.key] = (answer.get_value() if answer else None)

        # Set attributes on each user instance.
        for user in users:
            user.localized_to = org
            user.user_settings_task = account_project_settings.get(account_project_root_tasks.get(user))
            user.user_settings_task_answers = settings.get(user.user_settings_task, None)
            user.can_see_org_settings = (user in org_members)

        # Apply a standard sort.
        if sort:
            users.sort(key = lambda user : user.name_and_email())
Example #2
0
 def get_open_tasks(self, user):
     # Get all tasks that the user might want to continue working on
     # (except for the project root task).
     from guidedmodules.models import Task
     return [
         task for task in
         Task.get_all_tasks_readable_by(user, self.organization)
             .filter(project=self, editor=user) \
             .order_by('-updated')\
             .select_related('project')
         if not task.is_finished()
            and task != self.root_task ]
Example #3
0
 def has_read_priv(self, user):
     # Who can see this project? Team members + anyone with read privs to a task within
     # this project + anyone that's a guest in dicussion within this project.
     # See get_all_participants for the inverse of this function.
     from guidedmodules.models import Task
     if ProjectMembership.objects.filter(project=self, user=user).exists():
         return True
     if Task.get_all_tasks_readable_by(user, self.organization, recursive=True).filter(project=self).exists():
         return True
     for d in self.get_discussions_in_project_as_guest(user):
         return True
     return False
Example #4
0
    def get_projects_with_read_priv(user, organization, filters={}, excludes={}):
        # Gets all projects a user has read priv to, excluding
        # account and organization profile projects, and sorted
        # in reverse chronological order by modified date.

        projects = set()

        if not user.is_authenticated:
            return projects

        # Add all of the Projects the user is a member of within the Organization
        # that the user is on the subdomain of.
        for pm in ProjectMembership.objects\
            .filter(project__organization=organization, user=user)\
            .filter(**{ "project__"+k: v for k, v in filters.items() })\
            .exclude(**{ "project__"+k: v for k, v in excludes.items() })\
            .select_related('project__root_task__module')\
            .prefetch_related('project__root_task__module__questions'):
            projects.add(pm.project)
            if pm.is_admin:
                # Annotate with whether the user is an admin of the project.
                pm.project.user_is_admin = True

        # Add projects that the user is the editor of a task in, even if
        # the user isn't a team member of that project.
        from guidedmodules.models import Task
        for task in Task.get_all_tasks_readable_by(user, organization)\
            .filter(**{ "project__"+k: v for k, v in filters.items() })\
            .exclude(**{ "project__"+k: v for k, v in excludes.items() })\
            .order_by('-created')\
            .select_related('project__root_task__module')\
            .prefetch_related('project__root_task__module__questions'):
            projects.add(task.project)

        # Add projects that the user is participating in a Discussion in
        # as a guest.
        from discussion.models import Discussion
        for d in Discussion.objects.filter(organization=organization, guests=user):
            if d.attached_to is not None: # because it is generic there is no cascaded delete and the Discussion can become dangling
                if not filters or d.attached_to.task.project in Project.objects.filter(**filters):
                    if not excludes or d.attached_to.task.project not in Project.objects.exclude(**filters):
                        projects.add(d.attached_to.task.project)

        # Don't show system projects.
        system_projects = set(p for p in projects if p.is_organization_project or p.is_account_project)
        projects -= system_projects

        # Sort.
        projects = sorted(projects, key = lambda x : x.updated, reverse=True)

        return projects