Beispiel #1
0
 def test_get_performance_since(self):
     self._give_points()
     ReviewerScore.award_moderation_points(self.user, self.app, 1)
     rs = list(ReviewerScore.objects.all())
     rs[0].update(created=self.days_ago(50))
     performance = ReviewerScore.get_performance_since(self.user, self.days_ago(30))
     eq_(len(performance), 1)
Beispiel #2
0
 def test_get_breakdown(self):
     self._give_points()
     ReviewerScore.award_moderation_points(self.user, self.app, 1)
     breakdown = ReviewerScore.get_breakdown(self.user)
     eq_(len(breakdown), 1)
     eq_(set([b.atype for b in breakdown]),
         set([amo.ADDON_WEBAPP]))
Beispiel #3
0
def moderatelog_detail(request, eventlog_id):
    log = get_object_or_404(ActivityLog.objects.editor_events(),
                            pk=eventlog_id)
    review = None
    if len(log.arguments) > 1 and isinstance(log.arguments[1], Review):
        review = log.arguments[1]

    form = ModerateLogDetailForm(request.POST or None)
    is_admin = acl.action_allowed(request, 'ReviewerAdminTools', 'View')
    can_undelete = review and review.deleted and (is_admin or request.user.pk
                                                  == log.user.pk)

    if (request.method == 'POST' and form.is_valid()
            and form.cleaned_data['action'] == 'undelete'):
        if not can_undelete:
            if not review:
                raise RuntimeError('Review doesn`t exist.')
            elif not review.deleted:
                raise RuntimeError('Review isn`t deleted.')
            else:
                raise PermissionDenied
        ReviewerScore.award_moderation_points(log.user,
                                              review.addon,
                                              review.id,
                                              undo=True)
        review.undelete()
        return redirect('reviewers.apps.moderatelog.detail', eventlog_id)
    data = context(request,
                   log=log,
                   form=form,
                   review=review,
                   can_undelete=can_undelete)
    return render(request, 'reviewers/moderatelog_detail.html', data)
Beispiel #4
0
 def test_get_total(self):
     user2 = UserProfile.objects.get(email="*****@*****.**")
     self._give_points()
     self._give_points()
     self._give_points(user=user2)
     eq_(ReviewerScore.get_total(self.user), mkt.REVIEWED_SCORES[mkt.REVIEWED_WEBAPP_HOSTED] * 2)
     eq_(ReviewerScore.get_total(user2), mkt.REVIEWED_SCORES[mkt.REVIEWED_WEBAPP_HOSTED])
Beispiel #5
0
def moderatelog_detail(request, eventlog_id):
    log = get_object_or_404(
        ActivityLog.objects.editor_events(), pk=eventlog_id)
    review = None
    if len(log.arguments) > 1 and isinstance(log.arguments[1], Review):
        review = log.arguments[1]

    form = ModerateLogDetailForm(request.POST or None)
    is_admin = acl.action_allowed(request, 'ReviewerAdminTools', 'View')
    can_undelete = review and review.deleted and (
        is_admin or request.user.pk == log.user.pk)

    if (request.method == 'POST' and form.is_valid() and
            form.cleaned_data['action'] == 'undelete'):
        if not can_undelete:
            if not review:
                raise RuntimeError('Review doesn`t exist.')
            elif not review.deleted:
                raise RuntimeError('Review isn`t deleted.')
            else:
                raise PermissionDenied
        ReviewerScore.award_moderation_points(
            log.user, review.addon, review.id, undo=True)
        review.undelete()
        return redirect('reviewers.apps.moderatelog.detail', eventlog_id)
    data = context(request, log=log, form=form, review=review,
                   can_undelete=can_undelete)
    return render(request, 'reviewers/moderatelog_detail.html', data)
Beispiel #6
0
 def test_get_performance_since(self):
     self._give_points()
     ReviewerScore.award_moderation_points(self.user, self.app, 1)
     rs = list(ReviewerScore.objects.all())
     rs[0].update(created=self.days_ago(50))
     performance = ReviewerScore.get_performance_since(
         self.user, self.days_ago(30))
     eq_(len(performance), 1)
Beispiel #7
0
 def test_get_total(self):
     user2 = UserProfile.objects.get(email='*****@*****.**')
     self._give_points()
     self._give_points()
     self._give_points(user=user2)
     eq_(ReviewerScore.get_total(self.user),
         mkt.REVIEWED_SCORES[mkt.REVIEWED_WEBAPP_HOSTED] * 2)
     eq_(ReviewerScore.get_total(user2),
         mkt.REVIEWED_SCORES[mkt.REVIEWED_WEBAPP_HOSTED])
Beispiel #8
0
 def test_get_breakdown_since(self):
     self._give_points()
     ReviewerScore.award_moderation_points(self.user, self.app, 1)
     rs = list(ReviewerScore.objects.all())
     rs[0].update(created=self.days_ago(50))
     breakdown = ReviewerScore.get_breakdown_since(self.user,
                                                   self.days_ago(30))
     eq_(len(breakdown), 1)
     eq_([b.atype for b in breakdown], [rs[1].addon.type])
Beispiel #9
0
def reviewers_score_bar(context, types=None):
    user = context.get('user')

    return new_context(dict(
        request=context.get('request'),
        mkt=mkt, settings=settings,
        points=ReviewerScore.get_recent(user),
        total=ReviewerScore.get_total(user),
        **ReviewerScore.get_leaderboards(user, types=types)))
Beispiel #10
0
def reviewers_score_bar(context, types=None):
    user = context.get('user')

    return new_context(
        dict(request=context.get('request'),
             amo=amo,
             settings=settings,
             points=ReviewerScore.get_recent(user),
             total=ReviewerScore.get_total(user),
             **ReviewerScore.get_leaderboards(user, types=types)))
