Example #1
0
def can_unpublish(user, video):
    """Return True if the user can unpublish subtitles for this video.

    Safe to use with anonymous users as well as non-team videos.

    Usage:

        {% if request.user|can_unpublish:video %}
            ...
        {% endif %}

    """
    team_video = video.get_team_video()

    if not team_video:
        return False

    workflow = Workflow.get_for_team_video(team_video)
    if not workflow:
        return False

    if workflow.approve_enabled:
        return _can_approve(team_video, user)

    return False
Example #2
0
def can_delete_task(task, user):
    """Return whether the given user can delete the given task."""

    team, project, lang = task.team, task.team_video.project, task.language

    can_delete = can_delete_tasks(team, user, project, lang)

    # Allow stray review tasks to be deleted.
    if task.type == Task.TYPE_IDS['Review']:
        workflow = Workflow.get_for_team_video(task.team_video)
        if not workflow.review_allowed:
            return can_delete

    # Allow stray approve tasks to be deleted.
    if task.type == Task.TYPE_IDS['Approve']:
        workflow = Workflow.get_for_team_video(task.team_video)
        if not workflow.approve_allowed:
            return can_delete

    return can_delete and can_perform_task(user, task)
Example #3
0
def can_approve(team_video, user, lang=None):
    workflow = Workflow.get_for_team_video(team_video)
    role = get_role_for_target(user, team_video.team, team_video.project, lang)

    if not workflow.approve_allowed:
        return False

    role_req = {
        10: ROLE_MANAGER,
        20: ROLE_ADMIN,
    }[workflow.approve_allowed]

    return role in _perms_equal_or_greater(role_req)
Example #4
0
    def _moderate_session(self, session, user):
        """Return the right moderation_status for a version based on the given session.

        Also may possibly return a Task object that needs to be saved once the
        subtitle_version is ready.

        Also perform any ancillary tasks that are appropriate, assuming the
        version actually gets created later.

        Also :(

        """
        sl = session.language
        team_video = sl.video.get_team_video()

        if not team_video:
            return UNMODERATED, False

        workflow = Workflow.get_for_team_video(team_video)

        if not workflow.approve_enabled and not workflow.review_enabled:
            return UNMODERATED, False

        # If there are any open team tasks for this video/language, it needs to
        # be kept under moderation.
        tasks = team_video.task_set.incomplete().filter(
            Q(language=sl.language)
            | Q(type=Task.TYPE_IDS['Subtitle']))
        if tasks:
            for task in tasks:
                if task.type == Task.TYPE_IDS['Subtitle']:
                    if not task.language:
                        task.language = sl.language
                        task.save()
            return WAITING_MODERATION, False

        if sl.has_version:
            # If there are already active subtitles for this language, we're
            # dealing with an edit.
            if can_publish_edits_immediately(team_video, user, sl.language):
                # The user may have the rights to immediately publish edits to
                # subtitles.  If that's the case we mark them as approved and
                # don't need a task.
                return APPROVED, False
            else:
                # Otherwise it's an edit that needs to be reviewed/approved.
                return WAITING_MODERATION, True
        else:
            # Otherwise we're dealing with a new set of subtitles for this
            # language.
            return WAITING_MODERATION, True
Example #5
0
def can_unpublish_subs(team_video, user, lang):
    """Return whether the user has permission to unpublish subtitles.

    lang should be a language code string.

    """
    workflow = Workflow.get_for_team_video(team_video)

    if workflow.approve_allowed:
        return can_approve(team_video, user, lang)

    if workflow.review_allowed:
        return can_review(team_video, user, lang, allow_own=True)

    return False
Example #6
0
def can_post_edit_subtitles(team_video, user, lang=None):
    """ Returns wheter the user has permission to post edit an original language """
    if user.is_staff:
        return True
    team = team_video.team

    if team.workflow_enabled:
        workflow = Workflow.get_for_team_video(team_video)
        if workflow.approve_allowed:
            return can_approve(team_video, user, lang=lang)
        elif workflow.review_allowed:
            return can_review(team_video, user, lang=lang)
        else:
            return team_video.team.is_member(user)
    else:
        return can_create_and_edit_subtitles(user, team_video, lang=lang)
