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=mkt.LOG_HIDE_DEVELOPER) admin_items = ActivityLog.objects.for_apps([app]).filter( action__in=mkt.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 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.ReviewLogForm(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__email__icontains=term)).distinct() pager = paginate(request, approvals, 50) data = context(request, form=form, pager=pager, ACTION_DICT=mkt.LOG_BY_ID, tab='logs') return render(request, 'reviewers/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 render(request, 'reviewers/abuse.html', context(request, item=addon, reports=reports, total=total))
def transactions(request): form, transactions = _get_transactions(request) return render( request, 'developers/transactions.html', {'form': form, 'CONTRIB_TYPES': mkt.CONTRIB_TYPES, 'count': transactions.count(), 'transactions': paginate(request, transactions, per_page=50)})
def website_abuse(request, website): reports = AbuseReport.objects.filter(website=website).order_by('-created') total = reports.count() reports = paginate(request, reports, count=total) return render(request, 'reviewers/abuse.html', context(request, item=website, reports=reports, total=total))
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=mkt.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=mkt.LOG.DELETE_USER_LOOKUP.id)[0] except IndexError: delete_log = None group_membership_formset = APIGroupMembershipFormSet() 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, 'group_membership_formset': group_membership_formset})
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 dashboard(request): addons, sorting = addon_listing(request) addons = paginate(request, addons, per_page=10) data = { 'addons': addons, 'sorting': sorting, 'motd': unmemoized_get_config('mkt_developers_motd') } return render(request, 'developers/apps/dashboard.html', data)
def transactions(request): form, transactions = _get_transactions(request) return render( request, "developers/transactions.html", { "form": form, "CONTRIB_TYPES": mkt.CONTRIB_TYPES, "count": transactions.count(), "transactions": paginate(request, transactions, per_page=50), }, )
def moderatelog(request): form = ModerateLogForm(request.GET) modlog = ActivityLog.objects.editor_events() if form.is_valid(): if form.cleaned_data['start']: modlog = modlog.filter(created__gte=form.cleaned_data['start']) if form.cleaned_data['end']: modlog = modlog.filter(created__lt=form.cleaned_data['end']) if form.cleaned_data['search']: modlog = modlog.filter(action=form.cleaned_data['search'].id) pager = paginate(request, modlog, 50) data = context(request, form=form, pager=pager, tab='moderatelog') return render(request, 'reviewers/moderatelog.html', data)
def queue_abuse_websites(request): """Queue for reviewing abuse reports for websites.""" queues_helper = ReviewersQueuesHelper(request) sites = queues_helper.get_abuse_queue_websites() page = paginate(request, sites, per_page=20) abuse_formset = WebsiteAbuseViewFormSet(request.POST or None, queryset=page.object_list, request=request) if abuse_formset.is_valid(): abuse_formset.save() return redirect(reverse('reviewers.websites.queue_abuse')) return render(request, 'reviewers/queue.html', context(request, abuse_formset=abuse_formset, tab='abusewebsites', page=page))
def purchase_list(request, user): # Return all apps that the user has a contribution for as well as all apps # they have installed. def get_ids(qs): return list(qs.order_by('-id').values_list('addon_id', flat=True)) contributed_apps_ids = get_ids(user.contribution_set.filter(type__in=[ mkt.CONTRIB_PURCHASE, mkt.CONTRIB_REFUND, mkt.CONTRIB_CHARGEBACK])) installed_apps_ids = get_ids(user.installed_set.filter(install_type__in=[ apps.INSTALL_TYPE_USER, apps.INSTALL_TYPE_DEVELOPER]).exclude( addon__in=contributed_apps_ids)) addon_ids = contributed_apps_ids + installed_apps_ids qs = Webapp.objects.filter(id__in=addon_ids) products = paginate(request, manual_order(qs, addon_ids), count=qs.count()) return products
def queue_abuse(request): """Queue for reviewing abuse reports for apps.""" queues_helper = ReviewersQueuesHelper(request) apps = queues_helper.get_abuse_queue() page = paginate(request, apps, per_page=20) abuse_formset = AppAbuseViewFormSet(request.POST or None, queryset=page.object_list, request=request) if abuse_formset.is_valid(): abuse_formset.save() return redirect(reverse('reviewers.apps.queue_abuse')) return render( request, 'reviewers/queue.html', context(request, abuse_formset=abuse_formset, tab='abuse', page=page))
def queue_moderated(request): """Queue for reviewing app reviews.""" queues_helper = ReviewersQueuesHelper(request) qs = queues_helper.get_moderated_queue() page = paginate(request, qs, per_page=20) flags = dict(ReviewFlag.FLAGS) reviews_formset = ReviewFlagFormSet(request.POST or None, queryset=page.object_list, request=request) if reviews_formset.is_valid(): reviews_formset.save() return redirect(reverse('reviewers.apps.queue_moderated')) return render(request, 'reviewers/queue.html', context(request, reviews_formset=reviews_formset, tab='moderated', page=page, flags=flags))
def purchase_list(request, user): # Return all apps that the user has a contribution for as well as all apps # they have installed. def get_ids(qs): return list(qs.order_by('-id').values_list('addon_id', flat=True)) contributed_apps_ids = get_ids( user.contribution_set.filter(type__in=[ mkt.CONTRIB_PURCHASE, mkt.CONTRIB_REFUND, mkt.CONTRIB_CHARGEBACK ])) installed_apps_ids = get_ids( user.installed_set.filter(install_type__in=[ apps.INSTALL_TYPE_USER, apps.INSTALL_TYPE_DEVELOPER ]).exclude(addon__in=contributed_apps_ids)) addon_ids = contributed_apps_ids + installed_apps_ids qs = Webapp.objects.filter(id__in=addon_ids) products = paginate(request, manual_order(qs, addon_ids), count=qs.count()) return products
def dashboard(request): addons, sorting = addon_listing(request) addons = paginate(request, addons, per_page=10) data = {"addons": addons, "sorting": sorting, "motd": unmemoized_get_config("mkt_developers_motd")} return render(request, "developers/apps/dashboard.html", data)
def preloads(request): preloads = (PreloadTestPlan.objects.filter( status=mkt.STATUS_PUBLIC).order_by('-created')) preloads = paginate(request, preloads, per_page=20) return render(request, 'operators/preloads.html', {'preloads': preloads})
def preloads(request): preloads = (PreloadTestPlan.objects.filter(status=mkt.STATUS_PUBLIC) .order_by('-created')) preloads = paginate(request, preloads, per_page=20) return render(request, 'operators/preloads.html', {'preloads': preloads})
def _review(request, addon, version): if (not settings.ALLOW_SELF_REVIEWS and not acl.action_allowed(request, 'Admin', '%') and addon.has_author(request.user)): messages.warning(request, _('Self-reviews are not allowed.')) return redirect(reverse('reviewers.home')) if (addon.status == mkt.STATUS_BLOCKED and not acl.action_allowed(request, 'Apps', 'ReviewEscalated')): messages.warning( request, _('Only senior reviewers can review blocklisted apps.')) return redirect(reverse('reviewers.home')) attachment_formset = CommAttachmentFormSet(data=request.POST or None, files=request.FILES or None, prefix='attachment') testedon_formset = TestedOnFormSet(data=request.POST or None, prefix='testedon') form = forms.get_review_form(data=request.POST or None, files=request.FILES or None, request=request, addon=addon, version=version, attachment_formset=attachment_formset, testedon_formset=testedon_formset) postdata = request.POST if request.method == 'POST' else None all_forms = [form, attachment_formset, testedon_formset] if version: features_list = version.features.to_names() appfeatures_form = AppFeaturesForm(data=postdata, instance=version.features) all_forms.append(appfeatures_form) else: appfeatures_form = None features_list = None queue_type = form.helper.review_type redirect_url = reverse('reviewers.apps.queue_%s' % queue_type) is_admin = acl.action_allowed(request, 'Apps', 'Edit') if request.method == 'POST' and all(f.is_valid() for f in all_forms): if form.cleaned_data.get('action') == 'public': old_types = set(o.id for o in addon.device_types) new_types = set(form.cleaned_data.get('device_override')) if old_types != new_types: # The reviewer overrode the device types. We need to not # publish this app immediately. if addon.publish_type == mkt.PUBLISH_IMMEDIATE: addon.update(publish_type=mkt.PUBLISH_PRIVATE) # And update the device types to what the reviewer set. AddonDeviceType.objects.filter(addon=addon).delete() for device in form.cleaned_data.get('device_override'): addon.addondevicetype_set.create(device_type=device) # Log that the reviewer changed the device types. added_devices = new_types - old_types removed_devices = old_types - new_types msg_list = [ _(u'Added {0}').format(unicode(mkt.DEVICE_TYPES[d].name)) for d in added_devices ] + [ _(u'Removed {0}').format(unicode(mkt.DEVICE_TYPES[d].name)) for d in removed_devices ] msg = _(u'Device(s) changed by ' u'reviewer: {0}').format(', '.join(msg_list)) log_reviewer_action(addon, request.user, msg, mkt.LOG.REVIEW_DEVICE_OVERRIDE) if appfeatures_form.changed_data: # The reviewer overrode the requirements. We need to not # publish this app immediately. if addon.publish_type == mkt.PUBLISH_IMMEDIATE: addon.update(publish_type=mkt.PUBLISH_PRIVATE) appfeatures_form.save(mark_for_rereview=False) # Log that the reviewer changed the minimum requirements. added_features, removed_features = (appfeatures_form .get_changed_features()) fmt = ', '.join( [_(u'Added {0}').format(f) for f in added_features] + [_(u'Removed {0}').format(f) for f in removed_features]) # L10n: {0} is the list of requirements changes. msg = _(u'Requirements changed by reviewer: {0}').format(fmt) log_reviewer_action(addon, request.user, msg, mkt.LOG.REVIEW_FEATURES_OVERRIDE) score = form.helper.process() if form.cleaned_data.get('is_showcase'): if not addon.tags.filter(tag_text=SHOWCASE_TAG).exists(): Tag(tag_text=SHOWCASE_TAG).save_tag(addon) recipient_list = (settings.APP_CURATION_BOARD_EMAIL,) subject = u'App [%s] nominated to be featured' % addon.name msg = (u'The Marketplace reviewer %s thinks %s (%s%s) is' u'good enough to be a featured app.\n\n' % ( request.user, addon.name, settings.SITE_URL, addon.get_url_path())) send_mail(subject, msg, recipient_list=recipient_list) else: Tag(tag_text=SHOWCASE_TAG).remove_tag(addon) # Success message. if score: score = ReviewerScore.objects.filter(user=request.user)[0] # L10N: {0} is the type of review. {1} is the points they earned. # {2} is the points they now have total. success = _( u'"{0}" successfully processed (+{1} points, {2} total).' .format(unicode(mkt.REVIEWED_CHOICES[score.note_key]), score.score, ReviewerScore.get_total(request.user))) else: success = _('Review successfully processed.') messages.success(request, success) return redirect(redirect_url) canned = CannedResponse.objects.all() actions = form.helper.actions.items() try: if not version: raise Version.DoesNotExist show_diff = (addon.versions.exclude(id=version.id) .filter(files__isnull=False, created__lt=version.created, files__status=mkt.STATUS_PUBLIC) .latest()) except Version.DoesNotExist: show_diff = None # The actions we should show a minimal form from. actions_minimal = [k for (k, a) in actions if not a.get('minimal')] # We only allow the user to check/uncheck files for "pending" allow_unchecking_files = form.helper.review_type == "pending" versions = (Version.with_deleted.filter(addon=addon) .order_by('-created') .transform(Version.transformer_activity) .transform(Version.transformer)) product_attrs = { 'product': json.dumps( product_as_dict(request, addon, False, 'reviewer'), cls=JSONEncoder), 'manifest_url': addon.manifest_url, } pager = paginate(request, versions, 10) num_pages = pager.paginator.num_pages count = pager.paginator.count ctx = context(request, version=version, product=addon, pager=pager, num_pages=num_pages, count=count, form=form, canned=canned, is_admin=is_admin, status_types=mkt.STATUS_CHOICES, show_diff=show_diff, allow_unchecking_files=allow_unchecking_files, actions=actions, actions_minimal=actions_minimal, tab=queue_type, product_attrs=product_attrs, attachment_formset=attachment_formset, appfeatures_form=appfeatures_form, testedon_formset=testedon_formset) if features_list is not None: ctx['feature_list'] = features_list return render(request, 'reviewers/review.html', ctx)
def _review(request, addon, version): if (not settings.ALLOW_SELF_REVIEWS and not acl.action_allowed(request, 'Admin', '%') and addon.has_author(request.user)): messages.warning(request, _('Self-reviews are not allowed.')) return redirect(reverse('reviewers.home')) if (addon.status == mkt.STATUS_BLOCKED and not acl.action_allowed(request, 'Apps', 'ReviewEscalated')): messages.warning( request, _('Only senior reviewers can review blocklisted apps.')) return redirect(reverse('reviewers.home')) attachment_formset = CommAttachmentFormSet(data=request.POST or None, files=request.FILES or None, prefix='attachment') testedon_formset = TestedOnFormSet(data=request.POST or None, prefix='testedon') form = forms.get_review_form(data=request.POST or None, files=request.FILES or None, request=request, addon=addon, version=version, attachment_formset=attachment_formset, testedon_formset=testedon_formset) postdata = request.POST if request.method == 'POST' else None all_forms = [form, attachment_formset, testedon_formset] if version: features_list = version.features.to_names() appfeatures_form = AppFeaturesForm(data=postdata, instance=version.features) all_forms.append(appfeatures_form) else: appfeatures_form = None features_list = None queue_type = form.helper.review_type redirect_url = reverse('reviewers.apps.queue_%s' % queue_type) is_admin = acl.action_allowed(request, 'Apps', 'Edit') if request.method == 'POST' and all(f.is_valid() for f in all_forms): if form.cleaned_data.get('action') == 'public': old_types = set(o.id for o in addon.device_types) new_types = set(form.cleaned_data.get('device_override')) if old_types != new_types: # The reviewer overrode the device types. We need to not # publish this app immediately. if addon.publish_type == mkt.PUBLISH_IMMEDIATE: addon.update(publish_type=mkt.PUBLISH_PRIVATE) # And update the device types to what the reviewer set. AddonDeviceType.objects.filter(addon=addon).delete() for device in form.cleaned_data.get('device_override'): addon.addondevicetype_set.create(device_type=device) # Log that the reviewer changed the device types. added_devices = new_types - old_types removed_devices = old_types - new_types msg_list = [ _(u'Added {0}').format(unicode(mkt.DEVICE_TYPES[d].name)) for d in added_devices ] + [ _(u'Removed {0}').format(unicode(mkt.DEVICE_TYPES[d].name)) for d in removed_devices ] msg = _(u'Device(s) changed by ' u'reviewer: {0}').format(', '.join(msg_list)) log_reviewer_action(addon, request.user, msg, mkt.LOG.REVIEW_DEVICE_OVERRIDE) if appfeatures_form.changed_data: # The reviewer overrode the requirements. We need to not # publish this app immediately. if addon.publish_type == mkt.PUBLISH_IMMEDIATE: addon.update(publish_type=mkt.PUBLISH_PRIVATE) appfeatures_form.save(mark_for_rereview=False) # Log that the reviewer changed the minimum requirements. added_features, removed_features = ( appfeatures_form.get_changed_features()) fmt = ', '.join( [_(u'Added {0}').format(f) for f in added_features] + [_(u'Removed {0}').format(f) for f in removed_features]) # L10n: {0} is the list of requirements changes. msg = _(u'Requirements changed by reviewer: {0}').format(fmt) log_reviewer_action(addon, request.user, msg, mkt.LOG.REVIEW_FEATURES_OVERRIDE) score = form.helper.process() if form.cleaned_data.get('is_showcase'): if not addon.tags.filter(tag_text=SHOWCASE_TAG).exists(): Tag(tag_text=SHOWCASE_TAG).save_tag(addon) recipient_list = (settings.APP_CURATION_BOARD_EMAIL, ) subject = u'App [%s] nominated to be featured' % addon.name msg = (u'The Marketplace reviewer %s thinks %s (%s%s) is' u'good enough to be a featured app.\n\n' % (request.user, addon.name, settings.SITE_URL, addon.get_url_path())) send_mail(subject, msg, recipient_list=recipient_list) else: Tag(tag_text=SHOWCASE_TAG).remove_tag(addon) # Success message. if score: score = ReviewerScore.objects.filter(user=request.user)[0] # L10N: {0} is the type of review. {1} is the points they earned. # {2} is the points they now have total. success = _( u'"{0}" successfully processed (+{1} points, {2} total).'. format(unicode(mkt.REVIEWED_CHOICES[score.note_key]), score.score, ReviewerScore.get_total(request.user))) else: success = _('Review successfully processed.') messages.success(request, success) return redirect(redirect_url) canned = CannedResponse.objects.all() actions = form.helper.actions.items() try: if not version: raise Version.DoesNotExist show_diff = (addon.versions.exclude(id=version.id).filter( files__isnull=False, created__lt=version.created, files__status=mkt.STATUS_PUBLIC).latest()) except Version.DoesNotExist: show_diff = None # The actions we should show a minimal form from. actions_minimal = [k for (k, a) in actions if not a.get('minimal')] # We only allow the user to check/uncheck files for "pending" allow_unchecking_files = form.helper.review_type == "pending" versions = (Version.with_deleted.filter( addon=addon).order_by('-created').transform( Version.transformer_activity).transform(Version.transformer)) product_attrs = { 'product': json.dumps(product_as_dict(request, addon, False, 'reviewer'), cls=JSONEncoder), 'manifest_url': addon.manifest_url, } pager = paginate(request, versions, 10) num_pages = pager.paginator.num_pages count = pager.paginator.count ctx = context(request, version=version, product=addon, pager=pager, num_pages=num_pages, count=count, form=form, canned=canned, is_admin=is_admin, status_types=mkt.STATUS_CHOICES, show_diff=show_diff, allow_unchecking_files=allow_unchecking_files, actions=actions, actions_minimal=actions_minimal, tab=queue_type, product_attrs=product_attrs, attachment_formset=attachment_formset, appfeatures_form=appfeatures_form, testedon_formset=testedon_formset) if features_list is not None: ctx['feature_list'] = features_list return render(request, 'reviewers/review.html', ctx)