Beispiel #11
0
def reviewers_score_bar(context, types=None, addon_type=None):
    user = context.get("amo_user")

    return new_context(
        dict(
            request=context.get("request"),
            amo=amo,
            settings=settings,
            points=ReviewerScore.get_recent(user, addon_type=addon_type),
            total=ReviewerScore.get_total(user),
            **ReviewerScore.get_leaderboards(user, types=types, addon_type=addon_type)
        )
    )
Beispiel #12
0
 def test_get_leaderboards_last(self):
     users = []
     for i in range(6):
         users.append(user_factory())
     last_user = users.pop(len(users) - 1)
     for u in users:
         self._give_points(user=u)
     # Last user gets lower points by a moderation review.
     ReviewerScore.award_moderation_points(last_user, self.app, 1)
     leaders = ReviewerScore.get_leaderboards(last_user)
     eq_(leaders['user_rank'], 6)
     eq_(len(leaders['leader_top']), 3)
     eq_(len(leaders['leader_near']), 2)
Beispiel #13
0
    def test_award_moderation_points(self):
        ReviewerScore.award_moderation_points(self.user, self.app, 1)
        score = ReviewerScore.objects.all()[0]
        eq_(score.score, mkt.REVIEWED_SCORES.get(mkt.REVIEWED_APP_REVIEW))
        eq_(score.note_key, mkt.REVIEWED_APP_REVIEW)

        ReviewerScore.award_moderation_points(self.user, self.app, 1, undo=True)
        score = ReviewerScore.objects.all()[1]
        eq_(score.score, mkt.REVIEWED_SCORES.get(mkt.REVIEWED_APP_REVIEW_UNDO))
        eq_(score.note_key, mkt.REVIEWED_APP_REVIEW_UNDO)

        # If we change the _UNDO score to be different this test will fail.
        eq_(ReviewerScore.get_total(self.user), 0)
Beispiel #14
0
 def test_get_leaderboards_last(self):
     users = []
     for i in range(6):
         users.append(UserProfile.objects.create(username='******' % i))
     last_user = users.pop(len(users) - 1)
     for u in users:
         self._give_points(user=u)
     # Last user gets lower points by a moderation review.
     ReviewerScore.award_moderation_points(last_user, self.app, 1)
     leaders = ReviewerScore.get_leaderboards(last_user)
     eq_(leaders['user_rank'], 6)
     eq_(len(leaders['leader_top']), 3)
     eq_(len(leaders['leader_near']), 2)
Beispiel #15
0
 def test_get_leaderboards_last(self):
     users = []
     for i in range(6):
         users.append(user_factory())
     last_user = users.pop(len(users) - 1)
     for u in users:
         self._give_points(user=u)
     # Last user gets lower points by a moderation review.
     ReviewerScore.award_moderation_points(last_user, self.app, 1)
     leaders = ReviewerScore.get_leaderboards(last_user)
     eq_(leaders["user_rank"], 6)
     eq_(len(leaders["leader_top"]), 3)
     eq_(len(leaders["leader_near"]), 2)
Beispiel #16
0
    def test_award_moderation_points(self):
        ReviewerScore.award_moderation_points(self.user, self.app, 1)
        score = ReviewerScore.objects.all()[0]
        eq_(score.score, mkt.REVIEWED_SCORES.get(mkt.REVIEWED_APP_REVIEW))
        eq_(score.note_key, mkt.REVIEWED_APP_REVIEW)

        ReviewerScore.award_moderation_points(self.user, self.app, 1,
                                              undo=True)
        score = ReviewerScore.objects.all()[1]
        eq_(score.score, mkt.REVIEWED_SCORES.get(mkt.REVIEWED_APP_REVIEW_UNDO))
        eq_(score.note_key, mkt.REVIEWED_APP_REVIEW_UNDO)

        # If we change the _UNDO score to be different this test will fail.
        eq_(ReviewerScore.get_total(self.user), 0)
Beispiel #17
0
    def save(self):
        for form in self.forms:
            if form.cleaned_data:
                action = int(form.cleaned_data['action'])
                if action == ABUSE_REPORT_SKIP:
                    continue

                inst = form.instance

                app = None
                site = None
                user = None
                texts = []
                for report in inst.abuse_reports.all().filter(read=False):
                    report.read = True
                    report.save()
                    app = report.addon
                    site = report.website
                    user = report.user
                    if report.message:
                        texts.append(report.message)
                    if app:
                        mkt.log(mkt.LOG.APP_ABUSE_MARKREAD,
                                app,
                                report,
                                details=dict(body=unicode(report.message),
                                             addon_id=app.id,
                                             addon_title=unicode(app.name)))
                    elif user:
                        # Not possible on Marketplace currently.
                        pass
                    elif site:
                        mkt.log(mkt.LOG.WEBSITE_ABUSE_MARKREAD,
                                site,
                                report,
                                details=dict(body=unicode(report.message),
                                             website_id=site.id,
                                             website_title=unicode(site.name)))
                if app or site:
                    ReviewerScore.award_mark_abuse_points(self.request.user,
                                                          addon=app,
                                                          website=site)
                if app and action == ABUSE_REPORT_FLAG:
                    message = _('Abuse reports needing investigation: %s' %
                                (', '.join(texts)))
                    RereviewQueue.flag(app,
                                       mkt.LOG.REREVIEW_ABUSE_APP,
                                       message=message)
Beispiel #18
0
    def process_reject(self):
        """
        Reject an app.
        Changes status to Rejected.
        Creates Rejection note.
        """
        # Hold onto the status before we change it.
        status = self.addon.status

        self.set_files(mkt.STATUS_DISABLED, self.version.files.all(),
                       hide_disabled_file=True)
        # If this app is not packaged (packaged apps can have multiple
        # versions) or if there aren't other versions with already reviewed
        # files, reject the app also.
        if (not self.addon.is_packaged or
            not self.addon.versions.exclude(id=self.version.id)
                .filter(files__status__in=mkt.REVIEWED_STATUSES).exists()):
            self.set_addon(status=mkt.STATUS_REJECTED)

        if self.in_escalate:
            EscalationQueue.objects.filter(addon=self.addon).delete()
        if self.in_rereview:
            RereviewQueue.objects.filter(addon=self.addon).delete()

        self.create_note(mkt.LOG.REJECT_VERSION)

        log.info(u'Making %s disabled' % self.addon)

        # Assign reviewer incentive scores.
        return ReviewerScore.award_points(self.request.user, self.addon,
                                          status, in_rereview=self.in_rereview)
