Beispiel #1
0
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'
    })
Beispiel #4
0
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))
Beispiel #5
0
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))
Beispiel #6
0
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))
Beispiel #7
0
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'
        })
Beispiel #8
0
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))
Beispiel #9
0
    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
        })
Beispiel #10
0
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_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')}))
Beispiel #12
0
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)
Beispiel #13
0
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))
Beispiel #14
0
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)
Beispiel #16
0
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})
Beispiel #17
0
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))
Beispiel #18
0
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)))
Beispiel #19
0
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)))
Beispiel #20
0
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'})
Beispiel #21
0
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))
Beispiel #22
0
    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)
Beispiel #23
0
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))
Beispiel #24
0
    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)
Beispiel #25
0
 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'
        })
Beispiel #27
0
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))
Beispiel #28
0
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 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}))
Beispiel #30
0
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}))
Beispiel #32
0
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)
Beispiel #33
0
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
Beispiel #34
0
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})
Beispiel #35
0
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})
Beispiel #36
0
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
Beispiel #37
0
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)
Beispiel #38
0
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))
Beispiel #39
0
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)))
Beispiel #40
0
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})
Beispiel #41
0
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))
Beispiel #42
0
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)))
Beispiel #43
0
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'})
Beispiel #44
0
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'
        })
Beispiel #45
0
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))
Beispiel #46
0
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))
Beispiel #47
0
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)
Beispiel #48
0
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))
Beispiel #49
0
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))
Beispiel #50
0
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)
Beispiel #51
0
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))
Beispiel #52
0
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))
Beispiel #53
0
    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')}))