def process_public(self, auto_validation=False): """Set an addons files to public.""" if self.review_type == "preliminary": raise AssertionError("Preliminary addons cannot be made public.") # Sign addon. for file_ in self.files: sign_file(file_, settings.SIGNING_SERVER) # Hold onto the status before we change it. status = self.addon.status self.set_files(amo.STATUS_PUBLIC, self.files, copy_to_mirror=True) self.log_action(amo.LOG.APPROVE_VERSION) template = u"%s_to_public" % self.review_type subject = u"Mozilla Add-ons: %s %s Fully Reviewed" if not self.addon.is_listed: template = u"unlisted_to_reviewed" if auto_validation: template = u"unlisted_to_reviewed_auto" subject = u"Mozilla Add-ons: %s %s signed and ready to download" self.notify_email(template, subject) log.info(u"Making %s files %s public" % (self.addon, ", ".join([f.filename for f in self.files]))) log.info(u"Sending email for %s" % (self.addon)) # Assign reviewer incentive scores. if self.request and not auto_validation: ReviewerScore.award_points(self.request.user, self.addon, status)
def performance(request, user_id=False): user = request.amo_user editors = _recent_editors() is_admin = acl.action_allowed(request, "Admin", "%") if is_admin and user_id: try: user = UserProfile.objects.get(pk=user_id) except UserProfile.DoesNotExist: pass # Use request.amo_user from above. monthly_data = _performance_by_month(user.id) performance_total = _performance_total(monthly_data) point_total = ReviewerScore.get_total(user) point_breakdown = ReviewerScore.get_breakdown(user) data = context( monthly_data=json.dumps(monthly_data), performance_month=performance_total["month"], performance_year=performance_total["year"], point_breakdown=point_breakdown, point_total=point_total, editors=editors, current_user=user, is_admin=is_admin, is_user=(request.amo_user.id == user.id), ) return jingo.render(request, "editors/performance.html", data)
def process_sandbox(self): """Set an addon back to sandbox.""" # Hold onto the status before we change it. status = self.addon.status if not self.is_upgrade or not self.addon.versions.exclude(id=self.version.id).filter( files__status__in=amo.REVIEWED_STATUSES ): self.set_addon(status=amo.STATUS_NULL) else: self.set_addon(status=amo.STATUS_LITE) self.set_files(amo.STATUS_DISABLED, self.files, hide_disabled_file=True) self.log_action(amo.LOG.REJECT_VERSION) template = u"%s_to_sandbox" % self.review_type subject = u"Mozilla Add-ons: %s %s Rejected" if not self.addon.is_listed: template = u"unlisted_to_sandbox" subject = u"Mozilla Add-ons: %s %s didn't pass review" self.notify_email(template, subject) log.info(u"Making %s disabled" % (self.addon)) log.info(u"Sending email for %s" % (self.addon)) # Assign reviewer incentive scores. if self.request: ReviewerScore.award_points(self.request.user, self.addon, status)
def process_preliminary(self, auto_validation=False): """Set an addon to preliminary.""" # Sign addon. for file_ in self.files: sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER) # Hold onto the status before we change it. status = self.addon.status changes = {"status": amo.STATUS_LITE} if self.addon.status in (amo.STATUS_PUBLIC, amo.STATUS_LITE_AND_NOMINATED): changes["highest_status"] = amo.STATUS_LITE template = u"%s_to_preliminary" % self.review_type subject = u"Mozilla Add-ons: %s %s Preliminary Reviewed" if self.review_type == "preliminary" and self.addon.status == amo.STATUS_LITE_AND_NOMINATED: template = u"nominated_to_nominated" if not self.addon.is_listed: template = u"unlisted_to_reviewed" if auto_validation: template = u"unlisted_to_reviewed_auto" subject = u"Mozilla Add-ons: %s %s signed and ready to download" self.set_addon(**changes) self.set_files(amo.STATUS_LITE, self.files, copy_to_mirror=True) self.log_action(amo.LOG.PRELIMINARY_VERSION) self.notify_email(template, subject) log.info(u"Making %s preliminary" % (self.addon)) log.info(u"Sending email for %s" % (self.addon)) if self.request and not auto_validation: # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.user, self.addon, status)
def process_public(self): """Set an addons files to public.""" if self.review_type == 'preliminary': raise AssertionError('Preliminary addons cannot be made public.') # Sign addon. for file_ in self.files: sign_file(file_, settings.SIGNING_SERVER) # Hold onto the status before we change it. status = self.addon.status self.set_files(amo.STATUS_PUBLIC, self.files, copy_to_mirror=True) self.log_action(amo.LOG.APPROVE_VERSION) template = u'%s_to_public' % self.review_type subject = u'Mozilla Add-ons: %s %s Fully Reviewed' if not self.addon.is_listed: template = u'unlisted_to_reviewed' subject = u'Mozilla Add-ons: %s %s signed and ready to download' self.notify_email(template, subject) log.info(u'Making %s files %s public' % (self.addon, ', '.join([f.filename for f in self.files]))) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. if self.request: ReviewerScore.award_points(self.request.amo_user, self.addon, status)
def save(self): action = self.cleaned_data['action'] comment = self.cleaned_data.get('comment') reject_reason = self.cleaned_data.get('reject_reason') theme = self.cleaned_data['theme'] is_rereview = ( theme.rereviewqueuetheme_set.exists() and theme.addon.status not in (amo.STATUS_PENDING, amo.STATUS_REVIEW_PENDING)) theme_lock = ThemeLock.objects.get(theme=self.cleaned_data['theme']) mail_and_log = True if action == rvw.ACTION_APPROVE: if is_rereview: approve_rereview(theme) theme.addon.update(status=amo.STATUS_PUBLIC) theme.approve = datetime.datetime.now() theme.save() elif action == rvw.ACTION_REJECT: if is_rereview: reject_rereview(theme) else: theme.addon.update(status=amo.STATUS_REJECTED) elif action == rvw.ACTION_DUPLICATE: if is_rereview: reject_rereview(theme) else: theme.addon.update(status=amo.STATUS_REJECTED) elif action == rvw.ACTION_FLAG: if is_rereview: mail_and_log = False else: theme.addon.update(status=amo.STATUS_REVIEW_PENDING) elif action == rvw.ACTION_MOREINFO: if not is_rereview: theme.addon.update(status=amo.STATUS_REVIEW_PENDING) if mail_and_log: send_mail(self.cleaned_data, theme_lock) # Log. amo.log(amo.LOG.THEME_REVIEW, theme.addon, details={ 'theme': theme.addon.name.localized_string, 'action': action, 'reject_reason': reject_reason, 'comment': comment}, user=theme_lock.reviewer) log.info('%sTheme %s (%s) - %s' % ( '[Rereview] ' if is_rereview else '', theme.addon.name, theme.id, action)) if action not in [rvw.ACTION_MOREINFO, rvw.ACTION_FLAG]: ReviewerScore.award_points(theme_lock.reviewer, theme.addon, theme.addon.status) theme_lock.delete()
def process_preliminary(self, auto_validation=False): """Set an addons files to preliminary.""" # Sign addon. for file_ in self.files: sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER) # Hold onto the status before we change it. status = self.addon.status self.set_files(amo.STATUS_LITE, self.files, copy_to_mirror=True) self.log_action(amo.LOG.PRELIMINARY_VERSION) template = u'%s_to_preliminary' % self.review_type subject = u'Mozilla Add-ons: %s %s Preliminary Reviewed' if not self.addon.is_listed: template = u'unlisted_to_reviewed' if auto_validation: template = u'unlisted_to_reviewed_auto' subject = u'Mozilla Add-ons: %s %s signed and ready to download' self.notify_email(template, subject) log.info(u'Making %s files %s preliminary' % (self.addon, ', '.join([f.filename for f in self.files]))) log.info(u'Sending email for %s' % (self.addon)) if self.request and not auto_validation: # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.amo_user, self.addon, status)
def process_sandbox(self): """Set an addons files to sandbox.""" # Hold onto the status before we change it. status = self.addon.status self.set_files(amo.STATUS_DISABLED, self.files, hide_disabled_file=True) self.log_action(amo.LOG.REJECT_VERSION) template = u'%s_to_sandbox' % self.review_type subject = u'Mozilla Add-ons: %s %s Rejected' if not self.addon.is_listed: template = u'unlisted_to_sandbox' subject = u'Mozilla Add-ons: %s %s didn\'t pass review' self.notify_email(template, subject) log.info(u'Making %s files %s disabled' % (self.addon, ', '.join([f.filename for f in self.files]))) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. if self.request: ReviewerScore.award_points(self.request.amo_user, self.addon, status)
def process_clear_rereview(self): """Clear app from re-review queue.""" RereviewQueue.objects.filter(addon=self.addon).delete() self.log_action(amo.LOG.REREVIEW_CLEARED) log.info(u"Re-review cleared for app: %s" % self.addon) # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.amo_user, self.addon, self.addon.status, in_rereview=True)
def process_public(self, auto_validation=False): """Set an addon to public.""" if self.review_type == 'preliminary': raise AssertionError('Preliminary addons cannot be made public.') # Sign addon. for file_ in self.files: sign_file(file_, settings.SIGNING_SERVER) # Hold onto the status before we change it. status = self.addon.status # Save files first, because set_addon checks to make sure there # is at least one public file or it won't make the addon public. self.set_files(amo.STATUS_PUBLIC, self.files, copy_to_mirror=True) self.set_addon(highest_status=amo.STATUS_PUBLIC, status=amo.STATUS_PUBLIC) self.log_action(amo.LOG.APPROVE_VERSION) template = u'%s_to_public' % self.review_type subject = u'Mozilla Add-ons: %s %s Fully Reviewed' if not self.addon.is_listed: template = u'unlisted_to_reviewed' if auto_validation: template = u'unlisted_to_reviewed_auto' subject = u'Mozilla Add-ons: %s %s signed and ready to download' self.notify_email(template, subject) log.info(u'Making %s public' % (self.addon)) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. if self.request and not auto_validation: ReviewerScore.award_points(self.request.user, self.addon, status)
def eventlog_detail(request, id): log = get_object_or_404(ActivityLog.objects.editor_events(), pk=id) review = None # I really cannot express the depth of the insanity incarnate in # our logging code... if len(log.arguments) > 1 and isinstance(log.arguments[1], Review): review = log.arguments[1] 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': # A Form seems overkill for this. if request.POST['action'] == 'undelete': if not can_undelete: raise PermissionDenied ReviewerScore.award_moderation_points( log.user, review.addon, review.id, undo=True) review.undelete() return redirect('editors.eventlog.detail', id) data = context(request, log=log, can_undelete=can_undelete) return render(request, 'editors/eventlog_detail.html', data)
def process_sandbox(self): """Reject an app.""" # Hold onto the status before we change it. status = self.addon.status self.set_files(amo.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=amo.REVIEWED_STATUSES).exists()): self.set_addon(status=amo.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.log_action(amo.LOG.REJECT_VERSION) self.notify_email('pending_to_sandbox', u'Submission Update: %s') log.info(u'Making %s disabled' % self.addon) log.info(u'Sending email for %s' % self.addon) # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.amo_user, self.addon, status, in_rereview=self.in_rereview) self.create_comm_thread(action='reject')
def process_sandbox(self): """Set an addon back to sandbox.""" # Hold onto the status before we change it. status = self.addon.status if (not self.is_upgrade or not self.addon.versions.exclude(id=self.version.id) .filter(files__status__in=amo.REVIEWED_STATUSES)): self.set_addon(status=amo.STATUS_NULL) else: self.set_addon(status=amo.STATUS_LITE) self.set_files(amo.STATUS_DISABLED, self.version.files.all(), hide_disabled_file=True) self.log_action(amo.LOG.REJECT_VERSION) self.notify_email('%s_to_sandbox' % self.review_type, u'Mozilla Add-ons: %s %s Rejected') log.info(u'Making %s disabled' % (self.addon)) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.amo_user, self.addon, status)
def process_preliminary(self): """Set an addon to preliminary.""" # Hold onto the status before we change it. status = self.addon.status changes = {'status': amo.STATUS_LITE} if (self.addon.status in (amo.STATUS_PUBLIC, amo.STATUS_LITE_AND_NOMINATED)): changes['highest_status'] = amo.STATUS_LITE template = '%s_to_preliminary' % self.review_type if (self.review_type == 'preliminary' and self.addon.status == amo.STATUS_LITE_AND_NOMINATED): template = 'nominated_to_nominated' self.set_addon(**changes) self.set_files(amo.STATUS_LITE, self.version.files.all(), copy_to_mirror=True) self.log_action(amo.LOG.PRELIMINARY_VERSION) self.notify_email(template, u'Mozilla Add-ons: %s %s Preliminary Reviewed') log.info(u'Making %s preliminary' % (self.addon)) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.amo_user, self.addon, status)
def reviewers_score_bar(context): user = context.get('amo_user') return new_context(dict( amo=amo, points=ReviewerScore.get_recent(user), total=ReviewerScore.get_total(user), **ReviewerScore.get_leaderboards(user)))
def reviewers_score_bar(context, types=None): user = context.get('amo_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)))
def test_get_total(self): user2 = UserProfile.objects.get(email="*****@*****.**") self._give_points() self._give_points(status=amo.STATUS_LITE) self._give_points(user=user2, status=amo.STATUS_NOMINATED) eq_( ReviewerScore.get_total(self.user), amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL] + amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_PRELIM], ) eq_(ReviewerScore.get_total(user2), amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL])
def performance(request, user_id=False): user = request.amo_user editors = _recent_editors() is_admin = (acl.action_allowed(request, 'Admin', '%') or acl.action_allowed(request, 'ReviewerAdminTools', 'View')) if is_admin and user_id: try: user = UserProfile.objects.get(pk=user_id) except UserProfile.DoesNotExist: pass # Use request.amo_user from above. monthly_data = _performance_by_month(user.id) performance_total = _performance_total(monthly_data) # Incentive point breakdown. today = date.today() month_ago = today - timedelta(days=30) year_ago = today - timedelta(days=365) point_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), 'themes': _sum(months, amo.GROUP_TYPE_THEME), }, 'year': { 'addons': _sum(years, amo.GROUP_TYPE_ADDON), 'apps': _sum(years, amo.GROUP_TYPE_WEBAPP), 'themes': _sum(years, amo.GROUP_TYPE_THEME), }, 'total': { 'addons': _sum(totals, amo.GROUP_TYPE_ADDON), 'apps': _sum(totals, amo.GROUP_TYPE_WEBAPP), 'themes': _sum(totals, amo.GROUP_TYPE_THEME), } } data = context(monthly_data=json.dumps(monthly_data), performance_month=performance_total['month'], performance_year=performance_total['year'], breakdown=breakdown, point_total=point_total, editors=editors, current_user=user, is_admin=is_admin, is_user=(request.amo_user.id == user.id)) return render(request, 'editors/performance.html', data)
def test_get_total(self): waffle.models.Switch.objects.create(name='reviewer-incentive-points', active=True) user2 = UserProfile.objects.get(email='*****@*****.**') self._give_points() self._give_points(event=amo.REVIEWED_ADDON_PRELIM) self._give_points(user=user2) eq_(ReviewerScore.get_total(self.user), amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL] + amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_PRELIM]) eq_(ReviewerScore.get_total(user2), amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL])
def process_public(self): if self.addon.make_public == amo.PUBLIC_IMMEDIATELY: self.process_public_immediately() else: self.process_public_waiting() if self.in_escalate: EscalationQueue.objects.filter(addon=self.addon).delete() # Assign reviewer incentive scores. event = ReviewerScore.get_event_by_type(self.addon) ReviewerScore.award_points(self.request.amo_user, self.addon, event)
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) ) )
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), 'themes': _sum(months, amo.GROUP_TYPE_THEME), }, 'year': { 'addons': _sum(years, amo.GROUP_TYPE_ADDON), 'apps': _sum(years, amo.GROUP_TYPE_WEBAPP), 'themes': _sum(years, amo.GROUP_TYPE_THEME), }, 'total': { 'addons': _sum(totals, amo.GROUP_TYPE_ADDON), 'apps': _sum(totals, amo.GROUP_TYPE_WEBAPP), 'themes': _sum(totals, amo.GROUP_TYPE_THEME), } } ctx = context(request, **{ 'profile': user, 'total': total, 'breakdown': breakdown, }) return jingo.render(request, 'reviewers/performance.html', ctx)
def process_public_waiting(self): """Make an app pending.""" self.set_files(amo.STATUS_PUBLIC_WAITING, self.version.files.all()) self.set_addon(highest_status=amo.STATUS_PUBLIC_WAITING, status=amo.STATUS_PUBLIC_WAITING) self.log_action(amo.LOG.APPROVE_VERSION_WAITING) self.notify_email("%s_to_public_waiting" % self.review_type, u"App Approved but waiting: %s") log.info(u"Making %s public but pending" % self.addon) log.info(u"Sending email for %s" % self.addon) # Assign reviewer incentive scores. event = ReviewerScore.get_event_by_type(self.addon) ReviewerScore.award_points(self.request.amo_user, self.addon, event)
def process_public(self): # 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_public_waiting() if self.in_escalate: EscalationQueue.objects.filter(addon=self.addon).delete() # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.amo_user, self.addon, status)
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)
def process_public(self): """ Makes an app public or public waiting. Changes status to Public/Public Waiting. Creates Approval note/email. """ if self.addon.has_incomplete_status(): # Failsafe. return # Create thread. self._create_comm_note(comm.APPROVAL) # 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_public_waiting() if self.in_escalate: EscalationQueue.objects.filter(addon=self.addon).delete() # Assign reviewer incentive scores. return ReviewerScore.award_points(self.request.amo_user, self.addon, status)
def process_public_waiting(self): """Make an app pending.""" self.set_files(amo.STATUS_PUBLIC_WAITING, self.version.files.all()) self.set_addon(highest_status=amo.STATUS_PUBLIC_WAITING, status=amo.STATUS_PUBLIC_WAITING) self.log_action(amo.LOG.APPROVE_VERSION_WAITING) self.notify_email('%s_to_public_waiting' % self.review_type, u'App Approved but waiting: %s') log.info(u'Making %s public but pending' % self.addon) log.info(u'Sending email for %s' % self.addon) # Assign reviewer incentive scores. event = ReviewerScore.get_event_by_type(self.addon) ReviewerScore.award_points(self.request.amo_user, self.addon, event)
def themes_commit(request): reviewer = request.user.get_profile() ThemeReviewFormset = formset_factory(forms.ThemeReviewForm) formset = ThemeReviewFormset(request.POST) scores = [] for form in formset: try: lock = ThemeLock.objects.filter( theme_id=form.data[form.prefix + '-theme'], reviewer=reviewer) except MultiValueDictKeyError: # Address off-by-one error caused by management form. continue if lock and form.is_valid(): scores.append(form.save()) # Success message. points = sum(scores) success = ngettext( # L10n: {0} is the number of reviews. {1} is the points just earned. # L10n: {2} is the total number of points the reviewer has overall. '{0} theme review successfully processed (+{1} points, {2} total).', '{0} theme reviews successfully processed (+{1} points, {2} total).', len(scores)).format(len(scores), points, ReviewerScore.get_total(request.amo_user)) amo.messages.success(request, success) if 'theme_redirect_url' in request.session: return redirect(request.session['theme_redirect_url']) else: return redirect(reverse('editors.themes.queue_themes'))
def test_get_breakdown(self): self._give_points() self._give_points(addon=amo.tests.app_factory()) breakdown = ReviewerScore.get_breakdown(self.user) eq_(len(breakdown), 2) eq_(set([b.atype for b in breakdown]), set([amo.ADDON_EXTENSION, amo.ADDON_WEBAPP]))
def themes_commit(request): reviewer = request.user.get_profile() ThemeReviewFormset = formset_factory(forms.ThemeReviewForm) formset = ThemeReviewFormset(request.POST) scores = [] for form in formset: try: lock = ThemeLock.objects.filter(theme_id=form.data[form.prefix + '-theme'], reviewer=reviewer) except MultiValueDictKeyError: # Address off-by-one error caused by management form. continue if lock and form.is_valid(): scores.append(form.save()) # Success message. points = sum(scores) success = ngettext( # L10n: {0} is the number of reviews. {1} is the points just earned. # L10n: {2} is the total number of points the reviewer has overall. '{0} theme review successfully processed (+{1} points, {2} total).', '{0} theme reviews successfully processed (+{1} points, {2} total).', len(scores)).format(len(scores), points, ReviewerScore.get_total(request.amo_user)) amo.messages.success(request, success) if 'theme_redirect_url' in request.session: return redirect(request.session['theme_redirect_url']) else: return redirect(reverse('reviewers.themes.queue_themes'))
def process_reject(self): """ Reject an app. Changes status to Rejected. Creates Rejection note/email. """ # Hold onto the status before we change it. status = self.addon.status self.set_files(amo.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=amo.REVIEWED_STATUSES).exists()): self.set_addon(status=amo.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.log_action(amo.LOG.REJECT_VERSION) self._create_comm_note(comm.REJECTION) self.notify_email('pending_to_sandbox', u'Submission Update: %s') log.info(u'Making %s disabled' % self.addon) # Assign reviewer incentive scores. return ReviewerScore.award_points(self.request.amo_user, self.addon, status, in_rereview=self.in_rereview)
def test_no_amo_points_in_marketplace_leaderboards(self): user2 = UserProfile.objects.get(email="*****@*****.**") self._give_points() self._give_points(status=amo.STATUS_LITE) self._give_points(addon=self.app, status=amo.STATUS_NOMINATED) leaders = ReviewerScore.get_leaderboards(self.user, types=amo.REVIEWED_MARKETPLACE) eq_(leaders["leader_top"][0]["total"], amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED])
def process_public(self): """ Makes an app public or public waiting. 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_public_waiting() 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)
def leaderboard(request): return jingo.render( request, 'reviewers/leaderboard.html', context(**{ 'scores': ReviewerScore.all_users_by_score(), }))
def check_event(self, type, status, event, **kwargs): self.addon.type = type eq_( ReviewerScore.get_event(self.addon, status, **kwargs), event, ("Score event for type:%s and status:%s was not %s" % (type, status, event)), )
def test_no_amo_points_in_marketplace_leaderboards(self): self._give_points() self._give_points(status=amo.STATUS_LITE) self._give_points(addon=self.app, status=amo.STATUS_NOMINATED) leaders = ReviewerScore.get_leaderboards( self.user, types=amo.REVIEWED_MARKETPLACE) eq_(leaders['leader_top'][0]['total'], amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED])
def save(self): action = self.cleaned_data['action'] comment = self.cleaned_data.get('comment') reject_reason = self.cleaned_data.get('reject_reason') theme = self.cleaned_data['theme'] is_rereview = ( theme.rereviewqueuetheme_set.exists() and theme.addon.status not in (amo.STATUS_PENDING, amo.STATUS_REVIEW_PENDING)) theme_lock = ThemeLock.objects.get(theme=self.cleaned_data['theme']) mail_and_log = True if action == rvw.ACTION_APPROVE: if is_rereview: approve_rereview(theme) theme.addon.update(status=amo.STATUS_PUBLIC) theme.approve = datetime.datetime.now() theme.save() elif action in (rvw.ACTION_REJECT, rvw.ACTION_DUPLICATE): if is_rereview: reject_rereview(theme) else: theme.addon.update(status=amo.STATUS_REJECTED) elif action == rvw.ACTION_FLAG: if is_rereview: mail_and_log = False else: theme.addon.update(status=amo.STATUS_REVIEW_PENDING) elif action == rvw.ACTION_MOREINFO: if not is_rereview: theme.addon.update(status=amo.STATUS_REVIEW_PENDING) if mail_and_log: send_mail(self.cleaned_data, theme_lock) # Log. amo.log(amo.LOG.THEME_REVIEW, theme.addon, details={ 'theme': theme.addon.name.localized_string, 'action': action, 'reject_reason': reject_reason, 'comment': comment}, user=theme_lock.reviewer) log.info('%sTheme %s (%s) - %s' % ( '[Rereview] ' if is_rereview else '', theme.addon.name, theme.id, action)) score = 0 if action in (rvw.ACTION_REJECT, rvw.ACTION_DUPLICATE, rvw.ACTION_APPROVE): score = ReviewerScore.award_points(theme_lock.reviewer, theme.addon, theme.addon.status) theme_lock.delete() return score
def save(self): from reviews.helpers import user_can_delete_review 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 != reviews.REVIEW_MODERATE_SKIP: # Delete flags. for flag in form.instance.reviewflag_set.all(): flag.delete() review = form.instance addon = review.addon if action == reviews.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.amo_user, addon, review_id) elif action == reviews.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.amo_user, addon, review.id)
def process_public_immediately(self): """Approve an app.""" # Save files first, because set_addon checks to make sure there # is at least one public file or it won't make the addon public. self.set_files(amo.STATUS_PUBLIC, self.version.files.all()) self.set_addon(highest_status=amo.STATUS_PUBLIC, status=amo.STATUS_PUBLIC) self.log_action(amo.LOG.APPROVE_VERSION) self.notify_email('%s_to_public' % self.review_type, u'App Approved: %s') log.info(u'Making %s public' % self.addon) log.info(u'Sending email for %s' % self.addon) # Assign reviewer incentive scores. event = ReviewerScore.get_event_by_type(self.addon) ReviewerScore.award_points(self.request.amo_user, self.addon, event)
def test_get_breakdown_since(self): self._give_points() self._give_points(addon=amo.tests.app_factory()) 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])
def test_no_amo_points_in_marketplace_leaderboards(self): user2 = UserProfile.objects.get(email='*****@*****.**') self._give_points() self._give_points(status=amo.STATUS_LITE) self._give_points(addon=self.app, status=amo.STATUS_NOMINATED) leaders = ReviewerScore.get_leaderboards( self.user, types=amo.REVIEWED_MARKETPLACE) eq_(leaders['leader_top'][0]['total'], amo.REVIEWED_SCORES[amo.REVIEWED_WEBAPP_HOSTED])
def test_no_marketplace_points_in_amo_leaderboards(self): self._give_points() self._give_points(status=amo.STATUS_LITE) self._give_points(addon=self.app, status=amo.STATUS_NOMINATED) leaders = ReviewerScore.get_leaderboards(self.user, types=amo.REVIEWED_AMO) eq_(leaders['leader_top'][0]['total'], amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL] + amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_PRELIM])
def process_sandbox(self): """Set an addons files to sandbox.""" # Hold onto the status before we change it. status = self.addon.status self.set_files(amo.STATUS_DISABLED, self.data['addon_files'], hide_disabled_file=True) self.log_action(amo.LOG.REJECT_VERSION) self.notify_email('%s_to_sandbox' % self.review_type, u'Mozilla Add-ons: %s %s Rejected') log.info(u'Making %s files %s disabled' % (self.addon, ', '.join( [f.filename for f in self.data['addon_files']]))) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.amo_user, self.addon, status)
def process_clear_rereview(self): """Clear app from re-review queue.""" RereviewQueue.objects.filter(addon=self.addon).delete() self.log_action(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.amo_user, self.addon, self.addon.status, in_rereview=True)
def process_preliminary(self): """Set an addons files to preliminary.""" # Hold onto the status before we change it. status = self.addon.status self.set_files(amo.STATUS_LITE, self.data['addon_files'], copy_to_mirror=True) self.log_action(amo.LOG.PRELIMINARY_VERSION) self.notify_email('%s_to_preliminary' % self.review_type, u'Mozilla Add-ons: %s %s Preliminary Reviewed') log.info(u'Making %s files %s preliminary' % (self.addon, ', '.join( [f.filename for f in self.data['addon_files']]))) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.amo_user, self.addon, status)
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(status=amo.STATUS_LITE) self._give_points(user=user2) scores = ReviewerScore.get_recent(self.user) eq_(len(scores), 2) eq_(scores[0].score, amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_PRELIM]) eq_(scores[1].score, amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL])
def process_public(self): """Set an addons files to public.""" if self.review_type == 'preliminary': raise AssertionError('Preliminary addons cannot be made public.') self.set_files(amo.STATUS_PUBLIC, self.data['addon_files'], copy_to_mirror=True) self.log_action(amo.LOG.APPROVE_VERSION) self.notify_email('%s_to_public' % self.review_type, u'Mozilla Add-ons: %s %s Fully Reviewed') log.info(u'Making %s files %s public' % (self.addon, ', '.join([f.filename for f in self.data['addon_files']]))) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. event = ReviewerScore.get_event_by_type(self.addon, self.review_type) ReviewerScore.award_points(self.request.amo_user, self.addon, event)
def process_preliminary(self): """Set an addons files to preliminary.""" if self.addon.is_premium(): raise AssertionError('Premium add-ons cannot become preliminary.') self.set_files(amo.STATUS_LITE, self.data['addon_files'], copy_to_mirror=True) self.log_action(amo.LOG.PRELIMINARY_VERSION) self.notify_email('%s_to_preliminary' % self.review_type, u'Mozilla Add-ons: %s %s Preliminary Reviewed') log.info(u'Making %s files %s preliminary' % (self.addon, ', '.join([f.filename for f in self.data['addon_files']]))) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. event = ReviewerScore.get_event_by_type(self.addon, self.review_type) ReviewerScore.award_points(self.request.amo_user, self.addon, event)
def test_no_admins_or_staff_in_leaderboards(self): user2 = UserProfile.objects.get(email='*****@*****.**') self._give_points() self._give_points(status=amo.STATUS_LITE) self._give_points(user=user2, status=amo.STATUS_NOMINATED) 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.')
def test_get_recent(self): waffle.models.Switch.objects.create(name='reviewer-incentive-points', active=True) user2 = UserProfile.objects.get(email='*****@*****.**') self._give_points() time.sleep(1) # Wait 1 sec so ordering by created is checked. self._give_points(event=amo.REVIEWED_ADDON_PRELIM) self._give_points(user=user2) scores = ReviewerScore.get_recent(self.user) eq_(len(scores), 2) eq_(scores[0].score, amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_PRELIM]) eq_(scores[1].score, amo.REVIEWED_SCORES[amo.REVIEWED_ADDON_FULL])
def _batch_award_points(activity_log_ids, **kwargs): """For command award_theme_points.""" activity_logs = (ActivityLog.objects.filter(id__in=activity_log_ids) .select_related('user')) score = amo.REVIEWED_SCORES.get(amo.REVIEWED_PERSONA) ReviewerScore.objects.bulk_create( [ReviewerScore(user=log.user, score=score, note='RETROACTIVE', note_key=amo.REVIEWED_PERSONA, addon_id=json.loads(log._arguments)[0]['addons.addon']) for log in activity_logs] )
def test_get_leaderboards_last(self): waffle.models.Switch.objects.create(name='reviewer-incentive-points', active=True) users = list(UserProfile.objects.all()) last_user = users.pop(len(users) - 1) for u in users: self._give_points(user=u) # Last user gets lower points by reviewing a persona. self._give_points(user=last_user, event=amo.REVIEWED_PERSONA) leaders = ReviewerScore.get_leaderboards(last_user) eq_(leaders['user_rank'], 6) eq_(len(leaders['leader_top']), 3) eq_(len(leaders['leader_near']), 2)
def process_public(self): """Set an addon to public.""" if self.review_type == 'preliminary': raise AssertionError('Preliminary addons cannot be made public.') # Save files first, because set_addon checks to make sure there # is at least one public file or it won't make the addon public. self.set_files(amo.STATUS_PUBLIC, self.version.files.all(), copy_to_mirror=True) self.set_addon(highest_status=amo.STATUS_PUBLIC, status=amo.STATUS_PUBLIC) self.log_action(amo.LOG.APPROVE_VERSION) self.notify_email('%s_to_public' % self.review_type, u'Mozilla Add-ons: %s %s Fully Reviewed') log.info(u'Making %s public' % (self.addon)) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. event = ReviewerScore.get_event_by_type(self.addon, self.review_type) ReviewerScore.award_points(self.request.amo_user, self.addon, event)
def process_preliminary(self, auto_validation=False): """Set an addon to preliminary.""" # Sign addon. for file_ in self.files: sign_file(file_, settings.PRELIMINARY_SIGNING_SERVER) # Hold onto the status before we change it. status = self.addon.status changes = {'status': amo.STATUS_LITE} if (self.addon.status in (amo.STATUS_PUBLIC, amo.STATUS_LITE_AND_NOMINATED)): changes['highest_status'] = amo.STATUS_LITE template = u'%s_to_preliminary' % self.review_type subject = u'Mozilla Add-ons: %s %s Preliminary Reviewed' if (self.review_type == 'preliminary' and self.addon.status == amo.STATUS_LITE_AND_NOMINATED): template = u'nominated_to_nominated' if not self.addon.is_listed: template = u'unlisted_to_reviewed' if auto_validation: template = u'unlisted_to_reviewed_auto' subject = u'Mozilla Add-ons: %s %s signed and ready to download' self.set_addon(**changes) self.set_files(amo.STATUS_LITE, self.files, copy_to_mirror=True) self.log_action(amo.LOG.PRELIMINARY_VERSION) self.notify_email(template, subject) log.info(u'Making %s preliminary' % (self.addon)) log.info(u'Sending email for %s' % (self.addon)) if self.request and not auto_validation: # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.amo_user, self.addon, status)
def process_sandbox(self): """Set an addons files to sandbox.""" # Hold onto the status before we change it. status = self.addon.status self.set_files(amo.STATUS_DISABLED, self.files, hide_disabled_file=True) self.log_action(amo.LOG.REJECT_VERSION) template = u'%s_to_sandbox' % self.review_type subject = u'Mozilla Add-ons: %s %s Rejected' if not self.addon.is_listed: template = u'unlisted_to_sandbox' subject = u'Mozilla Add-ons: %s %s didn\'t pass review' self.notify_email(template, subject) log.info(u'Making %s files %s disabled' % (self.addon, ', '.join([f.filename for f in self.files]))) log.info(u'Sending email for %s' % (self.addon)) # Assign reviewer incentive scores. ReviewerScore.award_points(self.request.amo_user, self.addon, status)
def test_all_users_by_score(self): user2 = UserProfile.objects.get(email='*****@*****.**') self._give_points() self._give_points(status=amo.STATUS_LITE) self._give_points(user=user2, status=amo.STATUS_NOMINATED) users = ReviewerScore.all_users_by_score() eq_(len(users), 2) # First user. eq_(users[0]['total'], 180) eq_(users[0]['user_id'], self.user.id) eq_(users[0]['level'], amo.REVIEWED_LEVELS[0]['name']) # Second user. eq_(users[1]['total'], 120) eq_(users[1]['user_id'], user2.id) eq_(users[1]['level'], '')
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 reviewing a persona. addon = self.addon addon.type = amo.ADDON_PERSONA self._give_points(user=last_user, addon=addon) leaders = ReviewerScore.get_leaderboards(last_user) eq_(leaders['user_rank'], 6) eq_(len(leaders['leader_top']), 3) eq_(len(leaders['leader_near']), 2)