Beispiel #19
0
    def process_public(self):
        """
        Makes an app public or approved.
        Changes status to Public/Public Waiting.
        Creates Approval note/email.
        """
        if self.addon.has_incomplete_status():
            # Failsafe.
            return

        # Hold onto the status before we change it.
        status = self.addon.status
        if self.addon.make_public == amo.PUBLIC_IMMEDIATELY:
            self._process_public_immediately()
        else:
            self._process_approved()

        if self.in_escalate:
            EscalationQueue.objects.filter(addon=self.addon).delete()

        # Clear priority_review flag on approval - its not persistant.
        if self.addon.priority_review:
            self.addon.update(priority_review=False)

        # Assign reviewer incentive scores.
        return ReviewerScore.award_points(self.request.amo_user, self.addon,
                                          status)
Beispiel #20
0
    def process_reject(self):
        """
        Reject an app.
        Changes status to Rejected.
        Creates Rejection note.
        """
        # Hold onto the status before we change it.
        status = self.addon.status

        self.set_files(mkt.STATUS_DISABLED,
                       self.version.files.all(),
                       hide_disabled_file=True)
        # If this app is not packaged (packaged apps can have multiple
        # versions) or if there aren't other versions with already reviewed
        # files, reject the app also.
        if (not self.addon.is_packaged
                or not self.addon.versions.exclude(id=self.version.id).filter(
                    files__status__in=mkt.REVIEWED_STATUSES).exists()):
            self.set_addon(status=mkt.STATUS_REJECTED)

        if self.in_escalate:
            EscalationQueue.objects.filter(addon=self.addon).delete()
        if self.in_rereview:
            RereviewQueue.objects.filter(addon=self.addon).delete()

        self.create_note(mkt.LOG.REJECT_VERSION)

        log.info(u'Making %s disabled' % self.addon)

        # Assign reviewer incentive scores.
        return ReviewerScore.award_points(self.request.user,
                                          self.addon,
                                          status,
                                          in_rereview=self.in_rereview)
Beispiel #21
0
    def save(self):

        for form in self.forms:
            if form.cleaned_data and user_can_delete_review(self.request, form.instance):
                action = int(form.cleaned_data["action"])

                is_flagged = form.instance.reviewflag_set.count() > 0

                if action != REVIEW_MODERATE_SKIP:  # Delete flags.
                    for flag in form.instance.reviewflag_set.all():
                        flag.delete()

                review = form.instance
                webapp = review.webapp
                if action == REVIEW_MODERATE_DELETE:
                    review.delete()
                    mkt.log(
                        mkt.LOG.DELETE_REVIEW,
                        webapp,
                        review,
                        details=dict(
                            title=unicode(review.title),
                            body=unicode(review.body),
                            webapp_id=webapp.id,
                            webapp_title=unicode(webapp.name),
                            is_flagged=is_flagged,
                        ),
                    )
                    if self.request:
                        ReviewerScore.award_moderation_points(self.request.user, webapp, review.id)
                elif action == REVIEW_MODERATE_KEEP:
                    review.editorreview = False
                    review.save()
                    mkt.log(
                        mkt.LOG.APPROVE_REVIEW,
                        webapp,
                        review,
                        details=dict(
                            title=unicode(review.title),
                            body=unicode(review.body),
                            webapp_id=webapp.id,
                            webapp_title=unicode(webapp.name),
                            is_flagged=is_flagged,
                        ),
                    )
                    if self.request:
                        ReviewerScore.award_moderation_points(self.request.user, webapp, review.id)
Beispiel #22
0
    def save(self):
        for form in self.forms:
            if form.cleaned_data:
                action = int(form.cleaned_data['action'])
                if action == ABUSE_REPORT_SKIP:
                    continue

                inst = form.instance

                app = None
                site = None
                user = None
                texts = []
                for report in inst.abuse_reports.all().filter(read=False):
                    report.read = True
                    report.save()
                    app = report.addon
                    site = report.website
                    user = report.user
                    if report.message:
                        texts.append(report.message)
                    if app:
                        mkt.log(mkt.LOG.APP_ABUSE_MARKREAD, app, report,
                                details=dict(
                                    body=unicode(report.message),
                                    addon_id=app.id,
                                    addon_title=unicode(app.name)
                                ))
                    elif user:
                        # Not possible on Marketplace currently.
                        pass
                    elif site:
                        mkt.log(mkt.LOG.WEBSITE_ABUSE_MARKREAD, site,
                                report,
                                details=dict(
                                    body=unicode(report.message),
                                    website_id=site.id,
                                    website_title=unicode(site.name)
                                ))
                if app or site:
                    ReviewerScore.award_mark_abuse_points(
                        self.request.user, addon=app, website=site)
                if app and action == ABUSE_REPORT_FLAG:
                    message = _('Abuse reports needing investigation: %s' %
                                (', '.join(texts)))
                    RereviewQueue.flag(
                        app, mkt.LOG.REREVIEW_ABUSE_APP, message=message)
