def profile(request, user): # Temporary until we decide we want user profile pages. raise http.Http404 edit_any_user = acl.action_allowed(request, 'Users', 'Edit') own_profile = (request.user.is_authenticated() and request.amo_user.id == user.id) submissions = [] if user.is_developer: submissions = paginate(request, user.apps_listed.order_by('-weekly_downloads'), per_page=5) reviews = user.reviews.filter(addon__type=amo.ADDON_WEBAPP) reviews = paginate(request, reviews, per_page=5) data = { 'profile': user, 'edit_any_user': edit_any_user, 'submissions': submissions, 'own_profile': own_profile, 'reviews': reviews } return jingo.render(request, 'account/profile.html', data)
def app_activity(request, addon): """Shows the app activity age for single app.""" user_items = ActivityLog.objects.for_apps([addon]).exclude(action__in=amo.LOG_HIDE_DEVELOPER) admin_items = ActivityLog.objects.for_apps([addon]).filter(action__in=amo.LOG_HIDE_DEVELOPER) user_items = paginate(request, user_items, per_page=20) admin_items = paginate(request, admin_items, per_page=20) return jingo.render( request, "detail/app_activity.html", {"admin_items": admin_items, "product": addon, "user_items": user_items} )
def app_activity(request, addon_id): """Shows the app activity age for single app.""" app = get_object_or_404(Webapp.with_deleted, pk=addon_id) user_items = ActivityLog.objects.for_apps([app]).exclude(action__in=amo.LOG_HIDE_DEVELOPER) admin_items = ActivityLog.objects.for_apps([app]).filter(action__in=amo.LOG_HIDE_DEVELOPER) user_items = paginate(request, user_items, per_page=20) admin_items = paginate(request, admin_items, per_page=20) return render( request, "lookup/app_activity.html", {"admin_items": admin_items, "app": app, "user_items": user_items} )
def app_activity(request, addon_id): """Shows the app activity age for single app.""" app = get_object_or_404(Webapp.with_deleted, pk=addon_id) user_items = ActivityLog.objects.for_apps([app]).exclude( action__in=amo.LOG_HIDE_DEVELOPER) admin_items = ActivityLog.objects.for_apps([app]).filter( action__in=amo.LOG_HIDE_DEVELOPER) user_items = paginate(request, user_items, per_page=20) admin_items = paginate(request, admin_items, per_page=20) return render(request, 'lookup/app_activity.html', { 'admin_items': admin_items, 'app': app, 'user_items': user_items})
def themes_single(request, slug): """ Like a detail page, manually review a single theme if it is pending and isn't locked. """ reviewer = request.amo_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: reviewable = False # Don't review a locked theme (that's not locked to self). try: theme_lock = theme.themelock if theme_lock.reviewer.id != reviewer.id and theme_lock.expiry > datetime.datetime.now(): reviewable = False elif theme_lock.reviewer.id != reviewer.id and theme_lock.expiry < datetime.datetime.now(): # Steal expired lock. theme_lock.reviewer = (reviewer,) theme_lock.expiry = get_updated_expiry() theme_lock.save() else: # Update expiry. theme_lock.expiry = get_updated_expiry() theme_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]) return jingo.render( request, "reviewers/themes/single.html", context( **{ "formset": formset, "theme": theme, "theme_formsets": zip([theme], formset), "theme_reviews": paginate( request, ActivityLog.objects.filter(action=amo.LOG.THEME_REVIEW.id, _arguments__contains=theme.addon.id), ), # Setting this to 0 makes sure more themes aren't loaded from more(). "max_locks": 0, "actions": get_actions_json(), "theme_count": 1, "reviewable": reviewable, "reject_reasons": rvw.THEME_REJECT_REASONS.items(), "action_dict": rvw.REVIEW_ACTIONS, } ), )
def app_list(request, category=None): if category is not None: q = Category.objects.filter(type=TYPE) category = get_object_or_404(q, slug=category) sort = request.GET.get('sort') if not sort and not request.MOBILE and category and category.count > 4: return category_landing(request, category, TYPE, AppCategoryLandingFilter) addons, filter = app_listing(request) sorting = filter.field src = 'cb-btn-%s' % sorting dl_src = 'cb-dl-%s' % sorting if category: addons = addons.filter(categories__id=category.id) addons = paginate(request, addons, count=addons.count()) ctx = { 'section': amo.ADDON_SLUGS[TYPE], 'addon_type': TYPE, 'category': category, 'addons': addons, 'filter': filter, 'sorting': sorting, 'sort_opts': filter.opts, 'src': src, 'dl_src': dl_src, 'search_cat': 'apps' } return jingo.render(request, 'browse/extensions.html', ctx)
def app_list(request, category=None, template=None): if category is not None: q = Category.objects.filter(type=TYPE) category = get_object_or_404(q, slug=category) sort = request.GET.get('sort') # TODO: Uncomment this when we have apps category landing pages. #if not sort and not request.MOBILE and category and category.count > 4: # return category_landing(request, category, TYPE, # AppCategoryLandingFilter) addons, filter = app_listing(request) sorting = filter.field src = 'cb-btn-%s' % sorting dl_src = 'cb-dl-%s' % sorting if category: addons = addons.filter(categories__id=category.id) addons = paginate(request, addons, count=addons.count()) ctx = { 'section': amo.ADDON_SLUGS[TYPE], 'addon_type': TYPE, 'category': category, 'addons': addons, 'filter': filter, 'sorting': sorting, 'sort_opts': filter.opts, 'src': src, 'dl_src': dl_src } return jingo.render(request, template, ctx)
def purchase_list(request, user, product_id): cs = (Contribution.objects .filter(user=user, type__in=[amo.CONTRIB_PURCHASE, amo.CONTRIB_INAPP, amo.CONTRIB_REFUND, amo.CONTRIB_CHARGEBACK]) .order_by('created')) if product_id: cs = cs.filter(addon=product_id) ids = list(cs.values_list('addon_id', flat=True)) product_ids = [] # If you are asking for a receipt for just one item, show only that. # Otherwise, we'll show all apps that have a contribution or are free. if not product_id: product_ids = list(user.installed_set .filter(install_type=apps.INSTALL_TYPE_USER) .exclude(addon__in=ids) .values_list('addon_id', flat=True)) contributions = {} for c in cs: contributions.setdefault(c.addon_id, []).append(c) unique_ids = set(ids + product_ids) listing = PurchasesFilter(request, Webapp.objects.all(), key='sort', default='purchased', ids=[ids, product_ids], uids=unique_ids) if product_id and not listing.qs.exists(): # User has requested a receipt for an app he ain't got. raise http.Http404 products = paginate(request, listing.qs, count=len(unique_ids)) return products, contributions, listing
def app_list(request, category=None, template=None): if category is not None: q = Category.objects.filter(type=TYPE) category = get_object_or_404(q, slug=category) #sort = request.GET.get('sort') # TODO: Uncomment this when we have apps category landing pages. #if not sort and not request.MOBILE and category and category.count > 4: # return category_landing(request, category, TYPE, # AppCategoryLandingFilter) addons, filter = app_listing(request) sorting = filter.field src = 'cb-btn-%s' % sorting dl_src = 'cb-dl-%s' % sorting if category: addons = addons.filter(categories__id=category.id) addons = paginate(request, addons, count=addons.count()) ctx = {'section': amo.ADDON_SLUGS[TYPE], 'addon_type': TYPE, 'category': category, 'addons': addons, 'filter': filter, 'sorting': sorting, 'sort_opts': filter.opts, 'src': src, 'dl_src': dl_src} return jingo.render(request, template, ctx)
def _queue(request, qs, tab, pager_processor=None): review_num = request.GET.get('num') if review_num: try: review_num = int(review_num) except ValueError: pass else: try: # Force a limit query for efficiency: start = review_num - 1 row = qs[start:start + 1][0] # Get the addon if the instance is one of the *Queue models. if not isinstance(row, Webapp): row = row.addon return redirect(urlparams( reverse('reviewers.apps.review', args=[row.app_slug]), num=review_num, tab=tab)) except IndexError: pass per_page = request.GET.get('per_page', QUEUE_PER_PAGE) pager = paginate(request, qs, per_page) if pager_processor: addons = pager_processor(pager) else: addons = pager.object_list return jingo.render(request, 'reviewers/queue.html', context(**{ 'addons': addons, 'pager': pager, 'tab': tab, }))
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.ReviewAppLogForm(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__lt=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) return jingo.render(request, "reviewers/themes/logs.html", data)
def deleted_themes(request): data = request.GET.copy() deleted = Addon.with_deleted.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 jingo.render( request, 'reviewers/themes/deleted.html', { 'form': form, 'pager': paginate(request, deleted.order_by('-modified'), 30), 'queue_counts': queue_counts(request), 'tab': 'deleted' })
def deleted_themes(request): data = request.GET.copy() deleted = Addon.with_deleted.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 app_abuse(request, addon): reports = AbuseReport.objects.filter(addon=addon).order_by('-created') total = reports.count() reports = paginate(request, reports, count=total) return render(request, 'reviewers/abuse.html', context(request, addon=addon, reports=reports, total=total))
def _queue(request, TableObj, tab, qs=None): if qs is None: qs = TableObj.Meta.model.objects.all() review_num = request.GET.get('num', None) if review_num: try: review_num = int(review_num) except ValueError: pass else: try: # Force a limit query for efficiency: start = review_num - 1 row = qs[start: start + 1][0] return redirect('%s?num=%s' % ( TableObj.review_url(row), review_num)) except IndexError: pass order_by = request.GET.get('sort', TableObj.default_order_by()) 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 jingo.render(request, 'reviewers/queue.html', context(table=table, page=page, tab=tab))
def queue_apps(request): qs = (Webapp.objects.pending().filter( disabled_by_user=False).order_by('created')) review_num = request.GET.get('num', None) if review_num: try: review_num = int(review_num) except ValueError: pass else: try: # Force a limit query for efficiency: start = review_num - 1 row = qs[start:start + 1][0] return redirect( urlparams(reverse('reviewers.apps.review', args=[row.app_slug]), num=review_num)) except IndexError: pass per_page = request.GET.get('per_page', QUEUE_PER_PAGE) pager = paginate(request, qs, per_page) return jingo.render(request, 'reviewers/queue.html', {'pager': pager})
def _queue(request, TableObj, tab, qs=None): if qs is None: qs = TableObj.Meta.model.objects.all() if request.GET: search_form = forms.QueueSearchForm(request.GET) if search_form.is_valid(): qs = search_form.filter_qs(qs) else: search_form = forms.QueueSearchForm() order_by = request.GET.get('sort', TableObj.default_order_by()) 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(table=table, page=page, tab=tab, search_form=search_form, point_types=amo.REVIEWED_AMO))
def user_summary(request, user_id): user = get_object_or_404(UserProfile, pk=user_id) is_admin = acl.action_allowed(request, "Users", "Edit") app_summary = _app_summary(user.pk) # All refunds that this user has requested (probably as a consumer). req = Refund.objects.filter(contribution__user=user) # All instantly-approved refunds that this user has requested. appr = req.filter(status=amo.REFUND_APPROVED_INSTANT) refund_summary = {"approved": appr.count(), "requested": req.count()} # TODO: This should return all `addon` types and not just webapps. # -- currently get_details_url() fails on non-webapps so this is a # temp fix. user_addons = user.addons.filter(type=amo.ADDON_WEBAPP).order_by("-created") user_addons = paginate(request, user_addons, per_page=15) paypal_ids = set(user.addons.exclude(paypal_id="").values_list("paypal_id", flat=True)) payment_data = ( AddonPaymentData.objects.filter(addon__authors=user).values(*AddonPaymentData.address_fields()).distinct() ) return jingo.render( request, "lookup/user_summary.html", { "account": user, "app_summary": app_summary, "is_admin": is_admin, "refund_summary": refund_summary, "user_addons": user_addons, "payment_data": payment_data, "paypal_ids": paypal_ids, }, )
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 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.ReviewAppLogForm(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(request, form=form, pager=pager, ACTION_DICT=rvw.REVIEW_ACTIONS, REJECT_REASONS=rvw.THEME_REJECT_REASONS, tab='themes') return jingo.render(request, 'reviewers/themes/logs.html', data)
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. """ ids = (AddonUser.objects.values_list('addon_id', flat=True) .filter(user=request.amo_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: 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 = [] if flagged: # TODO (ngoke): rename to STATUS_FLAGGED. themes = Addon.objects.filter(status=amo.STATUS_REVIEW_PENDING, type=amo.ADDON_PERSONA) 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) search_form = _get_search_form(request) per_page = request.GET.get('per_page', QUEUE_PER_PAGE) pager = paginate(request, themes, per_page) return jingo.render(request, 'reviewers/themes/queue_list.html', context( request, **{ 'addons': pager.object_list, 'flagged': flagged, 'pager': pager, 'rereview': rereview, 'STATUS_CHOICES': amo.STATUS_CHOICES, 'search_form': search_form, 'tab': ('rereview_themes' if rereview else 'flagged_themes' if flagged else 'pending_themes'), }))
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. """ ids = (AddonUser.objects.values_list('addon_id', flat=True).filter( user=request.amo_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: 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, 'editors/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_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, 'editors/themes/queue_list.html', context( **{ 'addons': pager.object_list, 'flagged': flagged, 'pager': pager, 'rereview': rereview, 'theme_search_form': search_form, 'STATUS_CHOICES': amo.STATUS_CHOICES, '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 user_summary(request, user_id): user = get_object_or_404(UserProfile, pk=user_id) is_admin = acl.action_allowed(request, 'Users', 'Edit') app_summary = _app_summary(user.pk) # All refunds that this user has requested (probably as a consumer). req = Refund.objects.filter(contribution__user=user) # All instantly-approved refunds that this user has requested. appr = req.filter(status=amo.REFUND_APPROVED_INSTANT) refund_summary = {'approved': appr.count(), 'requested': req.count()} user_addons = user.addons.order_by('-created') user_addons = paginate(request, user_addons, per_page=15) payment_data = (AddonPaymentData.objects.filter(addon__authors=user) .values(*AddonPaymentData.address_fields()) .distinct()) # If the user is deleted, get the log detailing the delete. try: delete_log = ActivityLog.objects.for_user(user).filter( action=amo.LOG.DELETE_USER_LOOKUP.id)[0] except IndexError: delete_log = None provider_portals = get_payment_provider_portals(user=user) return render(request, 'lookup/user_summary.html', {'account': user, 'app_summary': app_summary, 'delete_form': DeleteUserForm(), 'delete_log': delete_log, 'is_admin': is_admin, 'refund_summary': refund_summary, 'user_addons': user_addons, 'payment_data': payment_data, 'provider_portals': provider_portals})
def user_summary(request, user_id): user = get_object_or_404(UserProfile, pk=user_id) is_admin = acl.action_allowed(request, 'Users', 'Edit') app_summary = _app_summary(user.pk) # All refunds that this user has requested (probably as a consumer). req = Refund.objects.filter(contribution__user=user) # All instantly-approved refunds that this user has requested. appr = req.filter(status=amo.REFUND_APPROVED_INSTANT) refund_summary = {'approved': appr.count(), 'requested': req.count()} # TODO: This should return all `addon` types and not just webapps. # -- currently get_details_url() fails on non-webapps so this is a # temp fix. user_addons = (user.addons.filter(type=amo.ADDON_WEBAPP) .order_by('-created')) user_addons = paginate(request, user_addons, per_page=15) paypal_ids = set(user.addons.exclude(paypal_id='') .values_list('paypal_id', flat=True)) payment_data = (AddonPaymentData.objects.filter(addon__authors=user) .values(*AddonPaymentData.address_fields()) .distinct()) return jingo.render(request, 'lookup/user_summary.html', {'account': user, 'app_summary': app_summary, 'is_admin': is_admin, 'refund_summary': refund_summary, 'user_addons': user_addons, 'payment_data': payment_data, 'paypal_ids': paypal_ids})
def 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.ReviewAppLogForm(data) approvals = ActivityLog.objects.review_queue(webapp=True) if form.is_valid(): data = form.cleaned_data if data.get('start'): approvals = approvals.filter(created__gte=data['start']) if data.get('end'): approvals = approvals.filter(created__lt=data['end']) if data.get('search'): term = data['search'] approvals = approvals.filter( Q(commentlog__comments__icontains=term) | Q(applog__addon__name__localized_string__icontains=term) | Q(applog__addon__app_slug__icontains=term) | Q(user__display_name__icontains=term) | Q(user__username__icontains=term)).distinct() pager = paginate(request, approvals, 50) data = context(request, form=form, pager=pager, ACTION_DICT=amo.LOG_BY_ID, tab='apps') return render(request, 'reviewers/logs.html', data)
def user_summary(request, user_id): user = get_object_or_404(UserProfile, pk=user_id) is_admin = acl.action_allowed(request, 'Users', 'Edit') app_summary = _app_summary(user.pk) # All refunds that this user has requested (probably as a consumer). req = Refund.objects.filter(contribution__user=user) # All instantly-approved refunds that this user has requested. appr = req.filter(status=amo.REFUND_APPROVED_INSTANT) refund_summary = {'approved': appr.count(), 'requested': req.count()} # TODO: This should return all `addon` types and not just webapps. # -- currently get_details_url() fails on non-webapps so this is a # temp fix. user_addons = (user.addons.filter( type=amo.ADDON_WEBAPP).order_by('-created')) user_addons = paginate(request, user_addons, per_page=15) paypal_ids = set( user.addons.exclude(paypal_id='').values_list('paypal_id', flat=True)) payment_data = (AddonPaymentData.objects.filter( addon__authors=user).values( *AddonPaymentData.address_fields()).distinct()) return jingo.render( request, 'lookup/user_summary.html', { 'account': user, 'app_summary': app_summary, 'is_admin': is_admin, 'refund_summary': refund_summary, 'user_addons': user_addons, 'payment_data': payment_data, 'paypal_ids': paypal_ids })
def _queue(request, TableObj, tab, qs=None, unlisted=False): if qs is None: qs = TableObj.Meta.model.objects.all() if request.GET: search_form = forms.QueueSearchForm(request.GET) if search_form.is_valid(): qs = search_form.filter_qs(qs) else: search_form = forms.QueueSearchForm() order_by = request.GET.get('sort', TableObj.default_order_by()) 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(table=table, page=page, tab=tab, search_form=search_form, point_types=amo.REVIEWED_AMO, unlisted=unlisted))
def queue_moderated(request): rf = (Review.objects.exclude(Q(addon__isnull=True) | Q(reviewflag__isnull=True)) .filter(editorreview=1) .order_by('reviewflag__created')) page = paginate(request, rf, per_page=20) 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(reviews_formset=reviews_formset, tab='moderated', page=page, flags=flags, search_form=None, point_types=amo.REVIEWED_AMO))
def _queue(request, apps, tab, pager_processor=None, date_sort='created', template='reviewers/queue.html', data=None, use_es=False): per_page = request.GET.get('per_page', QUEUE_PER_PAGE) pager = paginate(request, apps, per_page) ctx = { 'addons': pager.object_list, 'pager': pager, 'tab': tab, 'search_form': _get_search_form(request), 'date_sort': date_sort, 'use_es': use_es, } # Additional context variables. if data is not None: ctx.update(data) return render(request, template, context(request, **ctx))
def queue_apps(request): qs = (Webapp.objects.pending().filter(disabled_by_user=False) .order_by('created')) review_num = request.GET.get('num', None) if review_num: try: review_num = int(review_num) except ValueError: pass else: try: # Force a limit query for efficiency: start = review_num - 1 row = qs[start:start + 1][0] return redirect( urlparams(reverse('reviewers.apps.review', args=[row.app_slug]), num=review_num)) except IndexError: pass per_page = request.GET.get('per_page', QUEUE_PER_PAGE) pager = paginate(request, qs, per_page) return jingo.render(request, 'reviewers/queue.html', {'pager': pager})
def logs(request): data = request.GET.copy() if not data.get('start') and not data.get('end'): today = datetime.date.today() data['start'] = today - datetime.timedelta(days=30) form = forms.ReviewAppLogForm(data) approvals = ActivityLog.objects.review_queue(webapp=True) if form.is_valid(): data = form.cleaned_data if data.get('start'): approvals = approvals.filter(created__gte=data['start']) if data.get('end'): approvals = approvals.filter(created__lt=data['end']) if data.get('search'): term = data['search'] approvals = approvals.filter( Q(commentlog__comments__icontains=term) | Q(applog__addon__name__localized_string__icontains=term) | Q(applog__addon__app_slug__icontains=term) | Q(user__display_name__icontains=term) | Q(user__username__icontains=term)).distinct() pager = paginate(request, approvals, 50) data = context(request, form=form, pager=pager, ACTION_DICT=amo.LOG_BY_ID, tab='apps') return render(request, 'reviewers/logs.html', data)
def preloads(request): preloads = (PreloadTestPlan.objects.filter( status=amo.STATUS_PUBLIC).order_by('addon__name')) preloads = paginate(request, preloads, per_page=20) return jingo.render(request, 'operators/preloads.html', {'preloads': preloads})
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.ReviewAppLogForm(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 app_abuse(request, addon): reports = AbuseReport.objects.filter(addon=addon).order_by('-created') total = reports.count() reports = paginate(request, reports, count=total) return jingo.render( request, 'reviewers/abuse.html', context(request, addon=addon, reports=reports, total=total))
def _queue(request, TableObj, tab, qs=None, unlisted=False): if qs is None: qs = TableObj.Meta.model.objects.all() if request.GET: search_form = forms.QueueSearchForm(request.GET) if search_form.is_valid(): qs = search_form.filter_qs(qs) else: search_form = forms.QueueSearchForm() 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()) 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 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 queue_moderated(request): rf = (Review.objects.exclude( Q(addon__isnull=True) | Q(reviewflag__isnull=True)).filter( editorreview=1).order_by('reviewflag__created')) page = paginate(request, rf, per_page=20) 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(reviews_formset=reviews_formset, tab='moderated', page=page, flags=flags, search_form=None, point_types=amo.REVIEWED_AMO))
def app_activity(request, addon): """Shows the app activity age for single app.""" user_items = ActivityLog.objects.for_apps( [addon]).exclude(action__in=amo.LOG_HIDE_DEVELOPER) admin_items = ActivityLog.objects.for_apps( [addon]).filter(action__in=amo.LOG_HIDE_DEVELOPER) user_items = paginate(request, user_items, per_page=20) admin_items = paginate(request, admin_items, per_page=20) return jingo.render(request, 'detail/app_activity.html', { 'admin_items': admin_items, 'product': addon, 'user_items': user_items })
def following(request): qs = (Collection.objects.filter(following__user=request.amo_user) .order_by('-following__created')) collections = paginate(request, qs) votes = get_votes(request, collections.object_list) return render(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.amo_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 preloads(request): preloads = (PreloadTestPlan.objects.filter(status=amo.STATUS_PUBLIC) .order_by('addon__name')) preloads = paginate(request, preloads, per_page=20) return jingo.render(request, 'operators/preloads.html', { 'preloads': preloads })
def themes_single(request, slug): """ Like a detail page, manually review a single theme if it is pending and isn't locked. """ reviewer = request.amo_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: reviewable = False # Don't review a locked theme (that's not locked to self). try: theme_lock = theme.themelock if (theme_lock.reviewer.id != reviewer.id and theme_lock.expiry > datetime.datetime.now()): reviewable = False elif (theme_lock.reviewer.id != reviewer.id and theme_lock.expiry < datetime.datetime.now()): # Steal expired lock. theme_lock.reviewer = reviewer, theme_lock.expiry = get_updated_expiry() theme_lock.save() else: # Update expiry. theme_lock.expiry = get_updated_expiry() theme_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]) return jingo.render(request, 'reviewers/themes/single.html', context( **{ 'formset': formset, 'theme': theme, 'theme_formsets': zip([theme], formset), 'theme_reviews': paginate(request, ActivityLog.objects.filter( action=amo.LOG.THEME_REVIEW.id, _arguments__contains=theme.addon.id)), 'max_locks': 0, # Setting this to 0 makes sure more Themes aren't # loaded from more(). 'actions': get_actions_json(), 'theme_count': 1, 'reviewable': reviewable, 'reject_reasons': rvw.THEME_REJECT_REASONS.items(), 'action_dict': rvw.REVIEW_ACTIONS, }))
def _queue(request, apps, tab, pager_processor=None): per_page = request.GET.get('per_page', QUEUE_PER_PAGE) pager = paginate(request, apps, per_page) return jingo.render(request, 'reviewers/queue.html', context(**{ 'addons': pager.object_list, 'pager': pager, 'tab': tab, }))
def following(request): qs = Collection.objects.filter(following__user=request.amo_user).order_by("-following__created") collections = paginate(request, qs) votes = get_votes(request, collections.object_list) return render( request, "bandwagon/user_listing.html", dict(collections=collections, votes=votes, page="following", filter=get_filter(request)), )
def profile(request, user): edit_any_user = acl.action_allowed(request, 'Users', 'Edit') own_profile = (request.user.is_authenticated() and request.amo_user.id == user.id) submissions = [] if user.is_developer: submissions = paginate(request, user.apps_listed.order_by('-weekly_downloads'), per_page=5) reviews = user.reviews.filter(addon__type=amo.ADDON_WEBAPP) reviews = paginate(request, reviews, per_page=5) data = {'profile': user, 'edit_any_user': edit_any_user, 'submissions': submissions, 'own_profile': own_profile, 'reviews': reviews} return jingo.render(request, 'account/profile.html', data)
def _queue(request, apps, tab, pager_processor=None, date_sort='created'): per_page = request.GET.get('per_page', QUEUE_PER_PAGE) pager = paginate(request, apps, per_page) return jingo.render(request, 'reviewers/queue.html', context(request, **{ 'addons': pager.object_list, 'pager': pager, 'tab': tab, 'search_form': _get_search_form(request), 'date_sort': date_sort }))
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 read(self, request, id=None): if id: try: return self.model.objects.get(pk=id) except Performance.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 user_listing(request, username): author = get_object_or_404(UserProfile, username=username) qs = (Collection.objects.filter(author__username=username) .order_by('-created')) if not (request.user.is_authenticated() and request.amo_user.username == username): qs = qs.filter(listed=True) collections = paginate(request, qs) votes = get_votes(request, collections.object_list) return render(request, 'bandwagon/user_listing.html', dict(collections=collections, collection_votes=votes, page='mine', author=author, filter=get_filter(request)))
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) collections = paginate(request, filter.qs) return render(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 themes_history(request, username): if not username: username = request.amo_user.username return render(request, 'editors/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': rvw.THEME_REJECT_REASONS, 'action_dict': rvw.REVIEW_ACTIONS}))
def collection_detail(request, username, slug): c = get_collection(request, username, slug) if not c.listed: if not request.user.is_authenticated(): return redirect_for_login(request) if not acl.check_collection_ownership(request, c): raise PermissionDenied if request.GET.get('format') == 'rss': return http.HttpResponsePermanentRedirect(c.feed_url()) base = Addon.objects.valid() & c.addons.all() filter = CollectionAddonFilter(request, base, key='sort', default='popular') notes = get_notes(c) # Go directly to CollectionAddon for the count to avoid joins. count = CollectionAddon.objects.filter(Addon.objects.valid_q( amo.VALID_STATUSES, prefix='addon__'), collection=c.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({c.flush_key(): keys}) if c.author_id: qs = Collection.objects.listed().filter(author=c.author) others = amo.utils.randslice(qs, limit=4, exclude=c.id) else: others = [] # `perms` is defined in django.contrib.auth.context_processors. Gotcha! user_perms = { 'view_stats': acl.check_ownership(request, c, require_owner=False), } tags = Tag.objects.filter(id__in=c.top_tags) if c.top_tags else [] return render_cat( request, 'bandwagon/collection_detail.html', { 'collection': c, 'filter': filter, 'addons': addons, 'notes': notes, 'author_collections': others, 'tags': tags, 'user_perms': user_perms })
def _queue(request, apps, tab, pager_processor=None): per_page = request.GET.get('per_page', QUEUE_PER_PAGE) pager = paginate(request, apps, per_page) return jingo.render( request, 'reviewers/queue.html', context( **{ 'addons': pager.object_list, 'pager': pager, 'tab': tab, 'search_form': _get_search_form(request), 'point_types': amo.REVIEWED_MARKETPLACE, }))