Example #7
0
def can_publish_edits_immediately(team_video, user, lang):
    """Return whether the user has permission to publish subtitle edits immediately.

    This may be the case when review/approval is not required, or when it is but
    the user is someone who can do it themselves.

    lang should be a language code string.

    """
    workflow = Workflow.get_for_team_video(team_video)

    if workflow.approve_allowed:
        return can_approve(team_video, user, lang)

    if workflow.review_allowed:
        return can_review(team_video, user, lang)

    return True
Example #8
0
    def _create_review_or_approve_task(self, subtitle_version):
        team_video = subtitle_version.video.get_team_video()
        lang = subtitle_version.subtitle_language.language_code
        workflow = Workflow.get_for_team_video(team_video)

        if workflow.review_allowed:
            type = Task.TYPE_IDS['Review']
            can_do = partial(can_review, allow_own=True)
        elif workflow.approve_allowed:
            type = Task.TYPE_IDS['Approve']
            can_do = can_approve
        else:
            return None

        # TODO: Dedupe this and Task._find_previous_assignee

        # Find the assignee.
        #
        # For now, we'll assign the review/approval task to whomever did
        # it last time (if it was indeed done), but only if they're
        # still eligible to perform it now.
        last_task = team_video.task_set.complete().filter(
            language=lang, type=type).order_by('-completed')[:1]

        assignee = None
        if last_task:
            candidate = last_task[0].assignee
            if candidate and can_do(team_video, candidate, lang):
                assignee = candidate

        task = Task(team=team_video.team,
                    team_video=team_video,
                    assignee=assignee,
                    language=lang,
                    type=type)

        task.set_expiration()
        task.new_subtitle_version = subtitle_version

        if task.get_type_display() in ['Review', 'Approve']:
            task.new_review_base_version = subtitle_version

        task.save()
Example #9
0
def can_review(team_video, user, lang=None, allow_own=False):
    workflow = Workflow.get_for_team_video(team_video)
    role = get_role_for_target(user, team_video.team, team_video.project, lang)

    if not workflow.review_allowed:
        return False

    role_req = {
        10: ROLE_CONTRIBUTOR,
        20: ROLE_MANAGER,
        30: ROLE_ADMIN,
    }[workflow.review_allowed]

    # Check that the user has the correct role.
    if role not in _perms_equal_or_greater(role_req):
        return False

    # Users cannot review their own subtitles, unless we're specifically
    # overriding that restriction in the arguments.
    if allow_own:
        return True

    # Users usually cannot review their own subtitles.
    if not hasattr(team_video, '_cached_version_for_review'):
        team_video._cached_version_for_review = team_video.video.latest_version(
            language_code=lang, public_only=False)

    subtitle_version = team_video._cached_version_for_review

    if lang and subtitle_version and subtitle_version.author_id == user.id:
        if can_review_own_subtitles(role, team_video):
            return True
        else:
            return False

    return True
Example #10
0
    def test_can_approve(self):
        user, outsider = self.user, self.outsider

        self.team.workflow_enabled = True
        self.team.save()

        workflow = Workflow.get_for_team_video(self.nonproject_video)

        # TODO: Test with Project/video-specific workflows.

        # Approval disabled.
        workflow.approve_allowed = Workflow.APPROVE_IDS[
            "Don't require approval"]
        workflow.save()
        self.clear_cached_workflows()

        for r in [ROLE_CONTRIBUTOR, ROLE_MANAGER, ROLE_ADMIN, ROLE_OWNER]:
            with self.role(r):
                self.assertFalse(can_approve(self.nonproject_video, user))

        self.assertFalse(can_approve(self.nonproject_video, outsider))

        # Manager approval.
        workflow.approve_allowed = Workflow.APPROVE_IDS["Manager must approve"]
        workflow.save()
        self.clear_cached_workflows()

        for r in [ROLE_MANAGER, ROLE_ADMIN, ROLE_OWNER]:
            with self.role(r):
                self.assertTrue(can_approve(self.nonproject_video, user))

        for r in [ROLE_CONTRIBUTOR]:
            with self.role(r):
                self.assertFalse(can_approve(self.nonproject_video, user))

        for r in [ROLE_MANAGER, ROLE_ADMIN]:
            with self.role(r, self.test_project):
                self.assertFalse(can_approve(self.nonproject_video, user))
                self.assertTrue(can_approve(self.project_video, user))

        self.assertFalse(can_approve(self.nonproject_video, outsider))

        # Admin approval.
        workflow.approve_allowed = Workflow.APPROVE_IDS["Admin must approve"]
        workflow.save()
        self.clear_cached_workflows()

        for r in [ROLE_ADMIN, ROLE_OWNER]:
            with self.role(r):
                self.assertTrue(can_approve(self.nonproject_video, user))

        for r in [ROLE_MANAGER, ROLE_CONTRIBUTOR]:
            with self.role(r):
                self.assertFalse(can_approve(self.nonproject_video, user))

        for r in [ROLE_ADMIN]:
            with self.role(r, self.test_project):
                self.assertFalse(can_approve(self.nonproject_video, user))
                self.assertTrue(can_approve(self.project_video, user))

        self.assertFalse(can_approve(self.nonproject_video, outsider))

        # Workflows disabled entirely.
        self.team.workflow_enabled = False
        self.team.save()
        self.clear_cached_workflows()

        for r in [ROLE_CONTRIBUTOR, ROLE_MANAGER, ROLE_ADMIN, ROLE_OWNER]:
            with self.role(r):
                self.assertFalse(can_approve(self.nonproject_video, user))

        self.assertFalse(can_approve(self.nonproject_video, outsider))