Beispiel #23
0
def performance(request, username=None):
    is_admin = acl.action_allowed(request, 'Admin', '%')

    if username:
        if username == request.amo_user.username:
            user = request.amo_user
        elif is_admin:
            user = get_object_or_404(UserProfile, username=username)
        else:
            raise http.Http404
    else:
        user = request.amo_user

    today = datetime.date.today()
    month_ago = today - datetime.timedelta(days=30)
    year_ago = today - datetime.timedelta(days=365)

    total = ReviewerScore.get_total(user)
    totals = ReviewerScore.get_breakdown(user)
    months = ReviewerScore.get_breakdown_since(user, month_ago)
    years = ReviewerScore.get_breakdown_since(user, year_ago)

    def _sum(iter, types):
        return sum(s.total for s in iter if s.atype in types)

    breakdown = {
        'month': {
            'addons': _sum(months, amo.GROUP_TYPE_ADDON),
            'apps': _sum(months, amo.GROUP_TYPE_WEBAPP),
        },
        'year': {
            'addons': _sum(years, amo.GROUP_TYPE_ADDON),
            'apps': _sum(years, amo.GROUP_TYPE_WEBAPP),
        },
        'total': {
            'addons': _sum(totals, amo.GROUP_TYPE_ADDON),
            'apps': _sum(totals, amo.GROUP_TYPE_WEBAPP),
        }
    }

    ctx = context(request, **{
        'profile': user,
        'total': total,
        'breakdown': breakdown,
    })

    return render(request, 'reviewers/performance.html', ctx)
Beispiel #24
0
    def save(self):

        for form in self.forms:
            if form.cleaned_data and user_can_delete_review(
                    self.request, form.instance):
                action = int(form.cleaned_data['action'])

                is_flagged = (form.instance.reviewflag_set.count() > 0)

                if action != REVIEW_MODERATE_SKIP:  # Delete flags.
                    for flag in form.instance.reviewflag_set.all():
                        flag.delete()

                review = form.instance
                addon = review.addon
                if action == REVIEW_MODERATE_DELETE:
                    review_addon = review.addon
                    review_id = review.id
                    review.delete()
                    amo.log(amo.LOG.DELETE_REVIEW,
                            review_addon,
                            review_id,
                            details=dict(title=unicode(review.title),
                                         body=unicode(review.body),
                                         addon_id=addon.id,
                                         addon_title=unicode(addon.name),
                                         is_flagged=is_flagged))
                    if self.request:
                        ReviewerScore.award_moderation_points(
                            self.request.user, addon, review_id)
                elif action == REVIEW_MODERATE_KEEP:
                    review.editorreview = False
                    review.save()
                    amo.log(amo.LOG.APPROVE_REVIEW,
                            review.addon,
                            review,
                            details=dict(title=unicode(review.title),
                                         body=unicode(review.body),
                                         addon_id=addon.id,
                                         addon_title=unicode(addon.name),
                                         is_flagged=is_flagged))
                    if self.request:
                        ReviewerScore.award_moderation_points(
                            self.request.user, addon, review.id)
Beispiel #25
0
 def test_get_recent(self):
     user2 = UserProfile.objects.get(email='*****@*****.**')
     self._give_points()
     time.sleep(1)  # Wait 1 sec so ordering by created is checked.
     self._give_points()
     self._give_points(user=user2)
     scores = ReviewerScore.get_recent(self.user)
     eq_(len(scores), 2)
     eq_(scores[0].score, amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED])
     eq_(scores[1].score, amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED])
Beispiel #26
0
 def test_get_recent(self):
     user2 = UserProfile.objects.get(email='*****@*****.**')
     self._give_points()
     time.sleep(1)  # Wait 1 sec so ordering by created is checked.
     self._give_points()
     self._give_points(user=user2)
     scores = ReviewerScore.get_recent(self.user)
     eq_(len(scores), 2)
     eq_(scores[0].score, mkt.REVIEWED_SCORES[mkt.REVIEWED_WEBAPP_HOSTED])
     eq_(scores[1].score, mkt.REVIEWED_SCORES[mkt.REVIEWED_WEBAPP_HOSTED])
Beispiel #27
0
 def test_no_admins_or_staff_in_leaderboards(self):
     user2 = UserProfile.objects.get(email='*****@*****.**')
     self._give_points()
     self._give_points(user=user2)
     leaders = ReviewerScore.get_leaderboards(self.user)
     eq_(leaders['user_rank'], 1)
     eq_(leaders['leader_near'], [])
     eq_(leaders['leader_top'][0]['user_id'], self.user.id)
     eq_(len(leaders['leader_top']), 1)  # Only the editor is here.
     assert user2.id not in [l['user_id'] for l in leaders['leader_top']], (
         'Unexpected admin user found in leaderboards.')
Beispiel #28
0
 def process_clear_rereview(self):
     """
     Clear app from re-review queue.
     Doesn't change status.
     Creates Reviewer-only note.
     """
     RereviewQueue.objects.filter(addon=self.addon).delete()
     self.create_note(mkt.LOG.REREVIEW_CLEARED)
     log.info(u"Re-review cleared for app: %s" % self.addon)
     # Assign reviewer incentive scores.
     return ReviewerScore.award_points(self.request.user, self.addon, self.addon.status, in_rereview=True)
Beispiel #29
0
 def test_no_admins_or_staff_in_leaderboards(self):
     user2 = UserProfile.objects.get(email='*****@*****.**')
     self._give_points()
     self._give_points(user=user2)
     leaders = ReviewerScore.get_leaderboards(self.user)
     eq_(leaders['user_rank'], 1)
     eq_(leaders['leader_near'], [])
     eq_(leaders['leader_top'][0]['user_id'], self.user.id)
     eq_(len(leaders['leader_top']), 1)  # Only the editor is here.
     assert user2.id not in [l['user_id'] for l in leaders['leader_top']], (
         'Unexpected admin user found in leaderboards.')
Beispiel #30
0
 def process_clear_rereview(self):
     """
     Clear app from re-review queue.
     Doesn't change status.
     Doesn't create note/email.
     """
     RereviewQueue.objects.filter(addon=self.addon).delete()
     self.create_note(amo.LOG.REREVIEW_CLEARED)
     log.info(u'Re-review cleared for app: %s' % self.addon)
     # Assign reviewer incentive scores.
     return ReviewerScore.award_points(self.request.user, self.addon,
                                       self.addon.status, in_rereview=True)
