def queue_counts(admin_reviewer, limited_reviewer, extension_reviews, theme_reviews): def construct_query_from_sql_model(sqlmodel): qs = sqlmodel.objects if not admin_reviewer: qs = filter_admin_review_for_legacy_queue(qs) if limited_reviewer: qs = qs.having('waiting_time_hours >=', amo.REVIEW_LIMITED_DELAY_HOURS) qs = filter_static_themes(qs, extension_reviews, theme_reviews) return qs.count expired = (Addon.objects.filter( addonreviewerflags__pending_info_request__lt=datetime.now()).order_by( 'addonreviewerflags__pending_info_request')) counts = { 'pending': construct_query_from_sql_model(ViewPendingQueue), 'nominated': construct_query_from_sql_model(ViewFullReviewQueue), 'moderated': Rating.objects.all().to_moderate().count, 'auto_approved': (AutoApprovalSummary.get_auto_approved_queue( admin_reviewer=admin_reviewer).count), 'content_review': (AutoApprovalSummary.get_content_review_queue( admin_reviewer=admin_reviewer).count), 'expired_info_requests': expired.count, } return {queue: count() for (queue, count) in counts.iteritems()}
def queue_counts(admin_reviewer, extension_reviews, theme_reviews): def construct_query_from_sql_model(sqlmodel): qs = sqlmodel.objects if not admin_reviewer: qs = filter_admin_review_for_legacy_queue(qs) qs = filter_static_themes(qs, extension_reviews, theme_reviews) return qs.count expired = (Addon.objects.filter( addonreviewerflags__pending_info_request__lt=datetime.now(), status__in=(amo.STATUS_NOMINATED, amo.STATUS_PUBLIC), disabled_by_user=False).order_by( 'addonreviewerflags__pending_info_request')) counts = { 'pending': construct_query_from_sql_model(ViewPendingQueue), 'nominated': construct_query_from_sql_model(ViewFullReviewQueue), 'moderated': Rating.objects.all().to_moderate().count, 'auto_approved': (AutoApprovalSummary.get_auto_approved_queue( admin_reviewer=admin_reviewer).count), 'content_review': (AutoApprovalSummary.get_content_review_queue( admin_reviewer=admin_reviewer).count), 'expired_info_requests': expired.count, } return {queue: count() for (queue, count) in counts.iteritems()}
def queue_counts(admin_reviewer, extension_reviews, theme_reviews): def construct_query_from_sql_model(sqlmodel): qs = sqlmodel.objects if not admin_reviewer: qs = filter_admin_review_for_legacy_queue(qs) qs = filter_static_themes(qs, extension_reviews, theme_reviews) return qs.count expired = ( Addon.objects.filter( addonreviewerflags__pending_info_request__lt=datetime.now(), status__in=(amo.STATUS_NOMINATED, amo.STATUS_PUBLIC), disabled_by_user=False) .order_by('addonreviewerflags__pending_info_request')) counts = { 'pending': construct_query_from_sql_model(ViewPendingQueue), 'nominated': construct_query_from_sql_model(ViewFullReviewQueue), 'moderated': Rating.objects.all().to_moderate().count, 'auto_approved': ( AutoApprovalSummary.get_auto_approved_queue( admin_reviewer=admin_reviewer).count), 'content_review': ( AutoApprovalSummary.get_content_review_queue( admin_reviewer=admin_reviewer).count), 'expired_info_requests': expired.count, } return {queue: count() for (queue, count) in counts.iteritems()}
def queue_counts(admin_reviewer, limited_reviewer, extension_reviews, theme_reviews): def construct_query_from_sql_model(sqlmodel): qs = sqlmodel.objects if not admin_reviewer: qs = filter_admin_review_for_legacy_queue(qs) if limited_reviewer: qs = qs.having('waiting_time_hours >=', amo.REVIEW_LIMITED_DELAY_HOURS) qs = filter_static_themes(qs, extension_reviews, theme_reviews) return qs.count expired = ( Addon.objects.filter( addonreviewerflags__pending_info_request__lt=datetime.now() ).order_by('addonreviewerflags__pending_info_request')) counts = { 'pending': construct_query_from_sql_model(ViewPendingQueue), 'nominated': construct_query_from_sql_model(ViewFullReviewQueue), 'moderated': Rating.objects.all().to_moderate().count, 'auto_approved': ( AutoApprovalSummary.get_auto_approved_queue( admin_reviewer=admin_reviewer).count), 'content_review': ( AutoApprovalSummary.get_content_review_queue( admin_reviewer=admin_reviewer).count), 'expired_info_requests': expired.count, } return {queue: count() for (queue, count) in counts.iteritems()}
def process(self, version): """Process a single version, figuring out if it should be auto-approved and calling the approval code if necessary.""" already_locked = AutoApprovalSummary.check_is_locked(version) if not already_locked: # Lock the addon for ourselves if possible. Even though # AutoApprovalSummary.create_summary_for_version() will do # call check_is_locked() again later when calculating the verdict, # we have to do it now to prevent overwriting an existing lock with # our own. set_reviewing_cache(version.addon.pk, settings.TASK_USER_ID) try: log.info('Processing %s version %s...', unicode(version.addon.name), unicode(version.version)) summary, info = AutoApprovalSummary.create_summary_for_version( version, dry_run=self.dry_run) log.info('Auto Approval for %s version %s: %s', unicode(version.addon.name), unicode(version.version), summary.get_verdict_display()) self.stats.update({k: int(v) for k, v in info.items()}) if summary.verdict == self.successful_verdict: self.stats['auto_approved'] += 1 if summary.verdict == amo.AUTO_APPROVED: self.approve(version) except (AutoApprovalNotEnoughFilesError, AutoApprovalNoValidationResultError): log.info( 'Version %s was skipped either because it had no ' 'file or because it had no validation attached.', version) self.stats['error'] += 1 finally: # Always clear our own lock no matter what happens (but only ours). if not already_locked: clear_reviewing_cache(version.addon.pk)
def process(self, version): """Process a single version, figuring out if it should be auto-approved and calling the approval code if necessary.""" already_locked = AutoApprovalSummary.check_is_locked(version) if not already_locked: # Lock the addon for ourselves if possible. Even though # AutoApprovalSummary.create_summary_for_version() will do # call check_is_locked() again later when calculating the verdict, # we have to do it now to prevent overwriting an existing lock with # our own. set_reviewing_cache(version.addon.pk, settings.TASK_USER_ID) try: with transaction.atomic(): log.info('Processing %s version %s...', six.text_type(version.addon.name), six.text_type(version.version)) summary, info = AutoApprovalSummary.create_summary_for_version( version, dry_run=self.dry_run) self.stats.update({k: int(v) for k, v in info.items()}) if summary.verdict == self.successful_verdict: if summary.verdict == amo.AUTO_APPROVED: self.approve(version) self.stats['auto_approved'] += 1 verdict_string = summary.get_verdict_display() else: verdict_string = '%s (%s)' % ( summary.get_verdict_display(), ', '.join( summary.verdict_info_prettifier(info))) log.info('Auto Approval for %s version %s: %s', six.text_type(version.addon.name), six.text_type(version.version), verdict_string) # At this point, any exception should have rolled back the transaction, # so even if we did create/update an AutoApprovalSummary instance that # should have been rolled back. This ensures that, for instance, a # signing error doesn't leave the version and its autoapprovalsummary # in conflicting states. except (AutoApprovalNotEnoughFilesError, AutoApprovalNoValidationResultError): log.info( 'Version %s was skipped either because it had no ' 'files or because it had no validation attached.', version) self.stats['error'] += 1 except SigningError: log.info('Version %s was skipped because of a signing error', version) self.stats['error'] += 1 finally: # Always clear our own lock no matter what happens (but only ours). if not already_locked: clear_reviewing_cache(version.addon.pk)
def process(self, version): """Process a single version, figuring out if it should be auto-approved and calling the approval code if necessary.""" already_locked = AutoApprovalSummary.check_is_locked(version) if not already_locked: # Lock the addon for ourselves if possible. Even though # AutoApprovalSummary.create_summary_for_version() will do # call check_is_locked() again later when calculating the verdict, # we have to do it now to prevent overwriting an existing lock with # our own. set_reviewing_cache(version.addon.pk, settings.TASK_USER_ID) try: with transaction.atomic(): log.info('Processing %s version %s...', six.text_type(version.addon.name), six.text_type(version.version)) summary, info = AutoApprovalSummary.create_summary_for_version( version, dry_run=self.dry_run) log.info('Auto Approval for %s version %s: %s', six.text_type(version.addon.name), six.text_type(version.version), summary.get_verdict_display()) self.stats.update({k: int(v) for k, v in info.items()}) if summary.verdict == self.successful_verdict: if summary.verdict == amo.AUTO_APPROVED: self.approve(version) self.stats['auto_approved'] += 1 # At this point, any exception should have rolled back the transaction, # so even if we did create/update an AutoApprovalSummary instance that # should have been rolled back. This ensures that, for instance, a # signing error doesn't leave the version and its autoapprovalsummary # in conflicting states. except (AutoApprovalNotEnoughFilesError, AutoApprovalNoValidationResultError): log.info( 'Version %s was skipped either because it had no ' 'files or because it had no validation attached.', version) self.stats['error'] += 1 except SigningError: log.info( 'Version %s was skipped because of a signing error', version) self.stats['error'] += 1 finally: # Always clear our own lock no matter what happens (but only ours). if not already_locked: clear_reviewing_cache(version.addon.pk)
def queue_content_review(request): qs = (AutoApprovalSummary.get_content_review_queue().select_related( 'addonapprovalscounter').order_by( 'addonapprovalscounter__last_content_review', 'created')) return _queue(request, ContentReviewTable, 'content_review', qs=qs, SearchForm=None)
def queue_counts(type=None, unlisted=False, admin_reviewer=False, limited_reviewer=False, **kw): def construct_query_from_sql_model(sqlmodel, days_min=None, days_max=None): qs = sqlmodel.objects if not admin_reviewer: qs = filter_admin_review_for_legacy_queue(qs) if days_min: qs = qs.having('waiting_time_days >=', days_min) if days_max: qs = qs.having('waiting_time_days <=', days_max) if limited_reviewer: qs = qs.having('waiting_time_hours >=', amo.REVIEW_LIMITED_DELAY_HOURS) return qs.count expired = ( Addon.objects.filter( addonreviewerflags__pending_info_request__lt=datetime.now() ).order_by('addonreviewerflags__pending_info_request')) counts = { 'pending': construct_query_from_sql_model(ViewPendingQueue, **kw), 'nominated': construct_query_from_sql_model(ViewFullReviewQueue, **kw), 'moderated': Rating.objects.all().to_moderate().count, 'auto_approved': ( AutoApprovalSummary.get_auto_approved_queue( admin_reviewer=admin_reviewer).count), 'content_review': ( AutoApprovalSummary.get_content_review_queue( admin_reviewer=admin_reviewer).count), 'expired_info_requests': expired.count, } if unlisted: counts = { 'all': construct_query_from_sql_model(ViewUnlistedAllList) } rv = {} if isinstance(type, basestring): return counts[type]() for k, v in counts.items(): if not isinstance(type, list) or k in type: rv[k] = v() return rv
def test_no_locking_if_already_locked( self, create_summary_for_version_mock, check_is_locked_mock, clear_reviewing_cache_mock, set_reviewing_cache_mock): check_is_locked_mock.return_value = True create_summary_for_version_mock.return_value = ( AutoApprovalSummary(), {}) call_command('auto_approve') assert create_summary_for_version_mock.call_count == 1 assert set_reviewing_cache_mock.call_count == 0 assert clear_reviewing_cache_mock.call_count == 0
def queue_content_review(request): admin_reviewer = is_admin_reviewer(request) qs = ( AutoApprovalSummary.get_content_review_queue( admin_reviewer=admin_reviewer) .select_related('addonapprovalscounter') .order_by('addonapprovalscounter__last_content_review', 'created') ) return _queue(request, ContentReviewTable, 'content_review', qs=qs, SearchForm=None)
def test_successful_verdict_dry_run( self, create_summary_for_version_mock, approve_mock): create_summary_for_version_mock.return_value = ( AutoApprovalSummary(verdict=amo.WOULD_HAVE_BEEN_AUTO_APPROVED), {}) call_command('auto_approve', '--dry-run') assert approve_mock.call_count == 0 assert create_summary_for_version_mock.call_args == ( (self.version, ), {'dry_run': True}) assert get_reviewing_cache(self.addon.pk) is None self._check_stats({'total': 1, 'auto_approved': 1})
def queue_auto_approved(request): qs = (AutoApprovalSummary.get_auto_approved_queue().select_related( 'addonapprovalscounter', '_current_version__autoapprovalsummary').order_by( '-_current_version__autoapprovalsummary__weight', 'addonapprovalscounter__last_human_review', 'created')) return _queue(request, AutoApprovedTable, 'auto_approved', qs=qs, SearchForm=None)
def queue_counts(type=None, unlisted=False, admin_reviewer=False, limited_reviewer=False, **kw): def construct_query(query_type, days_min=None, days_max=None): query = query_type.objects if not admin_reviewer: query = exclude_admin_only_addons(query) if days_min: query = query.having('waiting_time_days >=', days_min) if days_max: query = query.having('waiting_time_days <=', days_max) if limited_reviewer: query = query.having('waiting_time_hours >=', amo.REVIEW_LIMITED_DELAY_HOURS) return query.count counts = { 'pending': construct_query(ViewPendingQueue, **kw), 'nominated': construct_query(ViewFullReviewQueue, **kw), 'moderated': Review.objects.all().to_moderate().count, 'auto_approved': (AutoApprovalSummary.get_auto_approved_queue().count), 'content_review': (AutoApprovalSummary.get_content_review_queue().count), } if unlisted: counts = { 'all': (ViewUnlistedAllList.objects if admin_reviewer else exclude_admin_only_addons(ViewUnlistedAllList.objects)).count } rv = {} if isinstance(type, basestring): return counts[type]() for k, v in counts.items(): if not isinstance(type, list) or k in type: rv[k] = v() return rv
def test_locking(self, create_summary_for_version_mock, clear_reviewing_cache_mock, set_reviewing_cache_mock): create_summary_for_version_mock.return_value = (AutoApprovalSummary(), {}) call_command('auto_approve') assert create_summary_for_version_mock.call_count == 1 assert set_reviewing_cache_mock.call_count == 1 assert set_reviewing_cache_mock.call_args == ((self.addon.pk, settings.TASK_USER_ID), {}) assert clear_reviewing_cache_mock.call_count == 1 assert clear_reviewing_cache_mock.call_args == ((self.addon.pk, ), {})
def queue_auto_approved(request): admin_reviewer = is_admin_reviewer(request) qs = ( AutoApprovalSummary.get_auto_approved_queue( admin_reviewer=admin_reviewer) .select_related( 'addonapprovalscounter', '_current_version__autoapprovalsummary') .order_by( '-_current_version__autoapprovalsummary__weight', 'addonapprovalscounter__last_human_review', 'created')) return _queue(request, AutoApprovedTable, 'auto_approved', qs=qs, SearchForm=None)
def queue_counts(type=None, unlisted=False, admin_reviewer=False, limited_reviewer=False, **kw): def construct_query_from_sql_model(sqlmodel, days_min=None, days_max=None): qs = sqlmodel.objects if not admin_reviewer: qs = filter_admin_review_for_legacy_queue(qs) if days_min: qs = qs.having('waiting_time_days >=', days_min) if days_max: qs = qs.having('waiting_time_days <=', days_max) if limited_reviewer: qs = qs.having('waiting_time_hours >=', amo.REVIEW_LIMITED_DELAY_HOURS) return qs.count counts = { 'pending': construct_query_from_sql_model(ViewPendingQueue, **kw), 'nominated': construct_query_from_sql_model(ViewFullReviewQueue, **kw), 'moderated': Rating.objects.all().to_moderate().count, 'auto_approved': ( AutoApprovalSummary.get_auto_approved_queue( admin_reviewer=admin_reviewer).count), 'content_review': ( AutoApprovalSummary.get_content_review_queue( admin_reviewer=admin_reviewer).count), } if unlisted: counts = { 'all': construct_query_from_sql_model(ViewUnlistedAllList) } rv = {} if isinstance(type, basestring): return counts[type]() for k, v in counts.items(): if not isinstance(type, list) or k in type: rv[k] = v() return rv
def test_failed_verdict(self, create_summary_for_version_mock, approve_mock): fake_verdict_info = {'is_locked': True} create_summary_for_version_mock.return_value = (AutoApprovalSummary( verdict=amo.NOT_AUTO_APPROVED), fake_verdict_info) call_command('auto_approve') assert approve_mock.call_count == 0 assert create_summary_for_version_mock.call_args == ((self.version, ), { 'dry_run': False }) assert get_reviewing_cache(self.addon.pk) is None self._check_stats({ 'total': 1, 'is_locked': 1, })
def dashboard(request): # The dashboard is divided into sections that depend on what the reviewer # has access to, each section having one or more links, each link being # defined by a text and an URL. The template will show every link of every # section we provide in the context. sections = OrderedDict() view_all = acl.action_allowed(request, amo.permissions.REVIEWER_TOOLS_VIEW) admin_reviewer = is_admin_reviewer(request) extension_reviewer = acl.action_allowed( request, amo.permissions.ADDONS_REVIEW) theme_reviewer = acl.action_allowed( request, amo.permissions.STATIC_THEMES_REVIEW) if view_all or extension_reviewer or theme_reviewer: full_review_queue = ViewFullReviewQueue.objects pending_queue = ViewPendingQueue.objects if not admin_reviewer: full_review_queue = filter_admin_review_for_legacy_queue( full_review_queue) pending_queue = filter_admin_review_for_legacy_queue( pending_queue) if not view_all: full_review_queue = filter_static_themes( full_review_queue, extension_reviewer, theme_reviewer) pending_queue = filter_static_themes( pending_queue, extension_reviewer, theme_reviewer) header = ( ugettext('Static Themes and Legacy Add-ons') if extension_reviewer and theme_reviewer else ugettext('Static Themes') if theme_reviewer else ugettext('Legacy Add-ons')) sections[header] = [( ugettext('New ({0})').format(full_review_queue.count()), reverse('reviewers.queue_nominated') ), ( ugettext('Updates ({0})').format(pending_queue.count()), reverse('reviewers.queue_pending') ), ( ugettext('Performance'), reverse('reviewers.performance') ), ( ugettext('Review Log'), reverse('reviewers.reviewlog') )] if view_all or extension_reviewer: sections[header].append( (ugettext('Add-on Review Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Guide')) if view_all or theme_reviewer: sections[header].append( (ugettext('Theme Review Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Themes/' 'Guidelines')) if view_all or acl.action_allowed( request, amo.permissions.ADDONS_POST_REVIEW): sections[ugettext('Auto-Approved Add-ons')] = [( ugettext('Auto Approved Add-ons ({0})').format( AutoApprovalSummary.get_auto_approved_queue( admin_reviewer=admin_reviewer).count()), reverse('reviewers.queue_auto_approved') ), ( ugettext('Performance'), reverse('reviewers.performance') ), ( ugettext('Add-on Review Log'), reverse('reviewers.reviewlog') ), ( ugettext('Review Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Guide' )] if view_all or acl.action_allowed( request, amo.permissions.ADDONS_CONTENT_REVIEW): sections[ugettext('Content Review')] = [( ugettext('Content Review ({0})').format( AutoApprovalSummary.get_content_review_queue( admin_reviewer=admin_reviewer).count()), reverse('reviewers.queue_content_review') ), ( ugettext('Performance'), reverse('reviewers.performance') )] if view_all or acl.action_allowed( request, amo.permissions.THEMES_REVIEW): sections[ugettext('Lightweight Themes')] = [( ugettext('New Themes ({0})').format( Persona.objects.filter( addon__status=amo.STATUS_PENDING).count()), reverse('reviewers.themes.list') ), ( ugettext('Themes Updates ({0})').format( RereviewQueueTheme.objects.count()), reverse('reviewers.themes.list_rereview') ), ( ugettext('Flagged Themes ({0})').format( Persona.objects.filter( addon__status=amo.STATUS_REVIEW_PENDING).count()), reverse('reviewers.themes.list_flagged') ), ( ugettext('Lightweight Themes Review Log'), reverse('reviewers.themes.logs') ), ( ugettext('Deleted Themes Log'), reverse('reviewers.themes.deleted') ), ( ugettext('Review Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Themes/Guidelines' )] if view_all or acl.action_allowed( request, amo.permissions.RATINGS_MODERATE): sections[ugettext('User Ratings Moderation')] = [( ugettext('Ratings Awaiting Moderation ({0})').format( Rating.objects.all().to_moderate().count()), reverse('reviewers.queue_moderated') ), ( ugettext('Moderated Review Log'), reverse('reviewers.ratings_moderation_log') ), ( ugettext('Moderation Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Guide/Moderation' )] if view_all or acl.action_allowed( request, amo.permissions.ADDONS_REVIEW_UNLISTED): sections[ugettext('Unlisted Add-ons')] = [( ugettext('All Unlisted Add-ons'), reverse('reviewers.unlisted_queue_all') ), ( ugettext('Review Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Guide' )] if view_all or acl.action_allowed( request, amo.permissions.ADDON_REVIEWER_MOTD_EDIT): sections[ugettext('Announcement')] = [( ugettext('Update message of the day'), reverse('reviewers.motd') )] if view_all or acl.action_allowed( request, amo.permissions.REVIEWS_ADMIN): expired = ( Addon.objects.filter( addonreviewerflags__pending_info_request__lt=datetime.now() ).order_by('addonreviewerflags__pending_info_request')) sections[ugettext('Admin Tools')] = [( ugettext('Expired Information Requests ({0})'.format( expired.count())), reverse('reviewers.queue_expired_info_requests') )] return render(request, 'reviewers/dashboard.html', base_context(**{ # base_context includes motd. 'sections': sections }))
def process(self, version): """Process a single version, figuring out if it should be auto-approved and calling the approval code if necessary.""" already_locked = AutoApprovalSummary.check_is_locked(version) if not already_locked: # Lock the addon for ourselves if possible. Even though # AutoApprovalSummary.create_summary_for_version() will do # call check_is_locked() again later when calculating the verdict, # we have to do it now to prevent overwriting an existing lock with # our own. set_reviewing_cache(version.addon.pk, settings.TASK_USER_ID) # Discard any existing celery tasks that may have been queued before: # If there are any left at this point, it means the transaction from # the previous loop iteration was not committed and we shouldn't # trigger the corresponding tasks. _discard_tasks() # Queue celery tasks for this version, avoiding triggering them too # soon... _start_queuing_tasks() try: with transaction.atomic(): # ...and release the queued tasks to celery once transaction # is committed. transaction.on_commit(_send_tasks_and_stop_queuing) log.info( 'Processing %s version %s...', str(version.addon.name), str(version.version), ) if waffle.switch_is_active('run-action-in-auto-approve'): # We want to execute `run_action()` only once. summary_exists = AutoApprovalSummary.objects.filter( version=version).exists() if summary_exists: log.info('Not running run_action() because it has ' 'already been executed') else: ScannerResult.run_action(version) summary, info = AutoApprovalSummary.create_summary_for_version( version, dry_run=self.dry_run) self.stats.update({k: int(v) for k, v in info.items()}) if summary.verdict == self.successful_verdict: if summary.verdict == amo.AUTO_APPROVED: self.approve(version) self.stats['auto_approved'] += 1 verdict_string = summary.get_verdict_display() else: verdict_string = '%s (%s)' % ( summary.get_verdict_display(), ', '.join(summary.verdict_info_prettifier(info)), ) log.info( 'Auto Approval for %s version %s: %s', str(version.addon.name), str(version.version), verdict_string, ) # At this point, any exception should have rolled back the transaction, # so even if we did create/update an AutoApprovalSummary instance that # should have been rolled back. This ensures that, for instance, a # signing error doesn't leave the version and its autoapprovalsummary # in conflicting states. except (AutoApprovalNotEnoughFilesError, AutoApprovalNoValidationResultError): log.info( 'Version %s was skipped either because it had no ' 'files or because it had no validation attached.', version, ) self.stats['error'] += 1 except SigningError: statsd.incr('reviewers.auto_approve.approve.failure') log.info('Version %s was skipped because of a signing error', version) self.stats['error'] += 1 finally: # Always clear our own lock no matter what happens (but only ours). if not already_locked: clear_reviewing_cache(version.addon.pk) # Stop post request task queue before moving on (useful in tests to # leave a fresh state for the next test. Note that we don't want to # send or clear queued tasks (they may belong to a transaction that # has been rolled back, or they may not have been processed by the # on commit handler yet). _stop_queuing_tasks()
def dashboard(request): # The dashboard is divided into sections that depend on what the reviewer # has access to, each section having one or more links, each link being # defined by a text and an URL. The template will show every link of every # section we provide in the context. sections = OrderedDict() view_all = acl.action_allowed(request, amo.permissions.REVIEWER_TOOLS_VIEW) admin_reviewer = is_admin_reviewer(request) extension_reviewer = acl.action_allowed(request, amo.permissions.ADDONS_REVIEW) theme_reviewer = acl.action_allowed(request, amo.permissions.STATIC_THEMES_REVIEW) if view_all or extension_reviewer: full_review_queue = ViewFullReviewQueue.objects pending_queue = ViewPendingQueue.objects if not admin_reviewer: full_review_queue = filter_admin_review_for_legacy_queue( full_review_queue) pending_queue = filter_admin_review_for_legacy_queue(pending_queue) if not view_all: full_review_queue = filter_static_themes(full_review_queue, extension_reviewer, theme_reviewer) pending_queue = filter_static_themes(pending_queue, extension_reviewer, theme_reviewer) sections[ugettext('Legacy Add-ons')] = [ (ugettext('New Add-ons ({0})').format(full_review_queue.count()), reverse('reviewers.queue_nominated')), (ugettext('Add-on Updates ({0})').format(pending_queue.count()), reverse('reviewers.queue_pending')), (ugettext('Performance'), reverse('reviewers.performance')), (ugettext('Add-on Review Log'), reverse('reviewers.reviewlog')), (ugettext('Review Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Guide') ] if view_all or theme_reviewer: full_review_queue = ViewFullReviewQueue.objects pending_queue = ViewPendingQueue.objects if not admin_reviewer: full_review_queue = filter_admin_review_for_legacy_queue( full_review_queue) pending_queue = filter_admin_review_for_legacy_queue(pending_queue) if not view_all: full_review_queue = filter_static_themes(full_review_queue, extension_reviewer, theme_reviewer) pending_queue = filter_static_themes(pending_queue, extension_reviewer, theme_reviewer) sections[ugettext('Static Themes')] = [ (ugettext('New Add-ons ({0})').format(full_review_queue.count()), reverse('reviewers.queue_nominated')), (ugettext('Add-on Updates ({0})').format(pending_queue.count()), reverse('reviewers.queue_pending')), (ugettext('Performance'), reverse('reviewers.performance')), (ugettext('Add-on Review Log'), reverse('reviewers.reviewlog')), (ugettext('Review Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Themes/Guidelines') ] if view_all or acl.action_allowed(request, amo.permissions.ADDONS_POST_REVIEW): sections[ugettext('Auto-Approved Add-ons')] = [ (ugettext('Auto Approved Add-ons ({0})').format( AutoApprovalSummary.get_auto_approved_queue( admin_reviewer=admin_reviewer).count()), reverse('reviewers.queue_auto_approved')), (ugettext('Performance'), reverse('reviewers.performance')), (ugettext('Add-on Review Log'), reverse('reviewers.reviewlog')), (ugettext('Review Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Guide') ] if view_all or acl.action_allowed(request, amo.permissions.ADDONS_CONTENT_REVIEW): sections[ugettext('Content Review')] = [ (ugettext('Content Review ({0})').format( AutoApprovalSummary.get_content_review_queue( admin_reviewer=admin_reviewer).count()), reverse('reviewers.queue_content_review')), (ugettext('Performance'), reverse('reviewers.performance')) ] if view_all or acl.action_allowed(request, amo.permissions.THEMES_REVIEW): sections[ugettext('Lightweight Themes')] = [ (ugettext('New Themes ({0})').format( Persona.objects.filter( addon__status=amo.STATUS_PENDING).count()), reverse('reviewers.themes.list')), (ugettext('Themes Updates ({0})').format( RereviewQueueTheme.objects.count()), reverse('reviewers.themes.list_rereview')), (ugettext('Flagged Themes ({0})').format( Persona.objects.filter( addon__status=amo.STATUS_REVIEW_PENDING).count()), reverse('reviewers.themes.list_flagged')), (ugettext('Themes Review Log'), reverse('reviewers.themes.logs')), (ugettext('Deleted Themes Log'), reverse('reviewers.themes.deleted')), (ugettext('Review Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Themes/Guidelines') ] if view_all or acl.action_allowed(request, amo.permissions.RATINGS_MODERATE): sections[ugettext('User Ratings Moderation')] = [ (ugettext('Ratings Awaiting Moderation ({0})').format( Rating.objects.all().to_moderate().count()), reverse('reviewers.queue_moderated')), (ugettext('Moderated Review Log'), reverse('reviewers.eventlog')), (ugettext('Moderation Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Guide/Moderation') ] if view_all or acl.action_allowed(request, amo.permissions.ADDONS_REVIEW_UNLISTED): sections[ugettext('Unlisted Add-ons')] = [ (ugettext('All Unlisted Add-ons'), reverse('reviewers.unlisted_queue_all')), (ugettext('Review Guide'), 'https://wiki.mozilla.org/Add-ons/Reviewers/Guide') ] if view_all or acl.action_allowed( request, amo.permissions.ADDON_REVIEWER_MOTD_EDIT): sections[ugettext('Announcement')] = [ (ugettext('Update message of the day'), reverse('reviewers.motd')) ] if view_all or acl.action_allowed(request, amo.permissions.REVIEWS_ADMIN): expired = (Addon.objects.filter( addonreviewerflags__pending_info_request__lt=datetime.now()). order_by('addonreviewerflags__pending_info_request')) sections[ugettext('Admin Tools')] = [ (ugettext('Expired Information Requests ({0})'.format( expired.count())), reverse('reviewers.queue_expired_info_requests')) ] return render( request, 'reviewers/dashboard.html', base_context(**{ # base_context includes motd. 'sections': sections }))