Example #11
0
    def test_can_review(self):
        user, outsider = self.user, self.outsider
        workflow = Workflow.get_for_team_video(self.nonproject_video)

        self.team.workflow_enabled = True
        self.team.save()

        # TODO: Test with Project/video-specific workflows.

        # Review disabled.
        workflow.review_allowed = Workflow.REVIEW_IDS["Don't require review"]
        workflow.save()
        self.clear_cached_workflows()

        for r in [ROLE_CONTRIBUTOR, ROLE_MANAGER, ROLE_ADMIN, ROLE_OWNER]:
            with self.role(r):
                self.assertFalse(can_review(self.nonproject_video, user))

        self.assertFalse(can_review(self.nonproject_video, outsider))

        # Peer reviewing.
        workflow.review_allowed = Workflow.REVIEW_IDS["Peer must review"]
        workflow.save()
        self.clear_cached_workflows()

        for r in [ROLE_CONTRIBUTOR, ROLE_MANAGER, ROLE_ADMIN, ROLE_OWNER]:
            with self.role(r):
                self.assertTrue(can_review(self.nonproject_video, user))

        self.assertFalse(can_review(self.nonproject_video, outsider))

        # Manager review.
        workflow.review_allowed = Workflow.REVIEW_IDS["Manager must review"]
        workflow.save()
        self.clear_cached_workflows()

        for r in [ROLE_MANAGER, ROLE_ADMIN, ROLE_OWNER]:
            with self.role(r):
                self.assertTrue(can_review(self.nonproject_video, user))

        for r in [ROLE_CONTRIBUTOR]:
            with self.role(r):
                self.assertFalse(can_review(self.nonproject_video, user))

        for r in [ROLE_MANAGER, ROLE_ADMIN]:
            with self.role(r, self.test_project):
                self.assertFalse(can_review(self.nonproject_video, user))
                self.assertTrue(can_review(self.project_video, user))

        self.assertFalse(can_review(self.nonproject_video, outsider))

        # Admin review.
        workflow.review_allowed = Workflow.REVIEW_IDS["Admin must review"]
        workflow.save()
        self.clear_cached_workflows()

        for r in [ROLE_ADMIN, ROLE_OWNER]:
            with self.role(r):
                self.assertTrue(can_review(self.nonproject_video, user))

        for r in [ROLE_MANAGER, ROLE_CONTRIBUTOR]:
            with self.role(r):
                self.assertFalse(can_review(self.nonproject_video, user))

        for r in [ROLE_ADMIN]:
            with self.role(r, self.test_project):
                self.assertFalse(can_review(self.nonproject_video, user))
                self.assertTrue(can_review(self.project_video, user))

        self.assertFalse(can_review(self.nonproject_video, outsider))

        # Workflows disabled entirely.
        self.team.workflow_enabled = False
        self.team.save()
        self.clear_cached_workflows()

        for r in [ROLE_CONTRIBUTOR, ROLE_MANAGER, ROLE_ADMIN, ROLE_OWNER]:
            with self.role(r):
                self.assertFalse(can_review(self.nonproject_video, user))

        self.assertFalse(can_review(self.nonproject_video, outsider))