Beispiel #31
0
    def save(self):

        for form in self.forms:
            if form.cleaned_data and user_can_delete_review(self.request,
                                                            form.instance):
                action = int(form.cleaned_data['action'])

                is_flagged = (form.instance.reviewflag_set.count() > 0)

                if action != REVIEW_MODERATE_SKIP:  # Delete flags.
                    for flag in form.instance.reviewflag_set.all():
                        flag.delete()

                review = form.instance
                addon = review.addon
                if action == REVIEW_MODERATE_DELETE:
                    review_addon = review.addon
                    review_id = review.id
                    review.delete()
                    amo.log(amo.LOG.DELETE_REVIEW, review_addon, review_id,
                            details=dict(title=unicode(review.title),
                                         body=unicode(review.body),
                                         addon_id=addon.id,
                                         addon_title=unicode(addon.name),
                                         is_flagged=is_flagged))
                    if self.request:
                        ReviewerScore.award_moderation_points(
                            self.request.user, addon, review_id)
                elif action == REVIEW_MODERATE_KEEP:
                    review.editorreview = False
                    review.save()
                    amo.log(amo.LOG.APPROVE_REVIEW, review.addon, review,
                            details=dict(title=unicode(review.title),
                                         body=unicode(review.body),
                                         addon_id=addon.id,
                                         addon_title=unicode(addon.name),
                                         is_flagged=is_flagged))
                    if self.request:
                        ReviewerScore.award_moderation_points(
                            self.request.user, addon, review.id)
Beispiel #32
0
def performance(request, username=None):
    is_admin = acl.action_allowed(request, 'Admin', '%')

    if username:
        if username == request.user.username:
            user = request.user
        elif is_admin:
            user = get_object_or_404(UserProfile, username=username)
        else:
            raise http.Http404
    else:
        user = request.user

    today = datetime.date.today()
    month_ago = today - datetime.timedelta(days=30)
    year_ago = today - datetime.timedelta(days=365)

    total = ReviewerScore.get_total(user)
    totals = ReviewerScore.get_performance(user)
    months = ReviewerScore.get_performance_since(user, month_ago)
    years = ReviewerScore.get_performance_since(user, year_ago)

    def _sum(iter):
        return sum(s.total or 0 for s in iter)

    performance = {
        'month': _sum(months),
        'year': _sum(years),
        'total': _sum(totals),
    }

    ctx = context(
        request, **{
            'profile': user,
            'total': total,
            'performance': performance,
        })

    return render(request, 'reviewers/performance.html', ctx)
Beispiel #33
0
def performance(request, email=None):
    is_admin = acl.action_allowed(request, 'Admin', '%')

    if email:
        if email == request.user.email:
            user = request.user
        elif is_admin:
            user = get_object_or_404(UserProfile, email=email)
        else:
            raise http.Http404
    else:
        user = request.user

    today = datetime.date.today()
    month_ago = today - datetime.timedelta(days=30)
    year_ago = today - datetime.timedelta(days=365)

    total = ReviewerScore.get_total(user)
    totals = ReviewerScore.get_performance(user)
    months = ReviewerScore.get_performance_since(user, month_ago)
    years = ReviewerScore.get_performance_since(user, year_ago)

    def _sum(iter):
        return sum(s.total or 0 for s in iter)

    performance = {
        'month': _sum(months),
        'year': _sum(years),
        'total': _sum(totals),
    }

    ctx = context(request, **{
        'profile': user,
        'total': total,
        'performance': performance,
    })

    return render(request, 'reviewers/performance.html', ctx)
Beispiel #34
0
 def test_all_users_by_score(self):
     user2 = UserProfile.objects.get(email='*****@*****.**')
     mkt.REVIEWED_LEVELS[0]['points'] = 120
     self._give_points()
     self._give_points()
     self._give_points(user=user2)
     users = ReviewerScore.all_users_by_score()
     eq_(len(users), 2)
     # First user.
     eq_(users[0]['total'], 120)
     eq_(users[0]['user_id'], self.user.id)
     eq_(users[0]['level'], mkt.REVIEWED_LEVELS[0]['name'])
     # Second user.
     eq_(users[1]['total'], 60)
     eq_(users[1]['user_id'], user2.id)
     eq_(users[1]['level'], '')
Beispiel #35
0
 def test_all_users_by_score(self):
     user2 = UserProfile.objects.get(email="*****@*****.**")
     mkt.REVIEWED_LEVELS[0]["points"] = 120
     self._give_points()
     self._give_points()
     self._give_points(user=user2)
     users = ReviewerScore.all_users_by_score()
     eq_(len(users), 2)
     # First user.
     eq_(users[0]["total"], 120)
     eq_(users[0]["user_id"], self.user.id)
     eq_(users[0]["level"], mkt.REVIEWED_LEVELS[0]["name"])
     # Second user.
     eq_(users[1]["total"], 60)
     eq_(users[1]["user_id"], user2.id)
     eq_(users[1]["level"], "")
Beispiel #36
0
 def test_all_users_by_score(self):
     user2 = UserProfile.objects.get(email='*****@*****.**')
     amo.REVIEWED_LEVELS[0]['points'] = 120
     self._give_points()
     self._give_points()
     self._give_points(user=user2)
     users = ReviewerScore.all_users_by_score()
     eq_(len(users), 2)
     # First user.
     eq_(users[0]['total'], 120)
     eq_(users[0]['user_id'], self.user.id)
     eq_(users[0]['level'], amo.REVIEWED_LEVELS[0]['name'])
     # Second user.
     eq_(users[1]['total'], 60)
     eq_(users[1]['user_id'], user2.id)
     eq_(users[1]['level'], '')
Beispiel #37
0
 def test_get_leaderboards(self):
     user2 = UserProfile.objects.get(email='*****@*****.**')
     self._give_points()
     self._give_points()
     self._give_points(user=user2)
     leaders = ReviewerScore.get_leaderboards(self.user)
     eq_(leaders['user_rank'], 1)
     eq_(leaders['leader_near'], [])
     eq_(leaders['leader_top'][0]['rank'], 1)
     eq_(leaders['leader_top'][0]['user_id'], self.user.id)
     eq_(leaders['leader_top'][0]['total'],
         amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED] +
         amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED])
     eq_(leaders['leader_top'][1]['rank'], 2)
     eq_(leaders['leader_top'][1]['user_id'], user2.id)
     eq_(leaders['leader_top'][1]['total'],
         amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED])
