def get_actions()

in src/olympia/reviewers/utils.py [0:0]


    def get_actions(self):
        actions = OrderedDict()
        # 2 kind of checks are made for the review page.
        # - Base permission checks to access the review page itself, done in
        #   the review() view
        # - A more specific check for each action, done below, restricting
        #   their availability while not affecting whether the user can see
        #   the review page or not.
        version_is_unlisted = (
            self.version and self.version.channel == amo.CHANNEL_UNLISTED
        )
        version_is_listed = self.version and self.version.channel == amo.CHANNEL_LISTED
        promoted_group = self.addon.promoted_groups(currently_approved=False)
        is_static_theme = self.addon.type == amo.ADDON_STATICTHEME

        # Default permissions / admin needed values if it's just a regular
        # code review, nothing fancy.
        permission = amo.permissions.ADDONS_REVIEW
        permission_post_review = amo.permissions.ADDONS_REVIEW
        is_admin_needed = is_admin_needed_post_review = False

        # More complex/specific cases.
        if PROMOTED_GROUP_CHOICES.RECOMMENDED in promoted_group.group_id:
            permission = amo.permissions.ADDONS_RECOMMENDED_REVIEW
            permission_post_review = permission
        elif version_is_unlisted:
            permission = amo.permissions.ADDONS_REVIEW_UNLISTED
            permission_post_review = permission
        elif any(promoted_group.admin_review):
            is_admin_needed = is_admin_needed_post_review = True
        elif self.content_review:
            permission = amo.permissions.ADDONS_CONTENT_REVIEW
        elif is_static_theme:
            is_admin_needed = self.addon.needs_admin_theme_review
            permission = amo.permissions.STATIC_THEMES_REVIEW
            permission_post_review = permission

        # In addition, if the latest (or current for post-review) version is
        # pending rejection, an admin is needed.
        if self.version and self.version.pending_rejection:
            is_admin_needed = True
        if self.addon.current_version and self.addon.current_version.pending_rejection:
            is_admin_needed_post_review = True

        # Whatever permission values we set, we override if an admin is needed.
        if is_admin_needed:
            permission = amo.permissions.REVIEWS_ADMIN
        if is_admin_needed_post_review:
            permission_post_review = amo.permissions.REVIEWS_ADMIN

        # Is the current user a reviewer for this kind of add-on ?
        is_reviewer = acl.is_reviewer(self.user, self.addon)

        # Is the current user an appropriate reviewer, not only for this kind
        # of add-on, but also for the state the add-on is in ? (Allows more
        # impactful actions).
        is_appropriate_reviewer = acl.action_allowed_for(self.user, permission)
        is_appropriate_reviewer_post_review = acl.action_allowed_for(
            self.user, permission_post_review
        )
        is_appropriate_admin_reviewer = is_appropriate_reviewer and is_admin_reviewer(
            self.user
        )

        addon_is_not_deleted = self.addon.status != amo.STATUS_DELETED
        addon_is_not_disabled = self.addon.status != amo.STATUS_DISABLED
        addon_is_not_disabled_or_deleted = self.addon.status not in (
            amo.STATUS_DELETED,
            amo.STATUS_DISABLED,
        )
        addon_is_incomplete_and_version_is_unlisted = (
            self.addon.status == amo.STATUS_NULL and version_is_unlisted
        )
        addon_is_reviewable = (
            addon_is_not_disabled_or_deleted and self.addon.status != amo.STATUS_NULL
        ) or addon_is_incomplete_and_version_is_unlisted
        version_is_unreviewed = self.version and self.version.is_unreviewed
        version_was_rejected = bool(
            self.version
            and self.version.file.status == amo.STATUS_DISABLED
            and self.version.human_review_date
        )
        addon_is_valid = self.addon.is_public() or self.addon.is_unreviewed()
        addon_is_valid_and_version_is_listed = addon_is_valid and version_is_listed
        current_or_latest_listed_version_was_auto_approved = version_is_listed and (
            (
                self.addon.current_version
                and self.addon.current_version.was_auto_approved
            )
            or (not self.addon.current_version and self.version.was_auto_approved)
        )
        version_is_blocked = self.version and self.version.is_blocked

        self.unresolved_cinderjob_qs = (
            CinderJob.objects.for_addon(self.addon)
            .unresolved()
            .resolvable_in_reviewer_tools()
            .prefetch_related(
                'abusereport_set',
                'appealed_decisions__cinder_job',
                'appealed_decisions__override_of__cinder_job',
                'appealed_decisions__appeals',
            )
        )
        unresolved_cinder_jobs = list(self.unresolved_cinderjob_qs)
        has_unresolved_abuse_report_jobs = any(
            job for job in unresolved_cinder_jobs if not job.is_appeal
        )
        has_unresolved_appeal_jobs = any(
            job for job in unresolved_cinder_jobs if job.is_appeal
        )

        # Special logic for availability of reject/approve multiple action:
        if version_is_unlisted:
            can_reject_multiple = is_appropriate_reviewer
            can_approve_multiple = is_appropriate_reviewer
        elif (
            self.content_review
            or any(promoted_group.listed_pre_review)
            or is_static_theme
        ):
            can_reject_multiple = (
                addon_is_valid_and_version_is_listed and is_appropriate_reviewer
            )
            can_approve_multiple = False
        else:
            # When doing a code review, this action is also available to
            # users with Addons:PostReview even if the current version hasn't
            # been auto-approved, provided that the add-on isn't marked as
            # needing admin review.
            can_reject_multiple = addon_is_valid_and_version_is_listed and (
                is_appropriate_reviewer
                or is_appropriate_reviewer_post_review
                or not self.human_review
            )
            can_approve_multiple = False

        # Definitions for all actions.
        actions['public'] = {
            'method': self.handler.approve_latest_version,
            'minimal': False,
            'details': (
                'This will approve, sign, and publish this '
                'version. The comments will be sent to the '
                'developer.'
            ),
            'label': 'Approve',
            'available': (
                not self.content_review
                and addon_is_reviewable
                and version_is_unreviewed
                and (is_appropriate_reviewer or not self.human_review)
                and not version_is_blocked
            ),
            'allows_reasons': not is_static_theme,
            'resolves_cinder_jobs': True,
            'requires_reasons': False,
            'requires_reasons_for_cinder_jobs': False,
            'boilerplate_text': 'Thank you for your contribution.',
            'can_attach': True,
        }
        actions['reject'] = {
            'method': self.handler.reject_latest_version,
            'label': 'Reject',
            'details': (
                'This will reject this version and remove it '
                'from the queue. The comments will be sent '
                'to the developer.'
            ),
            'minimal': False,
            'available': (
                not self.content_review
                # We specifically don't let the individual reject action be
                # available for unlisted review. `reject_latest_version` isn't
                # currently implemented for unlisted.
                and addon_is_valid_and_version_is_listed
                and version_is_unreviewed
                and is_appropriate_reviewer
            ),
            'allows_reasons': True,
            'resolves_cinder_jobs': True,
            'requires_reasons': not is_static_theme,
            'requires_reasons_for_cinder_jobs': True,
        }
        actions['approve_content'] = {
            'method': self.handler.approve_content,
            'label': 'Approve Content',
            'details': (
                'This records your approbation of the '
                'content of the latest public version, '
                'without notifying the developer.'
            ),
            'minimal': False,
            'comments': False,
            'available': (
                self.content_review
                and addon_is_valid_and_version_is_listed
                and is_appropriate_reviewer
            ),
        }
        actions['confirm_auto_approved'] = {
            'method': self.handler.confirm_auto_approved,
            'label': 'Confirm Approval',
            'details': (
                'The latest public version of this add-on was '
                'automatically approved. This records your '
                'confirmation of the approval of that version, '
                'without notifying the developer.'
            ),
            'minimal': True,
            'comments': False,
            'available': (
                not self.content_review
                and current_or_latest_listed_version_was_auto_approved
                and is_appropriate_reviewer_post_review
            ),
            'resolves_cinder_jobs': True,
        }
        actions['approve_multiple_versions'] = {
            'method': self.handler.approve_multiple_versions,
            'label': 'Approve Multiple Versions',
            'minimal': True,
            'multiple_versions': True,
            'details': (
                'This will approve the selected versions. '
                'The comments will be sent to the developer.'
            ),
            'available': (can_approve_multiple),
            'allows_reasons': not is_static_theme,
            'resolves_cinder_jobs': True,
            'requires_reasons': False,
            'requires_reasons_for_cinder_jobs': False,
        }
        actions['reject_multiple_versions'] = {
            'method': self.handler.reject_multiple_versions,
            'label': 'Reject Multiple Versions',
            'minimal': True,
            'delayable': True,
            'multiple_versions': True,
            'details': (
                'This will reject the selected versions. '
                'The comments will be sent to the developer.'
            ),
            'available': can_reject_multiple,
            'allows_reasons': True,
            'resolves_cinder_jobs': True,
            'requires_reasons': not is_static_theme,
            'requires_reasons_for_cinder_jobs': True,
        }
        actions['unreject_latest_version'] = {
            'method': self.handler.unreject_latest_version,
            'label': 'Un-reject',
            'minimal': True,
            'details': (
                'This will un-reject the latest version without notifying the '
                'developer.'
            ),
            'comments': False,
            'available': (
                not version_is_unlisted
                and addon_is_not_disabled_or_deleted
                and version_was_rejected
                and is_appropriate_admin_reviewer
            ),
        }
        actions['unreject_multiple_versions'] = {
            'method': self.handler.unreject_multiple_versions,
            'label': 'Un-reject Versions',
            'minimal': True,
            'multiple_versions': True,
            'details': (
                'This will un-reject the selected versions without notifying the '
                'developer.'
            ),
            'comments': False,
            'available': (
                version_is_unlisted
                and addon_is_not_disabled_or_deleted
                and is_appropriate_admin_reviewer
            ),
        }
        actions['block_multiple_versions'] = {
            'method': self.handler.block_multiple_versions,
            'label': 'Block Multiple Versions',
            'minimal': True,
            'multiple_versions': True,
            'comments': False,
            'details': (
                'This will disable the selected approved '
                'versions silently, and open up the block creation '
                'admin page.'
            ),
            'available': (
                not is_static_theme and version_is_unlisted and is_appropriate_reviewer
            ),
        }
        actions['confirm_multiple_versions'] = {
            'method': self.handler.confirm_multiple_versions,
            'label': 'Confirm Multiple Versions',
            'minimal': True,
            'multiple_versions': True,
            'details': (
                'This will confirm approval of the selected '
                'versions without notifying the developer.'
            ),
            'comments': False,
            'available': (
                not is_static_theme and version_is_unlisted and is_appropriate_reviewer
            ),
            'resolves_cinder_jobs': True,
        }
        actions['change_or_clear_pending_rejection_multiple_versions'] = {
            'method': self.handler.change_or_clear_pending_rejection_multiple_versions,
            'label': 'Change pending rejection',
            'details': (
                'Change or clear pending rejection from selected versions, '
                "but otherwise don't change the version(s) or add-on "
                'statuses. Developer will be notified of the new pending '
                'rejection date unless the action clears it.'
            ),
            'delayable': True,
            'multiple_versions': True,
            'minimal': True,
            'comments': False,
            'available': is_appropriate_admin_reviewer,
        }
        actions['clear_needs_human_review_multiple_versions'] = {
            'method': self.handler.clear_needs_human_review_multiple_versions,
            'label': 'Clear Needs Human Review',
            'details': (
                'Clear needs human review flag from selected versions, but '
                "otherwise don't change the version(s) or add-on statuses."
            ),
            'multiple_versions': True,
            'minimal': True,
            'comments': False,
            'available': is_appropriate_admin_reviewer,
        }
        actions['set_needs_human_review_multiple_versions'] = {
            'method': self.handler.set_needs_human_review_multiple_versions,
            'label': 'Set Needs Human Review',
            'details': (
                'Set needs human review flag from selected versions, but '
                "otherwise don't change the version(s) or add-on statuses."
            ),
            'multiple_versions': True,
            'minimal': True,
            'available': addon_is_not_disabled and is_appropriate_reviewer,
        }
        actions['reply'] = {
            'method': self.handler.reviewer_reply,
            'label': 'Reviewer reply',
            'details': (
                'This will send a message to the developer, attached to the '
                'selected version(s). You will be notified when they reply.'
            ),
            'multiple_versions': True,
            'minimal': True,
            'available': (
                self.version is not None
                and is_reviewer
                and (not any(promoted_group.admin_review) or is_appropriate_reviewer)
            ),
            'allows_reasons': not is_static_theme,
            'requires_reasons': False,
        }
        actions['request_admin_review'] = {
            'method': self.handler.request_admin_review,
            'label': 'Request review from admin',
            'details': (
                'If you have concerns about this add-on that '
                'an admin reviewer should look into, enter '
                'your comments in the area below. They will '
                'not be sent to the developer.'
            ),
            'minimal': True,
            'available': (self.version is not None and is_reviewer and is_static_theme),
        }
        actions['clear_admin_review'] = {
            'method': self.handler.clear_admin_review,
            'label': 'Clear admin review',
            'details': ('Clear needs admin review flag on the add-on.'),
            'minimal': True,
            'comments': False,
            'available': is_appropriate_admin_reviewer and is_static_theme,
        }
        actions['enable_addon'] = {
            'method': self.handler.enable_addon,
            'label': 'Force enable',
            'details': (
                'This will force enable this add-on, and any versions previously '
                'disabled with Force Disable. '
                'The comments will be sent to the developer.'
            ),
            'minimal': True,
            'available': (
                addon_is_not_deleted
                and not addon_is_not_disabled
                and is_appropriate_admin_reviewer
            ),
            'resolves_cinder_jobs': True,
            'can_attach': False,
        }
        actions['disable_addon'] = {
            'method': self.handler.disable_addon,
            'label': 'Force disable',
            'details': (
                'This will force disable this add-on, and all its versions. '
                'The comments will be sent to the developer.'
            ),
            'minimal': False,
            'available': (
                addon_is_not_disabled_or_deleted and is_appropriate_admin_reviewer
            ),
            'allows_reasons': True,
            'resolves_cinder_jobs': True,
            'requires_reasons': not is_static_theme,
            'requires_reasons_for_cinder_jobs': True,
            'can_attach': False,
        }
        actions['resolve_reports_job'] = {
            'method': self.handler.resolve_reports_job,
            'label': 'Resolve Reports',
            'details': (
                'Allows abuse report jobs to be resolved without an action on the '
                'add-on or versions.'
            ),
            'minimal': True,
            'available': is_reviewer and has_unresolved_abuse_report_jobs,
            'comments': False,
            'resolves_cinder_jobs': True,
            'requires_policies': True,
        }
        actions['resolve_appeal_job'] = {
            'method': self.handler.resolve_appeal_job,
            'label': 'Resolve Appeals',
            'details': (
                'Allows abuse report jobs to be resolved without an action on the '
                'add-on or versions.'
            ),
            'minimal': True,
            'available': is_reviewer and has_unresolved_appeal_jobs,
            'resolves_cinder_jobs': True,
        }
        actions['request_legal_review'] = {
            'method': self.handler.request_legal_review,
            'label': 'Request review from Mozilla Legal',
            'details': (
                'If you have concerns about the legality of this add-on that requires '
                "Mozilla's legal to investigate, enter your comments in the area "
                'below. They will not be sent to the developer.'
                'If it relates to an open abuse report job or appeal resolve then job.'
            ),
            'minimal': True,
            'available': is_appropriate_reviewer,
            'resolves_cinder_jobs': True,
        }
        actions['comment'] = {
            'method': self.handler.process_comment,
            'label': 'Comment',
            'details': (
                "Make a comment on this version. The developer won't be able to see "
                'this.'
            ),
            'minimal': True,
            'available': is_reviewer,
        }
        return OrderedDict(
            ((key, action) for key, action in actions.items() if action['available'])
        )