def queue_moderated(request): qs = Rating.objects.all().to_moderate().order_by('ratingflag__created') page = paginate(request, qs, per_page=20) flags = dict(RatingFlag.FLAGS) reviews_formset = RatingFlagFormSet(request.POST or None, queryset=page.object_list, request=request) if request.method == 'POST': if reviews_formset.is_valid(): reviews_formset.save() else: amo.messages.error( request, ' '.join( e.as_text() or ugettext('An unknown error occurred') for e in reviews_formset.errors)) return redirect(reverse('reviewers.queue_moderated')) return render(request, 'reviewers/queue.html', context(request, reviews_formset=reviews_formset, tab='moderated', page=page, flags=flags, search_form=None, point_types=amo.REVIEWED_AMO))
def retrieve(self, request, addon_id=None): """ Returns authors who can update an addon (not Viewer role) for addons that have not been admin disabled. Optionally provide an addon id. """ if request.user.is_authenticated(): ids = (AddonUser.objects.values_list('addon_id', flat=True) .filter(user=request.user, role__in=[amo.AUTHOR_ROLE_DEV, amo.AUTHOR_ROLE_OWNER])) qs = (Addon.objects.filter(id__in=ids) .exclude(status=amo.STATUS_DISABLED) .no_transforms()) else: qs = Addon.objects.none() if addon_id: try: addon = qs.get(id=addon_id) except Addon.DoesNotExist: return Response(status=404) serializer = self.serializer_class(addon) return Response(serializer.data) paginator = paginate(request, qs) serializer = self.serializer_class(paginator.object_list, many=True) return Response({ 'objects': serializer.data, 'num_pages': paginator.paginator.num_pages, 'count': paginator.paginator.count })
def deleted_themes(request): data = request.GET.copy() deleted = Addon.unfiltered.filter(type=amo.ADDON_PERSONA, status=amo.STATUS_DELETED) if not data.get('start') and not data.get('end'): today = datetime.date.today() data['start'] = datetime.date(today.year, today.month, 1) form = forms.DeletedThemeLogForm(data) if form.is_valid(): data = form.cleaned_data if data.get('start'): deleted = deleted.filter(modified__gte=data['start']) if data.get('end'): deleted = deleted.filter(modified__lte=data['end']) if data.get('search'): term = data['search'] deleted = deleted.filter( Q(name__localized_string__icontains=term)) return render(request, 'reviewers/themes/deleted.html', { 'form': form, 'pager': paginate(request, deleted.order_by('-modified'), 30), 'tab': 'deleted' })
def _queue(request, TableObj, tab, qs=None, unlisted=False, SearchForm=QueueSearchForm): if qs is None: qs = TableObj.Meta.model.objects.all() if SearchForm: if request.GET: search_form = SearchForm(request.GET) if search_form.is_valid(): qs = search_form.filter_qs(qs) else: search_form = SearchForm() is_searching = search_form.data.get('searching') else: search_form = None is_searching = False admin_reviewer = is_admin_reviewer(request) # Those restrictions will only work with our RawSQLModel, so we need to # make sure we're not dealing with a regular Django ORM queryset first. if hasattr(qs, 'sql_model'): if not is_searching and not admin_reviewer: qs = filter_admin_review_for_legacy_queue(qs) if not unlisted: if is_limited_reviewer(request): qs = qs.having( 'waiting_time_hours >=', amo.REVIEW_LIMITED_DELAY_HOURS) qs = filter_static_themes( qs, acl.action_allowed(request, amo.permissions.ADDONS_REVIEW), acl.action_allowed( request, amo.permissions.STATIC_THEMES_REVIEW)) # Most WebExtensions are picked up by auto_approve cronjob, they # don't need to appear in the queues, unless auto approvals have # been disabled for them. Webextension static themes aren't auto # approved. qs = qs.filter( Q(addon_type_id=amo.ADDON_STATICTHEME) | Q(**{'files.is_webextension': False}) | Q(**{'addons_addonreviewerflags.auto_approval_disabled': True}) ) order_by = request.GET.get('sort', TableObj.default_order_by()) if hasattr(TableObj, 'translate_sort_cols'): order_by = TableObj.translate_sort_cols(order_by) table = TableObj(data=qs, order_by=order_by) per_page = request.GET.get('per_page', REVIEWS_PER_PAGE) try: per_page = int(per_page) except ValueError: per_page = REVIEWS_PER_PAGE if per_page <= 0 or per_page > REVIEWS_PER_PAGE_MAX: per_page = REVIEWS_PER_PAGE page = paginate(request, table.rows, per_page=per_page) table.set_page(page) return render(request, 'reviewers/queue.html', context(request, table=table, page=page, tab=tab, search_form=search_form, point_types=amo.REVIEWED_AMO, unlisted=unlisted))
def queue_moderated(request): qs = Rating.objects.all().to_moderate().order_by('ratingflag__created') page = paginate(request, qs, per_page=20) flags = dict(RatingFlag.FLAGS) reviews_formset = RatingFlagFormSet(request.POST or None, queryset=page.object_list, request=request) if request.method == 'POST': if reviews_formset.is_valid(): reviews_formset.save() else: amo.messages.error( request, ' '.join(e.as_text() or ugettext('An unknown error occurred') for e in reviews_formset.errors)) return redirect(reverse('reviewers.queue_moderated')) return render( request, 'reviewers/queue.html', context(request, reviews_formset=reviews_formset, tab='moderated', page=page, flags=flags, search_form=None, point_types=amo.REVIEWED_AMO))
def deleted_themes(request): data = request.GET.copy() deleted = Addon.unfiltered.filter(type=amo.ADDON_PERSONA, status=amo.STATUS_DELETED) if not data.get('start') and not data.get('end'): today = datetime.date.today() data['start'] = datetime.date(today.year, today.month, 1) form = forms.DeletedThemeLogForm(data) if form.is_valid(): data = form.cleaned_data if data.get('start'): deleted = deleted.filter(modified__gte=data['start']) if data.get('end'): deleted = deleted.filter(modified__lte=data['end']) if data.get('search'): term = data['search'] deleted = deleted.filter(Q(name__localized_string__icontains=term)) return render( request, 'editors/themes/deleted.html', { 'form': form, 'pager': paginate(request, deleted.order_by('-modified'), 30), 'tab': 'deleted' })
def queue_moderated(request): qs = Review.objects.all().to_moderate().order_by('reviewflag__created') page = paginate(request, qs, per_page=20) motd_editable = acl.action_allowed(request, 'AddonReviewerMOTD', 'Edit') flags = dict(ReviewFlag.FLAGS) reviews_formset = ReviewFlagFormSet(request.POST or None, queryset=page.object_list, request=request) if request.method == 'POST': if reviews_formset.is_valid(): reviews_formset.save() else: amo.messages.error( request, ' '.join(e.as_text() or _('An unknown error occurred') for e in reviews_formset.errors)) return redirect(reverse('editors.queue_moderated')) return render(request, 'editors/queue.html', context(request, reviews_formset=reviews_formset, tab='moderated', page=page, flags=flags, search_form=None, point_types=amo.REVIEWED_AMO, motd_editable=motd_editable))
def retrieve(self, request, addon_id=None): """ Returns authors who can update an addon (not Viewer role) for addons that have not been admin disabled. Optionally provide an addon id. """ if request.user.is_authenticated(): ids = (AddonUser.objects.values_list('addon_id', flat=True).filter( user=request.user, role__in=[amo.AUTHOR_ROLE_DEV, amo.AUTHOR_ROLE_OWNER])) qs = (Addon.objects.filter(id__in=ids).exclude( status=amo.STATUS_DISABLED).no_transforms()) else: qs = Addon.objects.none() if addon_id: try: addon = qs.get(id=addon_id) except Addon.DoesNotExist: return Response(status=404) serializer = self.serializer_class(addon) return Response(serializer.data) paginator = paginate(request, qs) serializer = self.serializer_class(paginator.object_list, many=True) return Response({ 'objects': serializer.data, 'num_pages': paginator.paginator.num_pages, 'count': paginator.paginator.count })
def themes_list(request, flagged=False, rereview=False): """Themes queue in list format.""" themes = [] if flagged: # TODO (ngoke): rename to STATUS_FLAGGED. themes = Addon.objects.filter(status=amo.STATUS_REVIEW_PENDING, type=amo.ADDON_PERSONA, persona__isnull=False) elif rereview: themes = [ rqt.theme.addon for rqt in RereviewQueueTheme.objects.select_related('theme__addon')] else: themes = Addon.objects.filter(status=amo.STATUS_PENDING, type=amo.ADDON_PERSONA, persona__isnull=False) search_form = forms.ThemeSearchForm(request.GET) per_page = request.GET.get('per_page', QUEUE_PER_PAGE) pager = paginate(request, themes, per_page) return render(request, 'reviewers/themes/queue_list.html', context( **{'addons': pager.object_list, 'flagged': flagged, 'pager': pager, 'rereview': rereview, 'theme_search_form': search_form, 'statuses': dict((k, unicode(v)) for k, v in amo.STATUS_CHOICES_API.items()), 'tab': ('rereview_themes' if rereview else 'flagged_themes' if flagged else 'pending_themes')}))
def themes_logs(request): data = request.GET.copy() if not data.get('start') and not data.get('end'): today = datetime.date.today() data['start'] = datetime.date(today.year, today.month, 1) form = forms.ReviewThemeLogForm(data) theme_logs = ActivityLog.objects.filter(action=amo.LOG.THEME_REVIEW.id) if form.is_valid(): data = form.cleaned_data if data.get('start'): theme_logs = theme_logs.filter(created__gte=data['start']) if data.get('end'): theme_logs = theme_logs.filter(created__lte=data['end']) if data.get('search'): term = data['search'] theme_logs = theme_logs.filter( Q(_details__icontains=term) | Q(user__display_name__icontains=term) | Q(user__username__icontains=term)).distinct() pager = paginate(request, theme_logs, 30) data = context(form=form, pager=pager, ACTION_DICT=rvw.REVIEW_ACTIONS, REJECT_REASONS=rvw.THEME_REJECT_REASONS, tab='themes') return render(request, 'editors/themes/logs.html', data)
def queue_moderated(request): # In addition to other checks, this only show reviews for public and # listed add-ons. Unlisted add-ons typically won't have reviews anyway # but they might if their status ever gets changed. rf = (Review.objects.exclude(Q(addon__isnull=True) | Q(addon__is_listed=False) | Q(reviewflag__isnull=True)) .filter(editorreview=1, addon__status__in=amo.LISTED_STATUSES) .order_by('reviewflag__created')) page = paginate(request, rf, per_page=20) motd_editable = acl.action_allowed(request, 'AddonReviewerMOTD', 'Edit') flags = dict(ReviewFlag.FLAGS) reviews_formset = ReviewFlagFormSet(request.POST or None, queryset=page.object_list, request=request) if request.method == 'POST': if reviews_formset.is_valid(): reviews_formset.save() else: amo.messages.error( request, ' '.join(e.as_text() or _('An unknown error occurred') for e in reviews_formset.errors)) return redirect(reverse('editors.queue_moderated')) return render(request, 'editors/queue.html', context(request, reviews_formset=reviews_formset, tab='moderated', page=page, flags=flags, search_form=None, point_types=amo.REVIEWED_AMO, motd_editable=motd_editable))
def collection_detail(request, username, slug): collection = get_collection(request, username, slug) if not collection.listed: if not request.user.is_authenticated(): return redirect_for_login(request) if not acl.check_collection_ownership(request, collection): raise PermissionDenied base = Addon.objects.valid() & collection.addons.all() filter = CollectionAddonFilter(request, base, key='sort', default='popular') notes = get_notes(collection) # Go directly to CollectionAddon for the count to avoid joins. count = CollectionAddon.objects.filter( Addon.objects.all().valid_q( amo.VALID_ADDON_STATUSES, prefix='addon__'), collection=collection.id) addons = paginate(request, filter.qs, per_page=15, count=count.count()) # `perms` is defined in django.contrib.auth.context_processors. Gotcha! user_perms = { 'view_stats': acl.check_ownership( request, collection, require_owner=False), } tags = Tag.objects.filter( id__in=collection.top_tags) if collection.top_tags else [] return render_cat(request, 'bandwagon/collection_detail.html', {'collection': collection, 'filter': filter, 'addons': addons, 'notes': notes, 'tags': tags, 'user_perms': user_perms})
def themes_logs(request): data = request.GET.copy() if not data.get('start') and not data.get('end'): today = datetime.date.today() data['start'] = datetime.date(today.year, today.month, 1) form = forms.ReviewThemeLogForm(data) theme_logs = ActivityLog.objects.filter(action=amo.LOG.THEME_REVIEW.id) if form.is_valid(): data = form.cleaned_data if data.get('start'): theme_logs = theme_logs.filter(created__gte=data['start']) if data.get('end'): theme_logs = theme_logs.filter(created__lte=data['end']) if data.get('search'): term = data['search'] theme_logs = theme_logs.filter( Q(_details__icontains=term) | Q(user__display_name__icontains=term) | Q(user__username__icontains=term)).distinct() pager = paginate(request, theme_logs, 30) data = context(form=form, pager=pager, ACTION_DICT=amo.REVIEW_ACTIONS, REJECT_REASONS=amo.THEME_REJECT_REASONS, tab='themes') return render(request, 'reviewers/themes/logs.html', data)
def collection_detail(request, username, slug): collection = get_collection(request, username, slug) if not collection.listed: if not request.user.is_authenticated: return redirect_for_login(request) if not acl.check_collection_ownership(request, collection): raise PermissionDenied base = Addon.objects.valid() & collection.addons.all() filter = CollectionAddonFilter(request, base, key='sort', default='popular') notes = get_notes(collection) # Go directly to CollectionAddon for the count to avoid joins. count = CollectionAddon.objects.filter( Addon.objects.all().valid_q( amo.VALID_ADDON_STATUSES, prefix='addon__'), collection=collection.id) addons = paginate(request, filter.qs, per_page=15, count=count.count()) # `perms` is defined in django.contrib.auth.context_processors. Gotcha! user_perms = { 'view_stats': acl.check_ownership( request, collection, require_owner=False), } tags = Tag.objects.filter( id__in=collection.top_tags) if collection.top_tags else [] return render_cat(request, 'bandwagon/collection_detail.html', {'collection': collection, 'filter': filter, 'addons': addons, 'notes': notes, 'tags': tags, 'user_perms': user_perms})
def queue_moderated(request): qs = Review.objects.all().to_moderate().order_by('reviewflag__created') page = paginate(request, qs, per_page=20) motd_editable = acl.action_allowed( request, amo.permissions.ADDON_REVIEWER_MOTD_EDIT) flags = dict(ReviewFlag.FLAGS) reviews_formset = forms.ReviewFlagFormSet(request.POST or None, queryset=page.object_list, request=request) if request.method == 'POST': if reviews_formset.is_valid(): reviews_formset.save() else: amo.messages.error( request, ' '.join(e.as_text() or ugettext('An unknown error occurred') for e in reviews_formset.errors)) return redirect(reverse('reviewers.queue_moderated')) return render( request, 'reviewers/queue.html', context(request, reviews_formset=reviews_formset, tab='moderated', page=page, flags=flags, search_form=None, point_types=amo.REVIEWED_AMO, motd_editable=motd_editable))
def following(request): qs = (Collection.objects.filter(following__user=request.user) .order_by('-following__created')) collections = paginate(request, qs) votes = get_votes(request, collections.object_list) return render_cat(request, 'bandwagon/user_listing.html', dict(collections=collections, votes=votes, page='following', filter=get_filter(request)))
def following(request): qs = (Collection.objects.filter(following__user=request.user) .order_by('-following__created')) collections = paginate(request, qs) votes = get_votes(request, collections.object_list) return render_cat(request, 'bandwagon/user_listing.html', {'collections': collections, 'votes': votes, 'page': 'following'})
def _queue(request, TableObj, tab, qs=None, unlisted=False, SearchForm=forms.QueueSearchForm): if qs is None: qs = TableObj.Meta.model.objects.all() if is_limited_reviewer(request): qs = qs.having('waiting_time_hours >=', REVIEW_LIMITED_DELAY_HOURS) if SearchForm: if request.GET: search_form = SearchForm(request.GET) if search_form.is_valid(): qs = search_form.filter_qs(qs) else: search_form = SearchForm() is_searching = search_form.data.get('searching') else: search_form = None is_searching = False admin_reviewer = is_admin_reviewer(request) if hasattr(qs, 'filter'): if waffle.switch_is_active('post-review'): # Hide webextensions from the queues so that human reviewers don't # pick them up: auto-approve cron should take care of them. qs = qs.filter(**{'files.is_webextension': False}) if not is_searching and not admin_reviewer: qs = exclude_admin_only_addons(qs) motd_editable = acl.action_allowed( request, amo.permissions.ADDON_REVIEWER_MOTD_EDIT) order_by = request.GET.get('sort', TableObj.default_order_by()) if hasattr(TableObj, 'translate_sort_cols'): order_by = TableObj.translate_sort_cols(order_by) table = TableObj(data=qs, order_by=order_by) per_page = request.GET.get('per_page', REVIEWS_PER_PAGE) try: per_page = int(per_page) except ValueError: per_page = REVIEWS_PER_PAGE if per_page <= 0 or per_page > REVIEWS_PER_PAGE_MAX: per_page = REVIEWS_PER_PAGE page = paginate(request, table.rows, per_page=per_page) table.set_page(page) return render( request, 'editors/queue.html', context(request, table=table, page=page, tab=tab, search_form=search_form, point_types=amo.REVIEWED_AMO, unlisted=unlisted, motd_editable=motd_editable))
def test_paginate_returns_this_paginator(self): request = MagicMock() request.GET.get.return_value = 1 request.GET.urlencode.return_value = '' request.path = '' qs = Addon.search() pager = paginate(request, qs) assert isinstance(pager.paginator, ESPaginator)
def _queue(request, TableObj, tab, qs=None, unlisted=False, SearchForm=forms.QueueSearchForm): if qs is None: qs = TableObj.Meta.model.objects.all() if SearchForm: if request.GET: search_form = SearchForm(request.GET) if search_form.is_valid(): qs = search_form.filter_qs(qs) else: search_form = SearchForm() is_searching = search_form.data.get('searching') else: search_form = None is_searching = False admin_reviewer = is_admin_reviewer(request) if hasattr(qs, 'filter'): if not is_searching and not admin_reviewer: qs = exclude_admin_only_addons(qs) # Those additional restrictions will only work with our RawSQLModel, # so we need to make sure we're not dealing with a regular Django ORM # queryset first. if hasattr(qs, 'sql_model') and not unlisted: if is_limited_reviewer(request): qs = qs.having( 'waiting_time_hours >=', REVIEW_LIMITED_DELAY_HOURS) if waffle.switch_is_active('post-review'): # Hide webextensions from the queues so that human reviewers # don't pick them up: auto-approve cron should take care of # them. qs = qs.filter(**{'files.is_webextension': False}) motd_editable = acl.action_allowed( request, amo.permissions.ADDON_REVIEWER_MOTD_EDIT) order_by = request.GET.get('sort', TableObj.default_order_by()) if hasattr(TableObj, 'translate_sort_cols'): order_by = TableObj.translate_sort_cols(order_by) table = TableObj(data=qs, order_by=order_by) per_page = request.GET.get('per_page', REVIEWS_PER_PAGE) try: per_page = int(per_page) except ValueError: per_page = REVIEWS_PER_PAGE if per_page <= 0 or per_page > REVIEWS_PER_PAGE_MAX: per_page = REVIEWS_PER_PAGE page = paginate(request, table.rows, per_page=per_page) table.set_page(page) return render(request, 'editors/queue.html', context(request, table=table, page=page, tab=tab, search_form=search_form, point_types=amo.REVIEWED_AMO, unlisted=unlisted, motd_editable=motd_editable))
def read(self, request, id=None): if id: try: return self.model.objects.get(pk=id) except self.model.DoesNotExist: return rc.NOT_HERE else: paginator = paginate(request, self.model.objects.all()) return {'objects': paginator.object_list, 'num_pages': paginator.paginator.num_pages, 'count': paginator.paginator.count}
def collection_listing(request, base=None): qs = (Collection.objects.listed().filter( Q(application=request.APP.id) | Q(application=None)).filter( type=amo.COLLECTION_FEATURED).exclude(addon_count=0)) collections = paginate(request, qs, count=qs.count()) return render_cat( request, 'bandwagon/impala/collection_listing.html', { 'collections': collections, 'src': 'co-hc-sidebar', 'dl_src': 'co-dp-sidebar' })
def _queue(request, TableObj, tab, qs=None, unlisted=False, SearchForm=forms.QueueSearchForm): if qs is None: qs = TableObj.Meta.model.objects.all() if SearchForm: if request.GET: search_form = SearchForm(request.GET) if search_form.is_valid(): qs = search_form.filter_qs(qs) else: search_form = SearchForm() is_searching = search_form.data.get('searching') else: search_form = None is_searching = False admin_reviewer = is_admin_reviewer(request) # Those restrictions will only work with our RawSQLModel, so we need to # make sure we're not dealing with a regular Django ORM queryset first. if hasattr(qs, 'sql_model'): if not is_searching and not admin_reviewer: qs = filter_admin_review_for_legacy_queue(qs) if not unlisted: if is_limited_reviewer(request): qs = qs.having( 'waiting_time_hours >=', amo.REVIEW_LIMITED_DELAY_HOURS) # Hide webextensions from the listed queues so that human reviewers # don't pick them up: auto-approve cron should take care of them. qs = qs.filter(**{'files.is_webextension': False}) motd_editable = acl.action_allowed( request, amo.permissions.ADDON_REVIEWER_MOTD_EDIT) order_by = request.GET.get('sort', TableObj.default_order_by()) if hasattr(TableObj, 'translate_sort_cols'): order_by = TableObj.translate_sort_cols(order_by) table = TableObj(data=qs, order_by=order_by) per_page = request.GET.get('per_page', REVIEWS_PER_PAGE) try: per_page = int(per_page) except ValueError: per_page = REVIEWS_PER_PAGE if per_page <= 0 or per_page > REVIEWS_PER_PAGE_MAX: per_page = REVIEWS_PER_PAGE page = paginate(request, table.rows, per_page=per_page) table.set_page(page) return render(request, 'reviewers/queue.html', context(request, table=table, page=page, tab=tab, search_form=search_form, point_types=amo.REVIEWED_AMO, unlisted=unlisted, motd_editable=motd_editable))
def themes_history(request, username): if not username: username = request.user.username return render(request, 'reviewers/themes/history.html', context( **{'theme_reviews': paginate(request, ActivityLog.objects.filter( action=amo.LOG.THEME_REVIEW.id, user__username=username), 20), 'user_history': True, 'username': username, 'reject_reasons': amo.THEME_REJECT_REASONS, 'action_dict': amo.REVIEW_ACTIONS}))
def collection_detail(request, username, slug): collection = get_collection(request, username, slug) if not collection.listed: if not request.user.is_authenticated(): return redirect_for_login(request) if not acl.check_collection_ownership(request, collection): raise PermissionDenied if request.GET.get('format') == 'rss': return http.HttpResponsePermanentRedirect(collection.feed_url()) base = Addon.objects.valid() & collection.addons.all() filter = CollectionAddonFilter(request, base, key='sort', default='popular') notes = get_notes(collection) # Go directly to CollectionAddon for the count to avoid joins. count = CollectionAddon.objects.filter(Addon.objects.all().valid_q( amo.VALID_ADDON_STATUSES, prefix='addon__'), collection=collection.id) addons = paginate(request, filter.qs, per_page=15, count=count.count()) # The add-on query is not related to the collection, so we need to manually # hook them up for invalidation. Bonus: count invalidation. keys = [addons.object_list.flush_key(), count.flush_key()] caching.invalidator.add_to_flush_list({collection.flush_key(): keys}) if collection.author_id: qs = Collection.objects.listed().filter(author=collection.author) others = amo.utils.randslice(qs, limit=4, exclude=collection.id) else: others = [] # `perms` is defined in django.contrib.auth.context_processors. Gotcha! user_perms = { 'view_stats': acl.check_ownership(request, collection, require_owner=False), } tags = Tag.objects.filter( id__in=collection.top_tags) if collection.top_tags else [] return render_cat( request, 'bandwagon/collection_detail.html', { 'collection': collection, 'filter': filter, 'addons': addons, 'notes': notes, 'author_collections': others, 'tags': tags, 'user_perms': user_perms })
def themes_history(request, user_id): if not user_id: user = request.user else: user = get_object_or_404(UserProfile, pk=user_id) return render(request, 'reviewers/themes/history.html', context( **{'theme_reviews': paginate(request, ActivityLog.objects.filter( action=amo.LOG.THEME_REVIEW.id, user_id=user.id), 20), 'user_history': True, 'user_name': user.name, 'reject_reasons': amo.THEME_REJECT_REASONS, 'action_dict': amo.REVIEW_ACTIONS}))
def review_list(request, addon, review_id=None, user_id=None): qs = Review.without_replies.all().filter(addon=addon).order_by('-created') ctx = {'addon': addon, 'grouped_ratings': GroupedRating.get(addon.id)} ctx['form'] = forms.ReviewForm(None) is_admin = acl.action_allowed(request, amo.permissions.ADDONS_EDIT) if review_id is not None: ctx['page'] = 'detail' # If this is a dev reply, find the first msg for context. review = get_object_or_404(Review.objects.all(), pk=review_id) if review.reply_to_id: review_id = review.reply_to_id ctx['reply'] = review qs = qs.filter(pk=review_id) elif user_id is not None: ctx['page'] = 'user' qs = qs.filter(user=user_id) if not qs: raise http.Http404() else: ctx['page'] = 'list' qs = qs.filter(is_latest=True) # Don't filter out empty reviews for admins. if not is_admin: # But otherwise, filter out everyone elses empty reviews. user_filter = (Q(user=request.user.pk) if request.user.is_authenticated() else Q()) qs = qs.filter(~Q(body=None) | user_filter) ctx['reviews'] = reviews = paginate(request, qs) ctx['replies'] = Review.get_replies(reviews.object_list) if request.user.is_authenticated(): ctx['review_perms'] = { 'is_admin': is_admin, 'is_editor': acl.is_editor(request, addon), 'is_author': acl.check_addon_ownership(request, addon, viewer=True, dev=True, support=True), } ctx['flags'] = get_flags(request, reviews.object_list) else: ctx['review_perms'] = {} return render(request, 'reviews/review_list.html', ctx)
def usage_stats(request, compat, app, binary=None): # Get the list of add-ons for usage stats. qs = AppCompat.search().order_by("-usage.%s" % app).values_dict() if request.GET.get("previous"): qs = qs.filter(**{"support.%s.max__gte" % app: vint(compat["previous"])}) else: qs = qs.filter(**{"support.%s.max__gte" % app: 0}) if binary is not None: qs = qs.filter(binary=binary) addons = amo_utils.paginate(request, qs) for obj in addons.object_list: obj["usage"] = obj["usage"][app] obj["max_version"] = obj["max_version"][app] return addons, CompatTotals.objects.get(app=app).total
def user_listing(request, username): author = get_object_or_404(UserProfile, username=username) qs = (Collection.objects.filter(author__username=username) .order_by('-created')) mine = (request.user.is_authenticated() and request.user.username == username) if mine: page = 'mine' else: page = 'user' qs = qs.filter(listed=True) collections = paginate(request, qs) return render_cat(request, 'bandwagon/user_listing.html', {'collections': collections, 'page': page, 'author': author})
def user_listing(request, username): author = get_object_or_404(UserProfile, username=username) qs = (Collection.objects.filter(author__username=username) .order_by('-created')) mine = (request.user.is_authenticated and request.user.username == username) if mine: page = 'mine' else: page = 'user' qs = qs.filter(listed=True) collections = paginate(request, qs) return render_cat(request, 'bandwagon/user_listing.html', {'collections': collections, 'page': page, 'author': author})
def usage_stats(request, compat, app, binary=None): # Get the list of add-ons for usage stats. qs = AppCompat.search().order_by('-usage.%s' % app).values_dict() if request.GET.get('previous'): qs = qs.filter( **{'support.%s.max__gte' % app: vint(compat['previous'])}) else: qs = qs.filter(**{'support.%s.max__gte' % app: 0}) if binary is not None: qs = qs.filter(binary=binary) addons = amo_utils.paginate(request, qs) for obj in addons.object_list: obj['usage'] = obj['usage'][app] obj['max_version'] = obj['max_version'][app] return addons, CompatTotals.objects.get(app=app).total
def review_list(request, addon, review_id=None, user_id=None): qs = Rating.without_replies.all().filter( addon=addon).order_by('-created') ctx = {'addon': addon, 'grouped_ratings': GroupedRating.get(addon.id)} ctx['form'] = forms.RatingForm(None) is_admin = acl.action_allowed(request, amo.permissions.ADDONS_EDIT) if review_id is not None: ctx['page'] = 'detail' # If this is a dev reply, find the first msg for context. review = get_object_or_404(Rating.objects.all(), pk=review_id) if review.reply_to_id: review_id = review.reply_to_id ctx['reply'] = review qs = qs.filter(pk=review_id) elif user_id is not None: ctx['page'] = 'user' qs = qs.filter(user=user_id) if not qs: raise http.Http404() else: ctx['page'] = 'list' qs = qs.filter(is_latest=True) # Don't filter out empty reviews for admins. if not is_admin: # But otherwise, filter out everyone elses empty reviews. user_filter = (Q(user=request.user.pk) if request.user.is_authenticated() else Q()) qs = qs.filter(~Q(body=None) | user_filter) ctx['reviews'] = reviews = paginate(request, qs) ctx['replies'] = Rating.get_replies(reviews.object_list) if request.user.is_authenticated(): ctx['review_perms'] = { 'is_admin': is_admin, 'is_reviewer': acl.action_allowed( request, amo.permissions.RATINGS_MODERATE), 'is_author': acl.check_addon_ownership(request, addon, viewer=True, dev=True, support=True), } ctx['flags'] = get_flags(request, reviews.object_list) else: ctx['review_perms'] = {} return render(request, 'ratings/review_list.html', ctx)
def _queue(request, TableObj, tab, qs=None, unlisted=False, SearchForm=forms.QueueSearchForm): if qs is None: qs = TableObj.Meta.model.objects.all() if is_limited_reviewer(request): qs = qs.having('waiting_time_hours >=', REVIEW_LIMITED_DELAY_HOURS) if request.GET: search_form = SearchForm(request.GET) if search_form.is_valid(): qs = search_form.filter_qs(qs) else: search_form = SearchForm() admin_reviewer = is_admin_reviewer(request) if not admin_reviewer and not search_form.data.get('searching'): qs = exclude_admin_only_addons(qs) motd_editable = acl.action_allowed(request, 'AddonReviewerMOTD', 'Edit') order_by = request.GET.get('sort', TableObj.default_order_by()) if hasattr(TableObj, 'translate_sort_cols'): order_by = TableObj.translate_sort_cols(order_by) table = TableObj(data=qs, order_by=order_by) default = 100 per_page = request.GET.get('per_page', default) try: per_page = int(per_page) except ValueError: per_page = default if per_page <= 0 or per_page > 200: per_page = default page = paginate(request, table.rows, per_page=per_page) table.set_page(page) return render( request, 'editors/queue.html', context(request, table=table, page=page, tab=tab, search_form=search_form, point_types=amo.REVIEWED_AMO, unlisted=unlisted, motd_editable=motd_editable))
def user_listing(request, username): author = get_object_or_404(UserProfile, username=username) qs = (Collection.objects.filter(author__username=username) .order_by('-created')) mine = (request.user.is_authenticated() and request.user.username == username) if mine: page = 'mine' else: page = 'user' qs = qs.filter(listed=True) collections = paginate(request, qs) votes = get_votes(request, collections.object_list) return render_cat(request, 'bandwagon/user_listing.html', dict(collections=collections, collection_votes=votes, page=page, author=author, filter=get_filter(request)))
def collection_detail(request, username, slug): collection = get_collection(request, username, slug) if not collection.listed: if not request.user.is_authenticated(): return redirect_for_login(request) if not acl.check_collection_ownership(request, collection): raise PermissionDenied if request.GET.get('format') == 'rss': return http.HttpResponsePermanentRedirect(collection.feed_url()) base = Addon.objects.valid() & collection.addons.all() filter = CollectionAddonFilter(request, base, key='sort', default='popular') notes = get_notes(collection) # Go directly to CollectionAddon for the count to avoid joins. count = CollectionAddon.objects.filter( Addon.objects.all().valid_q( amo.VALID_ADDON_STATUSES, prefix='addon__'), collection=collection.id) addons = paginate(request, filter.qs, per_page=15, count=count.count()) # The add-on query is not related to the collection, so we need to manually # hook them up for invalidation. Bonus: count invalidation. keys = [addons.object_list.flush_key(), count.flush_key()] caching.invalidator.add_to_flush_list({collection.flush_key(): keys}) if collection.author_id: qs = Collection.objects.listed().filter(author=collection.author) others = amo.utils.randslice(qs, limit=4, exclude=collection.id) else: others = [] # `perms` is defined in django.contrib.auth.context_processors. Gotcha! user_perms = { 'view_stats': acl.check_ownership( request, collection, require_owner=False), } tags = Tag.objects.filter( id__in=collection.top_tags) if collection.top_tags else [] return render_cat(request, 'bandwagon/collection_detail.html', {'collection': collection, 'filter': filter, 'addons': addons, 'notes': notes, 'author_collections': others, 'tags': tags, 'user_perms': user_perms})
def reporter_detail(request, guid): try: addon = Addon.objects.get(guid=guid) except Addon.DoesNotExist: addon = None name = addon.name if addon else guid qs = CompatReport.objects.filter(guid=guid) show_listed_only = addon and not owner_or_unlisted_reviewer(request, addon) if (addon and not addon.has_listed_versions() and show_listed_only): # Not authorized? Let's pretend this addon simply doesn't exist. name = guid qs = CompatReport.objects.none() elif show_listed_only: unlisted_versions = addon.versions.filter( channel=amo.RELEASE_CHANNEL_UNLISTED).values_list('version', flat=True) qs = qs.exclude(version__in=unlisted_versions) form = AppVerForm(request.GET) if request.GET and form.is_valid() and form.cleaned_data['appver']: # Apply filters only if we have a good app/version combination. version = form.cleaned_data['appver'] ver = vdict(floor_version(version))['major'] # 3.6 => 3 # Ideally we'd have a `version_int` column to do strict version # comparing, but that's overkill for basic version filtering here. qs = qs.filter(app_guid=amo.FIREFOX.guid, app_version__startswith=str(ver) + '.') works_ = dict(qs.values_list('works_properly').annotate(Count('id'))) works = {'success': works_.get(True, 0), 'failure': works_.get(False, 0)} works_properly = request.GET.get('works_properly') if works_properly: qs = qs.filter(works_properly=works_properly) reports = paginate(request, qs.order_by('-created'), 100) return render( request, 'compat/reporter_detail.html', dict(reports=reports, works=works, works_properly=works_properly, name=name, guid=guid, form=form))
def collection_listing(request, base=None): qs = ( Collection.objects.listed() .filter(Q(application=request.APP.id) | Q(application=None)) .filter(type=amo.COLLECTION_FEATURED) .exclude(addon_count=0) ) # Counts are hard to cache automatically, and accuracy for this # one is less important. Remember it for 5 minutes. countkey = hashlib.sha256(str(qs.query) + '_count').hexdigest() count = cache.get(countkey) if count is None: count = qs.count() cache.set(countkey, count, 300) collections = paginate(request, qs, count=count) return render_cat(request, 'bandwagon/impala/collection_listing.html', {'collections': collections, 'src': 'co-hc-sidebar', 'dl_src': 'co-dp-sidebar'})
def collection_listing(request, base=None): qs = (Collection.objects.listed().filter( Q(application=request.APP.id) | Q(application=None)).filter( type=amo.COLLECTION_FEATURED).exclude(addon_count=0)) # Counts are hard to cache automatically, and accuracy for this # one is less important. Remember it for 5 minutes. countkey = hashlib.sha256(str(qs.query) + '_count').hexdigest() count = cache.get(countkey) if count is None: count = qs.count() cache.set(countkey, count, 300) collections = paginate(request, qs, count=count) return render_cat( request, 'bandwagon/impala/collection_listing.html', { 'collections': collections, 'src': 'co-hc-sidebar', 'dl_src': 'co-dp-sidebar' })
def collection_listing(request, base=None): sort = request.GET.get('sort') # We turn users into followers. if sort == 'users': return redirect(urlparams(reverse('collections.list'), sort='followers'), permanent=True) filter = get_filter(request, base) # Counts are hard to cache automatically, and accuracy for this # one is less important. Remember it for 5 minutes. countkey = hashlib.md5(str(filter.qs.query) + '_count').hexdigest() count = cache.get(countkey) if count is None: count = filter.qs.count() cache.set(countkey, count, 300) collections = paginate(request, filter.qs, count=count) return render_cat(request, 'bandwagon/impala/collection_listing.html', dict(collections=collections, src='co-hc-sidebar', dl_src='co-dp-sidebar', filter=filter, sort=sort, sorting=filter.field))
def collection_listing(request, base=None): sort = request.GET.get('sort') # We turn users into followers. if sort == 'users': return redirect(urlparams(reverse('collections.list'), sort='followers'), permanent=True) filter = get_filter(request, base) # Counts are hard to cache automatically, and accuracy for this # one is less important. Remember it for 5 minutes. countkey = hashlib.sha256(str(filter.qs.query) + '_count').hexdigest() count = cache.get(countkey) if count is None: count = filter.qs.count() cache.set(countkey, count, 300) collections = paginate(request, filter.qs, count=count) return render_cat(request, 'bandwagon/impala/collection_listing.html', dict(collections=collections, src='co-hc-sidebar', dl_src='co-dp-sidebar', filter=filter, sort=sort, sorting=filter.field))
def review_list(request, addon, review_id=None, user_id=None, template=None): qs = Review.without_replies.all().filter(addon=addon).order_by('-created') ctx = {'addon': addon, 'grouped_ratings': GroupedRating.get(addon.id)} ctx['form'] = forms.ReviewForm(None) if review_id is not None: ctx['page'] = 'detail' # If this is a dev reply, find the first msg for context. review = get_object_or_404(Review.objects.all(), pk=review_id) if review.reply_to_id: review_id = review.reply_to_id ctx['reply'] = review qs = qs.filter(pk=review_id) elif user_id is not None: ctx['page'] = 'user' qs = qs.filter(user=user_id) if not qs: raise http.Http404() else: ctx['page'] = 'list' qs = qs.filter(is_latest=True) ctx['reviews'] = reviews = paginate(request, qs) ctx['replies'] = Review.get_replies(reviews.object_list) if request.user.is_authenticated(): ctx['review_perms'] = { 'is_admin': acl.action_allowed(request, 'Addons', 'Edit'), 'is_editor': acl.is_editor(request, addon), 'is_author': acl.check_addon_ownership(request, addon, viewer=True, dev=True, support=True), } ctx['flags'] = get_flags(request, reviews.object_list) else: ctx['review_perms'] = {} return render(request, template, ctx)
def reporter_detail(request, guid): try: addon = Addon.with_unlisted.get(guid=guid) except Addon.DoesNotExist: addon = None name = addon.name if addon else guid qs = CompatReport.objects.filter(guid=guid) if (addon and not addon.is_listed and not owner_or_unlisted_reviewer(request, addon)): # Not authorized? Let's pretend this addon simply doesn't exist. name = guid qs = CompatReport.objects.none() form = AppVerForm(request.GET) if request.GET and form.is_valid() and form.cleaned_data['appver']: # Apply filters only if we have a good app/version combination. app, ver = form.cleaned_data['appver'].split('-') app = amo.APP_IDS[int(app)] ver = vdict(floor_version(ver))['major'] # 3.6 => 3 # Ideally we'd have a `version_int` column to do strict version # comparing, but that's overkill for basic version filtering here. qs = qs.filter(app_guid=app.guid, app_version__startswith=str(ver) + '.') works_ = dict(qs.values_list('works_properly').annotate(Count('id'))) works = {'success': works_.get(True, 0), 'failure': works_.get(False, 0)} works_properly = request.GET.get('works_properly') if works_properly: qs = qs.filter(works_properly=works_properly) reports = amo_utils.paginate(request, qs.order_by('-created'), 100) return render( request, 'compat/reporter_detail.html', dict(reports=reports, works=works, works_properly=works_properly, name=name, guid=guid, form=form))
def reporter_detail(request, guid): try: addon = Addon.objects.get(guid=guid) except Addon.DoesNotExist: addon = None name = addon.name if addon else guid qs = CompatReport.objects.filter(guid=guid) show_listed_only = addon and not owner_or_unlisted_reviewer(request, addon) if (addon and not addon.has_listed_versions() and show_listed_only): # Not authorized? Let's pretend this addon simply doesn't exist. name = guid qs = CompatReport.objects.none() elif show_listed_only: unlisted_versions = addon.versions.filter( channel=amo.RELEASE_CHANNEL_UNLISTED).values_list( 'version', flat=True) qs = qs.exclude(version__in=unlisted_versions) form = AppVerForm(request.GET) if request.GET and form.is_valid() and form.cleaned_data['appver']: # Apply filters only if we have a good app/version combination. version = form.cleaned_data['appver'] ver = vdict(floor_version(version))['major'] # 3.6 => 3 # Ideally we'd have a `version_int` column to do strict version # comparing, but that's overkill for basic version filtering here. qs = qs.filter(app_guid=amo.FIREFOX.guid, app_version__startswith=str(ver) + '.') works_ = dict(qs.values_list('works_properly').annotate(Count('id'))) works = {'success': works_.get(True, 0), 'failure': works_.get(False, 0)} works_properly = request.GET.get('works_properly') if works_properly: qs = qs.filter(works_properly=works_properly) reports = paginate(request, qs.order_by('-created'), 100) return render(request, 'compat/reporter_detail.html', dict(reports=reports, works=works, works_properly=works_properly, name=name, guid=guid, form=form))
def review_list(request, addon, review_id=None, user_id=None, template=None): q = (Review.objects.valid().filter(addon=addon) .order_by('-created')) ctx = {'addon': addon, 'grouped_ratings': GroupedRating.get(addon.id)} ctx['form'] = forms.ReviewForm(None) if review_id is not None: ctx['page'] = 'detail' # If this is a dev reply, find the first msg for context. review = get_object_or_404(Review.objects.all(), pk=review_id) if review.reply_to_id: review_id = review.reply_to_id ctx['reply'] = review q = q.filter(pk=review_id) elif user_id is not None: ctx['page'] = 'user' q = q.filter(user=user_id) if not q: raise http.Http404() else: ctx['page'] = 'list' q = q.filter(is_latest=True) ctx['reviews'] = reviews = amo_utils.paginate(request, q) ctx['replies'] = Review.get_replies(reviews.object_list) if request.user.is_authenticated(): ctx['review_perms'] = { 'is_admin': acl.action_allowed(request, 'Addons', 'Edit'), 'is_editor': acl.is_editor(request, addon), 'is_author': acl.check_addon_ownership(request, addon, viewer=True, dev=True, support=True), } ctx['flags'] = get_flags(request, reviews.object_list) else: ctx['review_perms'] = {} return render(request, template, ctx)
def _queue(request, TableObj, tab, qs=None, unlisted=False, SearchForm=forms.QueueSearchForm): if qs is None: qs = TableObj.Meta.model.objects.all() if is_limited_reviewer(request): qs = qs.having('waiting_time_hours >=', REVIEW_LIMITED_DELAY_HOURS) if request.GET: search_form = SearchForm(request.GET) if search_form.is_valid(): qs = search_form.filter_qs(qs) else: search_form = SearchForm() admin_reviewer = is_admin_reviewer(request) if not admin_reviewer and not search_form.data.get('searching'): qs = exclude_admin_only_addons(qs) motd_editable = acl.action_allowed(request, 'AddonReviewerMOTD', 'Edit') order_by = request.GET.get('sort', TableObj.default_order_by()) if hasattr(TableObj, 'translate_sort_cols'): order_by = TableObj.translate_sort_cols(order_by) table = TableObj(data=qs, order_by=order_by) default = 100 per_page = request.GET.get('per_page', default) try: per_page = int(per_page) except ValueError: per_page = default if per_page <= 0 or per_page > 200: per_page = default page = paginate(request, table.rows, per_page=per_page) table.set_page(page) return render(request, 'editors/queue.html', context(request, table=table, page=page, tab=tab, search_form=search_form, point_types=amo.REVIEWED_AMO, unlisted=unlisted, motd_editable=motd_editable))
def reporter_detail(request, guid): try: addon = Addon.with_unlisted.get(guid=guid) except Addon.DoesNotExist: addon = None name = addon.name if addon else guid qs = CompatReport.objects.filter(guid=guid) if (addon and not addon.is_listed and not owner_or_unlisted_reviewer(request, addon)): # Not authorized? Let's pretend this addon simply doesn't exist. name = guid qs = CompatReport.objects.none() form = AppVerForm(request.GET) if request.GET and form.is_valid() and form.cleaned_data['appver']: # Apply filters only if we have a good app/version combination. app, ver = form.cleaned_data['appver'].split('-') app = amo.APP_IDS[int(app)] ver = vdict(floor_version(ver))['major'] # 3.6 => 3 # Ideally we'd have a `version_int` column to do strict version # comparing, but that's overkill for basic version filtering here. qs = qs.filter(app_guid=app.guid, app_version__startswith=str(ver) + '.') works_ = dict(qs.values_list('works_properly').annotate(Count('id'))) works = {'success': works_.get(True, 0), 'failure': works_.get(False, 0)} works_properly = request.GET.get('works_properly') if works_properly: qs = qs.filter(works_properly=works_properly) reports = amo_utils.paginate(request, qs.order_by('-created'), 100) return render(request, 'compat/reporter_detail.html', dict(reports=reports, works=works, works_properly=works_properly, name=name, guid=guid, form=form))
def read(self, request, addon_id=None): """ Returns authors who can update an addon (not Viewer role) for addons that have not been admin disabled. Optionally provide an addon id. """ if not request.user.is_authenticated(): return rc.BAD_REQUEST ids = (AddonUser.objects.values_list('addon_id', flat=True) .filter(user=request.user, role__in=[amo.AUTHOR_ROLE_DEV, amo.AUTHOR_ROLE_OWNER])) qs = (Addon.objects.filter(id__in=ids) .exclude(status=amo.STATUS_DISABLED) .no_transforms()) if addon_id: try: return qs.get(id=addon_id) except Addon.DoesNotExist: rc.NOT_HERE paginator = paginate(request, qs) return {'objects': paginator.object_list, 'num_pages': paginator.paginator.num_pages, 'count': paginator.paginator.count}
def themes_single(request, slug): """ Like a detail page, manually review a single theme if it is pending and isn't locked. """ reviewer = request.user reviewable = True # Don't review an already reviewed theme. theme = get_object_or_404(Persona, addon__slug=slug) if (theme.addon.status != amo.STATUS_PENDING and not theme.rereviewqueuetheme_set.all()): reviewable = False if (not settings.ALLOW_SELF_REVIEWS and not acl.action_allowed(request, amo.permissions.REVIEWS_ADMIN) and theme.addon.has_author(request.user)): reviewable = False else: # Don't review a locked theme (that's not locked to self). try: lock = theme.themelock if (lock.reviewer.id != reviewer.id and lock.expiry > datetime.datetime.now()): reviewable = False elif (lock.reviewer.id != reviewer.id and lock.expiry < datetime.datetime.now()): # Steal expired lock. lock.reviewer = reviewer lock.expiry = get_updated_expiry() lock.save() else: # Update expiry. lock.expiry = get_updated_expiry() lock.save() except ThemeLock.DoesNotExist: # Create lock if not created. ThemeLock.objects.create(theme=theme, reviewer=reviewer, expiry=get_updated_expiry()) ThemeReviewFormset = formset_factory(forms.ThemeReviewForm) formset = ThemeReviewFormset(initial=[{'theme': theme.id}]) # Since we started the review on the single page, we want to return to the # single page rather than get shot back to the queue. request.session['theme_redirect_url'] = reverse('reviewers.themes.single', args=[theme.addon.slug]) rereview = (theme.rereviewqueuetheme_set.all()[0] if theme.rereviewqueuetheme_set.exists() else None) return render(request, 'reviewers/themes/single.html', context( **{'formset': formset, 'theme': rereview if rereview else theme, 'theme_formsets': zip([rereview if rereview else theme], formset), 'theme_reviews': paginate(request, ActivityLog.objects.filter( action=amo.LOG.THEME_REVIEW.id, _arguments__contains=theme.addon.id)), 'actions': get_actions_json(), 'theme_count': 1, 'rereview': rereview, 'reviewable': reviewable, 'reject_reasons': amo.THEME_REJECT_REASONS, 'action_dict': amo.REVIEW_ACTIONS, 'tab': ('flagged' if theme.addon.status == amo.STATUS_REVIEW_PENDING else 'rereview' if rereview else 'pending')}))