Beispiel #38
0
 def test_get_leaderboards(self):
     user2 = UserProfile.objects.get(email="*****@*****.**")
     self._give_points()
     self._give_points()
     self._give_points(user=user2)
     leaders = ReviewerScore.get_leaderboards(self.user)
     eq_(leaders["user_rank"], 1)
     eq_(leaders["leader_near"], [])
     eq_(leaders["leader_top"][0]["rank"], 1)
     eq_(leaders["leader_top"][0]["user_id"], self.user.id)
     eq_(
         leaders["leader_top"][0]["total"],
         mkt.REVIEWED_SCORES[mkt.REVIEWED_WEBAPP_HOSTED] + mkt.REVIEWED_SCORES[mkt.REVIEWED_WEBAPP_HOSTED],
     )
     eq_(leaders["leader_top"][1]["rank"], 2)
     eq_(leaders["leader_top"][1]["user_id"], user2.id)
     eq_(leaders["leader_top"][1]["total"], mkt.REVIEWED_SCORES[mkt.REVIEWED_WEBAPP_HOSTED])
Beispiel #39
0
 def test_get_leaderboards(self):
     user2 = UserProfile.objects.get(email='*****@*****.**')
     self._give_points()
     self._give_points()
     self._give_points(user=user2)
     leaders = ReviewerScore.get_leaderboards(self.user)
     eq_(leaders['user_rank'], 1)
     eq_(leaders['leader_near'], [])
     eq_(leaders['leader_top'][0]['rank'], 1)
     eq_(leaders['leader_top'][0]['user_id'], self.user.id)
     eq_(leaders['leader_top'][0]['total'],
         amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED] +
         amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED])
     eq_(leaders['leader_top'][1]['rank'], 2)
     eq_(leaders['leader_top'][1]['user_id'], user2.id)
     eq_(leaders['leader_top'][1]['total'],
         amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED])
Beispiel #40
0
    def process_approve(self):
        """
        Handle the approval of apps and/or files.
        """
        if self.addon.has_incomplete_status():
            # Failsafe.
            return

        # Hold onto the status before we change it.
        status = self.addon.status
        if self.addon.publish_type == mkt.PUBLISH_IMMEDIATE:
            self._process_public(mkt.STATUS_PUBLIC)
        elif self.addon.publish_type == mkt.PUBLISH_HIDDEN:
            self._process_public(mkt.STATUS_UNLISTED)
        else:
            self._process_private()

        # Note: Post save signals shouldn't happen here. All the set_*()
        # methods pass _signal=False to prevent them from being sent. They are
        # manually triggered in the view after the transaction is committed to
        # avoid multiple indexing tasks getting fired with stale data.
        #
        # This does mean that we need to call update_version() manually to get
        # the addon in the correct state before updating names. We do that,
        # passing _signal=False again to prevent it from sending
        # 'version_changed'. The post_save() that happen in the view will
        # call it without that parameter, sending 'version_changed' normally.
        self.addon.update_version(_signal=False)
        if self.addon.is_packaged:
            self.addon.update_name_from_package_manifest()
        self.addon.update_supported_locales()
        self.addon.resend_version_changed_signal = True

        if self.in_escalate:
            EscalationQueue.objects.filter(addon=self.addon).delete()

        # Clear priority_review flag on approval - its not persistant.
        if self.addon.priority_review:
            self.addon.update(priority_review=False)

        # Assign reviewer incentive scores.
        return ReviewerScore.award_points(self.request.user, self.addon,
                                          status)
Beispiel #41
0
    def process_approve(self):
        """
        Handle the approval of apps and/or files.
        """
        if self.addon.has_incomplete_status():
            # Failsafe.
            return

        # Hold onto the status before we change it.
        status = self.addon.status
        if self.addon.publish_type == mkt.PUBLISH_IMMEDIATE:
            self._process_public(mkt.STATUS_PUBLIC)
        elif self.addon.publish_type == mkt.PUBLISH_HIDDEN:
            self._process_public(mkt.STATUS_UNLISTED)
        else:
            self._process_private()

        # Note: Post save signals shouldn't happen here. All the set_*()
        # methods pass _signal=False to prevent them from being sent. They are
        # manually triggered in the view after the transaction is committed to
        # avoid multiple indexing tasks getting fired with stale data.
        #
        # This does mean that we need to call update_version() manually to get
        # the addon in the correct state before updating names. We do that,
        # passing _signal=False again to prevent it from sending
        # 'version_changed'. The post_save() that happen in the view will
        # call it without that parameter, sending 'version_changed' normally.
        self.addon.update_version(_signal=False)
        if self.addon.is_packaged:
            self.addon.update_name_from_package_manifest()
        self.addon.update_supported_locales()
        self.addon.resend_version_changed_signal = True

        if self.in_escalate:
            EscalationQueue.objects.filter(addon=self.addon).delete()

        # Clear priority_review flag on approval - its not persistant.
        if self.addon.priority_review:
            self.addon.update(priority_review=False)

        # Assign reviewer incentive scores.
        return ReviewerScore.award_points(self.request.user, self.addon,
                                          status)
Beispiel #42
0
 def test_award_mark_abuse_points_website(self):
     ReviewerScore.award_mark_abuse_points(self.user, website=self.website)
     score = ReviewerScore.objects.all()[0]
     eq_(score.score,
         mkt.REVIEWED_SCORES.get(mkt.REVIEWED_WEBSITE_ABUSE_REPORT))
     eq_(score.note_key, mkt.REVIEWED_WEBSITE_ABUSE_REPORT)
Beispiel #43
0
 def check_event(self, status, event, **kwargs):
     eq_(ReviewerScore.get_event(self.app, status, **kwargs), event,
         ('Score event status:%s was not %s' % (status, event)))
Beispiel #44
0
 def _give_points(self, user=None, app=None, status=None):
     user = user or self.user
     app = app or self.app
     ReviewerScore.award_points(user, app, status or app.status)
Beispiel #45
0
 def test_award_moderation_points(self):
     ReviewerScore.award_moderation_points(self.user, self.app, 1)
     score = ReviewerScore.objects.all()[0]
     eq_(score.score, amo.REVIEWED_SCORES.get(amo.REVIEWED_APP_REVIEW))
     eq_(score.note_key, amo.REVIEWED_APP_REVIEW)
Beispiel #46
0
 def check_event(self, type, status, event, **kwargs):
     self.app.type = type
     eq_(ReviewerScore.get_event(self.app, status, **kwargs), event, (
         'Score event for type:%s and status:%s was not %s' % (
             type, status, event)))
Beispiel #47
0
 def _give_points(self, user=None, app=None, status=None):
     user = user or self.user
     app = app or self.app
     ReviewerScore.award_points(user, app, status or app.status)
Beispiel #48
0
    def test_caching(self):
        self._give_points()

        with self.assertNumQueries(1):
            ReviewerScore.get_total(self.user)
        with self.assertNumQueries(0):
            ReviewerScore.get_total(self.user)

        with self.assertNumQueries(1):
            ReviewerScore.get_recent(self.user)
        with self.assertNumQueries(0):
            ReviewerScore.get_recent(self.user)

        with self.assertNumQueries(1):
            ReviewerScore.get_leaderboards(self.user)
        with self.assertNumQueries(0):
            ReviewerScore.get_leaderboards(self.user)

        with self.assertNumQueries(1):
            ReviewerScore.get_breakdown(self.user)
        with self.assertNumQueries(0):
            ReviewerScore.get_breakdown(self.user)

        # New points invalidates all caches.
        self._give_points()

        with self.assertNumQueries(1):
            ReviewerScore.get_total(self.user)
        with self.assertNumQueries(1):
            ReviewerScore.get_recent(self.user)
        with self.assertNumQueries(1):
            ReviewerScore.get_leaderboards(self.user)
        with self.assertNumQueries(1):
            ReviewerScore.get_breakdown(self.user)
Beispiel #49
0
    def test_caching(self):
        self._give_points()

        with self.assertNumQueries(1):
            ReviewerScore.get_total(self.user)
        with self.assertNumQueries(0):
            ReviewerScore.get_total(self.user)

        with self.assertNumQueries(1):
            ReviewerScore.get_recent(self.user)
        with self.assertNumQueries(0):
            ReviewerScore.get_recent(self.user)

        with self.assertNumQueries(1):
            ReviewerScore.get_leaderboards(self.user)
        with self.assertNumQueries(0):
            ReviewerScore.get_leaderboards(self.user)

        with self.assertNumQueries(1):
            ReviewerScore.get_performance(self.user)
        with self.assertNumQueries(0):
            ReviewerScore.get_performance(self.user)

        # New points invalidates all caches.
        self._give_points()

        with self.assertNumQueries(1):
            ReviewerScore.get_total(self.user)
        with self.assertNumQueries(1):
            ReviewerScore.get_recent(self.user)
        with self.assertNumQueries(1):
            ReviewerScore.get_leaderboards(self.user)
        with self.assertNumQueries(1):
            ReviewerScore.get_performance(self.user)
Beispiel #50
0
 def test_award_moderation_points(self):
     ReviewerScore.award_moderation_points(self.user, self.app, 1)
     score = ReviewerScore.objects.all()[0]
     eq_(score.score, amo.REVIEWED_SCORES.get(amo.REVIEWED_APP_REVIEW))
     eq_(score.note_key, amo.REVIEWED_APP_REVIEW)
Beispiel #51
0
 def test_get_performance(self):
     self._give_points()
     ReviewerScore.award_moderation_points(self.user, self.app, 1)
     performance = ReviewerScore.get_performance(self.user)
     eq_(len(performance), 1)
Beispiel #52
0
 def test_award_additional_review_points(self):
     ReviewerScore.award_additional_review_points(self.user, self.app,
                                                  QUEUE_TARAKO)
     score = ReviewerScore.objects.all()[0]
     eq_(score.score, mkt.REVIEWED_SCORES.get(mkt.REVIEWED_WEBAPP_TARAKO))
     eq_(score.note_key, mkt.REVIEWED_WEBAPP_TARAKO)
Beispiel #53
0
 def test_award_mark_abuse_points_app(self):
     ReviewerScore.award_mark_abuse_points(self.user, addon=self.app)
     score = ReviewerScore.objects.all()[0]
     eq_(score.score,
         mkt.REVIEWED_SCORES.get(mkt.REVIEWED_APP_ABUSE_REPORT))
     eq_(score.note_key, mkt.REVIEWED_APP_ABUSE_REPORT)
Beispiel #54
0
 def test_award_additional_review_points(self):
     ReviewerScore.award_additional_review_points(self.user, self.app,
                                                  QUEUE_TARAKO)
     score = ReviewerScore.objects.all()[0]
     eq_(score.score, mkt.REVIEWED_SCORES.get(mkt.REVIEWED_WEBAPP_TARAKO))
     eq_(score.note_key, mkt.REVIEWED_WEBAPP_TARAKO)
Beispiel #55
0
def leaderboard(request):
    return render(
        request, 'reviewers/leaderboard.html',
        context(request, **{'scores': ReviewerScore.all_users_by_score()}))
Beispiel #56
0
def _review(request, addon, version):

    if (not settings.ALLOW_SELF_REVIEWS
            and not acl.action_allowed(request, 'Admin', '%')
            and addon.has_author(request.user)):
        messages.warning(request, _('Self-reviews are not allowed.'))
        return redirect(reverse('reviewers.home'))

    if (addon.status == amo.STATUS_BLOCKED
            and not acl.action_allowed(request, 'Apps', 'ReviewEscalated')):
        messages.warning(
            request, _('Only senior reviewers can review blocklisted apps.'))
        return redirect(reverse('reviewers.home'))

    attachment_formset = CommAttachmentFormSet(data=request.POST or None,
                                               files=request.FILES or None,
                                               prefix='attachment')
    form = forms.get_review_form(data=request.POST or None,
                                 files=request.FILES or None,
                                 request=request,
                                 addon=addon,
                                 version=version,
                                 attachment_formset=attachment_formset)
    postdata = request.POST if request.method == 'POST' else None
    all_forms = [form, attachment_formset]

    if version:
        features_list = [unicode(f) for f in version.features.to_list()]
        appfeatures_form = AppFeaturesForm(data=postdata,
                                           instance=version.features)
        all_forms.append(appfeatures_form)
    else:
        appfeatures_form = None
        features_list = None

    queue_type = form.helper.review_type
    redirect_url = reverse('reviewers.apps.queue_%s' % queue_type)
    is_admin = acl.action_allowed(request, 'Apps', 'Edit')

    if request.method == 'POST' and all(f.is_valid() for f in all_forms):

        old_types = set(o.id for o in addon.device_types)
        new_types = set(form.cleaned_data.get('device_override'))

        old_features = set(features_list)
        new_features = set(
            unicode(f) for f in appfeatures_form.instance.to_list())

        if form.cleaned_data.get('action') == 'public':
            if old_types != new_types:
                # The reviewer overrode the device types. We need to not
                # publish this app immediately.
                if addon.publish_type == amo.PUBLISH_IMMEDIATE:
                    addon.update(publish_type=amo.PUBLISH_PRIVATE)

                # And update the device types to what the reviewer set.
                AddonDeviceType.objects.filter(addon=addon).delete()
                for device in form.cleaned_data.get('device_override'):
                    addon.addondevicetype_set.create(device_type=device)

                # Log that the reviewer changed the device types.
                added_devices = new_types - old_types
                removed_devices = old_types - new_types
                msg = _(
                    u'Device(s) changed by '
                    u'reviewer: {0}'
                ).format(', '.join([
                    _(u'Added {0}').format(unicode(amo.DEVICE_TYPES[d].name))
                    for d in added_devices
                ] + [
                    _(u'Removed {0}').format(unicode(amo.DEVICE_TYPES[d].name))
                    for d in removed_devices
                ]))

                log_reviewer_action(addon, request.user, msg,
                                    amo.LOG.REVIEW_DEVICE_OVERRIDE)

            if old_features != new_features:
                # The reviewer overrode the requirements. We need to not
                # publish this app immediately.
                if addon.publish_type == amo.PUBLISH_IMMEDIATE:
                    addon.update(publish_type=amo.PUBLISH_PRIVATE)

                appfeatures_form.save(mark_for_rereview=False)

                # Log that the reviewer changed the minimum requirements.
                added_features = new_features - old_features
                removed_features = old_features - new_features

                fmt = ', '.join(
                    [_(u'Added {0}').format(f) for f in added_features] +
                    [_(u'Removed {0}').format(f) for f in removed_features])
                # L10n: {0} is the list of requirements changes.
                msg = _(u'Requirements changed by reviewer: {0}').format(fmt)

                log_reviewer_action(addon, request.user, msg,
                                    amo.LOG.REVIEW_FEATURES_OVERRIDE)

        score = form.helper.process()

        if form.cleaned_data.get('notify'):
            # TODO: bug 741679 for implementing notifications in Marketplace.
            EditorSubscription.objects.get_or_create(user=request.user,
                                                     addon=addon)

        is_tarako = form.cleaned_data.get('is_tarako', False)
        if is_tarako:
            Tag(tag_text='tarako').save_tag(addon)
        else:
            Tag(tag_text='tarako').remove_tag(addon)

        # Success message.
        if score:
            score = ReviewerScore.objects.filter(user=request.user)[0]
            # L10N: {0} is the type of review. {1} is the points they earned.
            #       {2} is the points they now have total.
            success = _(
                u'"{0}" successfully processed (+{1} points, {2} total).'.
                format(unicode(amo.REVIEWED_CHOICES[score.note_key]),
                       score.score, ReviewerScore.get_total(request.user)))
        else:
            success = _('Review successfully processed.')
        messages.success(request, success)

        return redirect(redirect_url)

    canned = CannedResponse.objects.all()
    actions = form.helper.actions.items()

    try:
        if not version:
            raise Version.DoesNotExist
        show_diff = (addon.versions.exclude(id=version.id).filter(
            files__isnull=False,
            created__lt=version.created,
            files__status=amo.STATUS_PUBLIC).latest())
    except Version.DoesNotExist:
        show_diff = None

    # The actions we should show a minimal form from.
    actions_minimal = [k for (k, a) in actions if not a.get('minimal')]

    # We only allow the user to check/uncheck files for "pending"
    allow_unchecking_files = form.helper.review_type == "pending"

    versions = (Version.with_deleted.filter(
        addon=addon).order_by('-created').transform(
            Version.transformer_activity).transform(Version.transformer))

    product_attrs = {
        'product':
        json.dumps(product_as_dict(request, addon, False, 'reviewer'),
                   cls=JSONEncoder),
        'manifest_url':
        addon.manifest_url,
    }

    pager = paginate(request, versions, 10)

    num_pages = pager.paginator.num_pages
    count = pager.paginator.count

    ctx = context(request,
                  version=version,
                  product=addon,
                  pager=pager,
                  num_pages=num_pages,
                  count=count,
                  form=form,
                  canned=canned,
                  is_admin=is_admin,
                  status_types=amo.STATUS_CHOICES,
                  show_diff=show_diff,
                  allow_unchecking_files=allow_unchecking_files,
                  actions=actions,
                  actions_minimal=actions_minimal,
                  tab=queue_type,
                  product_attrs=product_attrs,
                  attachment_formset=attachment_formset,
                  appfeatures_form=appfeatures_form)

    if features_list is not None:
        ctx['feature_list'] = features_list

    return render(request, 'reviewers/review.html', ctx)