Exemple #1
0
    def test_sorting_mixed(self):
        translation.activate('de')
        q = TranslatedModel.objects.all()
        expected = [1, 4, 3]

        eq_(ids(order_by_translation(q, 'name')), expected)
        eq_(ids(order_by_translation(q, '-name')), list(reversed(expected)))
    def test_sorting_mixed(self):
        translation.activate('de')
        q = TranslatedModel.objects.all()
        expected = [1, 4, 3]

        eq_(ids(order_by_translation(q, 'name')), expected)
        eq_(ids(order_by_translation(q, '-name')), list(reversed(expected)))
    def test_sorting_by_field(self):
        field = TranslatedModel._meta.get_field('default_locale')
        TranslatedModel.get_fallback = classmethod(lambda cls: field)

        translation.activate('de')
        q = TranslatedModel.objects.all()
        expected = [3, 1, 4]

        eq_(ids(order_by_translation(q, 'name')), expected)
        eq_(ids(order_by_translation(q, '-name')), list(reversed(expected)))

        del TranslatedModel.get_fallback
Exemple #4
0
    def test_sorting_by_field(self):
        field = TranslatedModel._meta.get_field('default_locale')
        TranslatedModel.get_fallback = classmethod(lambda cls: field)

        translation.activate('de')
        q = TranslatedModel.objects.all()
        expected = [3, 1, 4]

        eq_(ids(order_by_translation(q, 'name')), expected)
        eq_(ids(order_by_translation(q, '-name')), list(reversed(expected)))

        del TranslatedModel.get_fallback
Exemple #5
0
def sidebar(app):
    """Populates the sidebar with (categories, types)."""
    from addons.models import Category
    if app is None:
        return [], []

    # We muck with query to make order_by and extra_order_by play nice.
    q = Category.objects.filter(application=app.id,
                                weight__gte=0,
                                type=amo.ADDON_EXTENSION)
    categories = order_by_translation(q, 'name')
    categories.query.extra_order_by.insert(0, 'weight')

    Type = collections.namedtuple('Type', 'id name url')
    base = urlresolvers.reverse('home')
    types = [Type(99, _('Collections'), base + 'collections/')]

    shown_types = {
        amo.ADDON_PERSONA: urlresolvers.reverse('browse.personas'),
        amo.ADDON_DICT: urlresolvers.reverse('browse.language-tools'),
        amo.ADDON_SEARCH: urlresolvers.reverse('browse.search-tools'),
        amo.ADDON_THEME: urlresolvers.reverse('browse.themes'),
    }
    titles = dict(amo.ADDON_TYPES,
                  **{amo.ADDON_DICT: _('Dictionaries & Language Packs')})
    for type_, url in shown_types.items():
        if type_ in app.types:
            types.append(Type(type_, titles[type_], url))

    return categories, sorted(types, key=lambda x: x.name)
Exemple #6
0
def themes(request, user, category=None):
    cats = Category.objects.filter(type=amo.ADDON_PERSONA)

    ctx = {
        'profile': user,
        'categories': order_by_translation(cats, 'name'),
        'search_cat': 'themes'
    }

    if user.is_artist:
        base = user.addons.reviewed().filter(type=amo.ADDON_PERSONA,
                                             addonuser__user=user,
                                             addonuser__listed=True)

        if category:
            qs = cats.filter(slug=category)
            ctx['category'] = cat = get_list_or_404(qs)[0]
            base = base.filter(categories__id=cat.id)

    else:
        base = Addon.objects.none()

    filter_ = PersonasFilter(request, base, key='sort', default='popular')
    addons = amo.utils.paginate(request, filter_.qs, 30, count=base.count())

    ctx.update({
        'addons': addons,
        'filter': filter_,
        'sorting': filter_.field,
        'sort_opts': filter_.opts
    })

    return render(request, 'browse/personas/grid.html', ctx)
Exemple #7
0
def _personas(request):
    "Handle the request for persona searches."
    form = SecondarySearchForm(request.GET)
    form.is_valid()

    query = form.cleaned_data.get('q', '')

    search_opts = {}
    search_opts['limit'] = form.cleaned_data.get('pp', DEFAULT_NUM_RESULTS)
    page = form.cleaned_data.get('page') or 1
    search_opts['offset'] = (page - 1) * search_opts['limit']

    client = PersonasClient()

    q = Category.objects.filter(application=request.APP.id,
                                type=amo.ADDON_PERSONA)
    categories = order_by_translation(q, 'name')

    try:
        results = client.query(query, **search_opts)
    except SearchError:
        return jingo.render(request, 'search/down.html', {}, status=503)

    pager = amo.utils.paginate(request, results, search_opts['limit'])

    c = {
            'pager': pager,
            'form': form,
            'categories': categories,
        }

    return jingo.render(request, 'search/personas.html', c)
Exemple #8
0
def developers(request, addon, page):
    if 'version' in request.GET:
        qs = addon.versions.filter(files__status__in=amo.VALID_STATUSES)
        version = get_list_or_404(qs, version=request.GET['version'])[0]
    else:
        version = addon.current_version

    if 'src' in request.GET:
        contribution_src = src = request.GET['src']
    else:
        # Download src and contribution_src are be different.
        src = {'developers': 'developers',
               'installed': 'meet-the-developer-post-install',
               'roadblock': 'meetthedeveloper_roadblock'}.get(page, None)
        contribution_src = {'developers': 'meet-developers',
                            'installed': 'post-download',
                            'roadblock': 'roadblock'}.get(page, None)

    if addon.is_persona():
        raise http.Http404()
    author_addons = order_by_translation(addon.authors_other_addons, 'name')
    return jingo.render(request, 'addons/developers.html',
                        {'addon': addon, 'author_addons': author_addons,
                         'page': page, 'src': src,
                         'contribution_src': contribution_src,
                         'version': version})
Exemple #9
0
def search_tools(request, category=None):
    """View the search tools page."""
    APP, TYPE = request.APP, amo.ADDON_SEARCH
    qs = Category.objects.filter(application=APP.id, type=TYPE)
    categories = order_by_translation(qs, 'name')

    addons, filter = addon_listing(request, [TYPE], SearchToolsFilter,
                                   'popular')

    if category:
        category = get_object_or_404(qs, slug=category)
        addons = addons.filter(categories__id=category.id)

    addons = amo.utils.paginate(request, addons)

    base = (Addon.objects.listed(
        request.APP, amo.STATUS_PUBLIC).filter(type=amo.ADDON_EXTENSION))
    sidebar_ext = SearchExtensionsFilter(request, base, 'sort', 'popular')

    return render(
        request, 'browse/search_tools.html', {
            'categories': categories,
            'category': category,
            'addons': addons,
            'filter': filter,
            'search_extensions_filter': sidebar_ext
        })
Exemple #10
0
def search_tools(request, category=None):
    APP, TYPE = request.APP, amo.ADDON_SEARCH
    qs = Category.objects.filter(application=APP.id, type=TYPE)
    categories = order_by_translation(qs, 'name')

    # Feature page should list both extensions and search Add-ons
    # but other pages should only list search Add-ons

    types = [TYPE]
    default = 'featured'
    if request.GET.get('sort', default) == 'featured':
        types.append(amo.ADDON_EXTENSION)

    addons, filter, unreviewed = addon_listing(
        request, types, SearchToolsFilter, default)

    if category is not None:
        category = get_object_or_404(qs, slug=category)
        addons = addons.filter(categories__id=category.id)

    addons = amo.utils.paginate(request, addons)

    base = (Addon.objects.listed(request.APP, amo.STATUS_PUBLIC)
                         .filter(type=amo.ADDON_EXTENSION))
    search_extensions = SearchExtensionsFilter(
                            request, base, 'sort', 'popular')

    return jingo.render(request, 'browse/search_tools.html',
                        {'categories': categories, 'category': category,
                         'addons': addons, 'filter': filter,
                         'search_extensions_filter': search_extensions,
                         'unreviewed': unreviewed})
Exemple #11
0
def themes(request, user, category=None):
    cats = Category.objects.filter(type=amo.ADDON_PERSONA)

    ctx = {
        'profile': user,
        'categories': order_by_translation(cats, 'name'),
        'search_cat': 'themes'
    }

    if user.is_artist:
        base = user.addons.reviewed().filter(type=amo.ADDON_PERSONA,
            addonuser__user=user, addonuser__listed=True)

        if category:
            qs = cats.filter(slug=category)
            ctx['category'] = cat = get_list_or_404(qs)[0]
            base = base.filter(categories__id=cat.id)

    else:
        base = Addon.objects.none()

    filter_ = PersonasFilter(request, base, key='sort',
                             default='popular')
    addons = amo.utils.paginate(request, filter_.qs, 30,
                                count=base.count())

    ctx.update({
        'addons': addons,
        'filter': filter_,
        'sorting': filter_.field,
        'sort_opts': filter_.opts
    })

    return jingo.render(request, 'browse/personas/grid.html', ctx)
Exemple #12
0
def themes(request, category=None):
    q = Category.objects.filter(application=request.APP.id,
                                type=amo.ADDON_THEME)
    categories = order_by_translation(q, 'name')

    addons, filter, unreviewed = _listing(request, amo.ADDON_THEME)

    if category is not None:
        try:
            category = dict((c.slug, c) for c in categories)[category]
        except KeyError:
            raise http.Http404()
        addons = addons.filter(categories__id=category.id)

    count = addons.with_index(addons='type_status_inactive_idx').count()
    themes = amo.utils.paginate(request, addons, count=count)

    # Pre-selected category for search form
    search_cat = '%s,0' % amo.ADDON_THEME

    return jingo.render(request, 'browse/themes.html',
                        {'categories': categories,
                         'themes': themes, 'category': category,
                         'sorting': filter.field,
                         'sort_opts': filter.opts,
                         'unreviewed': unreviewed,
                         'search_cat': search_cat})
Exemple #13
0
def themes(request, category=None):
    q = Category.objects.filter(application=request.APP.id,
                                type=amo.ADDON_THEME)
    categories = order_by_translation(q, 'name')

    addons, filter, unreviewed = _listing(request, amo.ADDON_THEME)
    total_count = addons.count()

    if category is None:
        selected = _Category(_('All'), total_count, '')
    else:
        selected = dict((c.slug, c) for c in categories)[category]
        addons = addons.filter(categories__slug=category)

    themes = amo.utils.paginate(request, addons)

    # Pre-selected category for search form
    search_cat = '%s,0' % amo.ADDON_THEME

    return jingo.render(request, 'browse/themes.html',
                        {'categories': categories, 'total_count': total_count,
                         'themes': themes, 'selected': selected,
                         'sorting': filter.sorting,
                         'sort_opts': filter.opts,
                         'unreviewed': unreviewed,
                         'search_cat': search_cat})
Exemple #14
0
 def filter(self, field):
     if field == "added":
         return self.base_queryset.order_by("collectionaddon__created")
     elif field == "name":
         return order_by_translation(self.base_queryset, "name")
     elif field == "popular":
         return self.base_queryset.order_by("-weekly_downloads").with_index(addons="downloads_type_idx")
Exemple #15
0
def _categories(rand=False, limit=None):
    categories = Category.objects.filter(type=amo.ADDON_WEBAPP, weight__gte=0)

    # If the user has a carrier, show any categories that are either for their
    # carrier or that don't have a carrier. Otherwise, only show apps without
    # a carrier.
    carrier = mkt.carriers.get_carrier_id()
    if carrier:
        categories = categories.extra(where=[
            '(`categories`.`carrier` = %s OR '
            '`categories`.`carrier` IS NULL)'
        ],
                                      params=[carrier])
    else:
        categories = categories.filter(carrier__isnull=True)

    # Show any categories that are either for the user's region or that don't
    # have a region. Exclude categories not for the user's region.
    categories = categories.extra(where=[
        '(`categories`.`region` = %s OR '
        '`categories`.`region` IS NULL)'
    ],
                                  params=[mkt.regions.get_region_id()])

    if rand:
        categories = categories.order_by('-weight', '?')
    else:
        categories = categories.order_by('-weight')
        categories = order_by_translation(categories, 'name')

    if limit:
        categories = categories[:limit]

    return categories
Exemple #16
0
 def my_addons(self, n=8, with_unlisted=False):
     """Returns n addons"""
     addons = self.addons
     if with_unlisted:
         addons = self.addons.model.with_unlisted.filter(authors=self)
     qs = order_by_translation(addons, 'name')
     return qs[:n]
Exemple #17
0
def sidebar(app):
    """Populates the sidebar with (categories, types)."""
    from addons.models import Category
    if app is None:
        return [], []

    # We muck with query to make order_by and extra_order_by play nice.
    q = Category.objects.filter(application=app.id, weight__gte=0,
                                type=amo.ADDON_EXTENSION)
    categories = order_by_translation(q, 'name')
    categories.query.extra_order_by.insert(0, 'weight')

    Type = collections.namedtuple('Type', 'id name url')
    base = urlresolvers.reverse('home')
    types = [Type(99, _('Collections'), base + 'collections/')]

    shown_types = {
        amo.ADDON_PERSONA: urlresolvers.reverse('browse.personas'),
        amo.ADDON_DICT: urlresolvers.reverse('browse.language-tools'),
        amo.ADDON_SEARCH: urlresolvers.reverse('browse.search-tools'),
        amo.ADDON_THEME: urlresolvers.reverse('browse.themes'),
    }
    titles = dict(amo.ADDON_TYPES,
                  **{amo.ADDON_DICT: _('Dictionaries & Language Packs')})
    for type_, url in shown_types.items():
        if type_ in app.types:
            types.append(Type(type_, titles[type_], url))

    return categories, sorted(types, key=lambda x: x.name)
Exemple #18
0
def personas(request, category=None):
    TYPE = amo.ADDON_PERSONA
    q = Category.objects.filter(application=request.APP.id,
                                type=TYPE)
    categories = order_by_translation(q, 'name')

    base = Addon.objects.valid().filter(type=TYPE)
    featured = base & Addon.objects.featured(request.APP)
    is_homepage = category is None and 'sort' not in request.GET

    if category is not None:
        category = get_object_or_404(q, slug=category)
        base = base.filter(categories__id=category.id)

    filter = PersonasFilter(request, base, key='sort', default='up-and-coming')

    if 'sort' in request.GET:
        template = 'grid.html'
    else:
        template = 'category_landing.html'

    # Pass the count from base instead of letting it come from
    # filter.qs.count() since that would join against personas.
    addons = amo.utils.paginate(request, filter.qs, 30, count=base.count())

    search_cat = '%s,%s' % (TYPE, category.id if category else 0)

    return jingo.render(request, 'browse/personas/' + template,
                        {'categories': categories, 'category': category,
                         'filter': filter, 'addons': addons,
                         'featured': featured, 'is_homepage': is_homepage,
                         'search_cat': search_cat})
Exemple #19
0
def themes(request, category=None):
    q = Category.objects.filter(application=request.APP.id, type=amo.ADDON_THEME)
    categories = order_by_translation(q, "name")

    addons, filter, unreviewed = _listing(request, amo.ADDON_THEME)
    total_count = addons.count()

    if category is None:
        selected = _Category(_("All"), total_count, "")
    else:
        selected = dict((c.slug, c) for c in categories)[category]
        addons = addons.filter(categories__slug=category)

    themes = amo.utils.paginate(request, addons)

    # Pre-selected category for search form
    search_cat = "%s,0" % amo.ADDON_THEME

    return jingo.render(
        request,
        "browse/themes.html",
        {
            "categories": categories,
            "total_count": total_count,
            "themes": themes,
            "selected": selected,
            "sorting": filter.sorting,
            "sort_opts": filter.opts,
            "unreviewed": unreviewed,
            "search_cat": search_cat,
        },
    )
Exemple #20
0
def developers(request, addon, page):
    if 'version' in request.GET:
        qs = addon.versions.filter(files__status__in=amo.VALID_STATUSES)
        version = get_list_or_404(qs, version=request.GET['version'])[0]
    else:
        version = addon.current_version

    if 'src' in request.GET:
        src = request.GET['src']
    else:
        src = {
            'developers': 'meet-developers',
            'installed': 'post-download',
            'roadblock': 'roadblock'
        }.get(page, None)

    if addon.is_persona():
        raise http.Http404()
    author_addons = order_by_translation(addon.authors_other_addons, 'name')
    return jingo.render(
        request, 'addons/developers.html', {
            'addon': addon,
            'author_addons': author_addons,
            'page': page,
            'src': src,
            'version': version
        })
Exemple #21
0
def _do_sort_queue_obj(request, qs, date_sort):
    """
    Column sorting logic based on request GET parameters.
    Deals with objects with joins on the Addon (e.g. RereviewQueue, Version).
    Returns qs of apps.
    """
    sort_type, order = clean_sort_param(request, date_sort=date_sort)
    sort_str = sort_type

    if sort_type not in [date_sort, 'name']:
        sort_str = 'addon__' + sort_type

    # sort_str includes possible joins when ordering.
    # sort_type is the name of the field to sort on without desc/asc markers.
    # order_by is the name of the field to sort on with desc/asc markers.
    order_by = ('-' if order == 'desc' else '') + sort_str

    # Sort.
    if sort_type == 'name':
        # Sorting by name translation through an addon foreign key.
        return order_by_translation(
            Webapp.objects.filter(id__in=qs.values_list('addon', flat=True)),
            order_by)

    elif sort_type == 'num_abuse_reports':
        qs = qs.annotate(num_abuse_reports=Count('abuse_reports'))

    # Convert sorted queue object queryset to sorted app queryset.
    sorted_app_ids = qs.order_by(order_by).values_list('addon', flat=True)
    qs = Webapp.objects.filter(id__in=sorted_app_ids)
    return manual_order(qs, sorted_app_ids, 'addons.id')
Exemple #22
0
def _categories(rand=False, limit=None):
    categories = Category.objects.filter(
        type=amo.ADDON_WEBAPP, weight__gte=0)

    # If the user has a carrier, show any categories that are either for their
    # carrier or that don't have a carrier. Otherwise, only show apps without
    # a carrier.
    carrier = mkt.carriers.get_carrier_id()
    if carrier:
        categories = categories.extra(
            where=['carrier = %s OR carrier IS NULL'], params=[carrier])
    else:
        categories = categories.filter(carrier__isnull=True)

    # Show any categories that are either for the user's region or that don't
    # have a region. Exclude categories not for the user's region.
    categories = categories.extra(
        where=['(`categories`.`region` = %s OR '
               '`categories`.`region` IS NULL)'],
        params=[mkt.regions.get_region_id()])

    if rand:
        categories = categories.order_by('-weight', '?')
    else:
        categories = categories.order_by('-weight')
        categories = order_by_translation(categories, 'name')

    if limit:
        categories = categories[:limit]

    return categories
Exemple #23
0
def personas(request, category=None):
    TYPE = amo.ADDON_PERSONA
    q = Category.objects.filter(application=request.APP.id, type=TYPE)
    categories = order_by_translation(q, "name")

    base = Addon.objects.valid().filter(type=TYPE)

    if category is not None:
        category = get_object_or_404(q, slug=category)
        base = base.filter(categories__id=category.id)

    filter = PersonasFilter(request, base, key="sort", default="up-and-coming")

    if "sort" in request.GET:
        template = "grid.html"
    else:
        template = "category_landing.html"

    addons = amo.utils.paginate(request, filter.qs, 30)

    search_cat = "%s,%s" % (TYPE, category.id if category else 0)

    return jingo.render(
        request,
        "browse/personas/" + template,
        {"categories": categories, "category": category, "filter": filter, "addons": addons, "search_cat": search_cat},
    )
Exemple #24
0
def personas_listing(request, category_slug=None):
    # Common pieces using by browse and search.
    TYPE = amo.ADDON_PERSONA
    q = Category.objects.filter(type=TYPE)
    categories = order_by_translation(q, 'name')

    frozen = list(FrozenAddon.objects.values_list('addon', flat=True))

    base = (Addon.objects.public().filter(type=TYPE)
                 .exclude(id__in=frozen)
                 .extra(select={'_app': request.APP.id}))

    cat = None
    if category_slug is not None:
        try:
            cat = Category.objects.filter(slug=category_slug, type=TYPE)[0]
        except IndexError:
            # Maybe it's a Complete Theme?
            try:
                cat = Category.objects.filter(slug=category_slug,
                                              type=amo.ADDON_THEME)[0]
            except IndexError:
                raise Http404
            else:
                # Hey, it was a Complete Theme.
                url = reverse('browse.themes', args=[cat.slug])
                if 'sort' in request.GET:
                    url = amo.utils.urlparams(url, sort=request.GET['sort'])
                return redirect(url, permanent=not settings.DEBUG)

        base = base.filter(categories__id=cat.id)

    filter_ = PersonasFilter(request, base, key='sort',
                             default='up-and-coming')
    return categories, filter_, base, cat
Exemple #25
0
def themes(request, category=None):
    APP, THEME = request.APP, amo.ADDON_THEME
    status = [amo.STATUS_PUBLIC]

    experimental = 'on' if request.GET.get('experimental', False) else None
    if experimental:
        status.append(amo.STATUS_SANDBOX)

    q = Category.objects.filter(application=APP.id, type=THEME)
    categories = order_by_translation(q, 'name')

    addons = Addon.objects.listed(APP, *status).filter(type=THEME).distinct()
    total_count = addons.count()

    sorting, sort_opts, addons = AddonSorter(request, addons, 'downloads')

    if category is None:
        selected = _Category(_('All'), total_count, '')
    else:
        selected = dict((c.slug, c) for c in categories)[category]
        addons = addons.filter(categories__slug=category)

    themes = amo.utils.paginate(request, addons)

    return jingo.render(request, 'browse/themes.html',
                        {'categories': categories, 'total_count': total_count,
                         'themes': themes, 'selected': selected,
                         'sorting': sorting, 'sort_opts': sort_opts,
                         'experimental': experimental})
Exemple #26
0
def personas_listing(request, category_slug=None):
    # Common pieces using by browse and search.
    TYPE = amo.ADDON_PERSONA
    q = Category.objects.filter(type=TYPE)
    categories = order_by_translation(q, 'name')

    frozen = list(FrozenAddon.objects.values_list('addon', flat=True))

    base = (Addon.objects.public().filter(type=TYPE).exclude(
        id__in=frozen).extra(select={'_app': request.APP.id}))

    cat = None
    if category_slug is not None:
        try:
            cat = Category.objects.filter(slug=category_slug, type=TYPE)[0]
        except IndexError:
            # Maybe it's a Complete Theme?
            try:
                cat = Category.objects.filter(slug=category_slug,
                                              type=amo.ADDON_THEME)[0]
            except IndexError:
                raise Http404
            else:
                # Hey, it was a Complete Theme.
                url = reverse('browse.themes', args=[cat.slug])
                if 'sort' in request.GET:
                    url = amo.utils.urlparams(url, sort=request.GET['sort'])
                return redirect(url, permanent=not settings.DEBUG)

        base = base.filter(categories__id=cat.id)

    filter = PersonasFilter(request, base, key='sort', default='up-and-coming')
    return categories, filter, base, cat
Exemple #27
0
def _do_sort_queue_obj(request, qs, date_sort):
    """
    Column sorting logic based on request GET parameters.
    Deals with objects with joins on the Addon (e.g. RereviewQueue, Version).
    Returns qs of apps.
    """
    sort_type, order = clean_sort_param(request, date_sort=date_sort)
    sort_str = sort_type

    if sort_type not in [date_sort, 'name']:
        sort_str = 'addon__' + sort_type

    # sort_str includes possible joins when ordering.
    # sort_type is the name of the field to sort on without desc/asc markers.
    # order_by is the name of the field to sort on with desc/asc markers.
    order_by = ('-' if order == 'desc' else '') + sort_str

    # Sort.
    if sort_type == 'name':
        # Sorting by name translation through an addon foreign key.
        return order_by_translation(
            Webapp.objects.filter(id__in=qs.values_list('addon', flat=True)),
            order_by)

    elif sort_type == 'num_abuse_reports':
        qs = qs.annotate(num_abuse_reports=Count('abuse_reports'))

    # Convert sorted queue object queryset to sorted app queryset.
    sorted_app_ids = qs.order_by(order_by).values_list('addon', flat=True)
    qs = Webapp.objects.filter(id__in=sorted_app_ids)
    return manual_order(qs, sorted_app_ids, 'addons.id')
Exemple #28
0
def sidebar(app):
    """Populates the sidebar with (categories, types)."""
    if app is None:
        return [], []

    # We muck with query to make order_by and extra_order_by play nice.
    q = Category.objects.filter(application=app.id, weight__gte=0,
                                type=amo.ADDON_EXTENSION)
    categories = order_by_translation(q, 'name')
    categories.query.extra_order_by.insert(0, 'weight')

    # TODO(jbalogh): real reverse
    Type = collections.namedtuple('Type', 'name url')
    base = urlresolvers.reverse('home')
    types = [Type(_('Collections'), base + 'collections/')]
    shown_types = {
        amo.ADDON_PERSONA: base + 'personas/',
        amo.ADDON_DICT: urlresolvers.reverse('browse.language_tools'),
        amo.ADDON_SEARCH: base + 'browse/type:4',
        amo.ADDON_PLUGIN: base + 'browse/type:7',
        amo.ADDON_THEME: urlresolvers.reverse('browse.themes'),
    }
    for type_, url in shown_types.items():
        if type_ in app.types:
            name = amo.ADDON_TYPES[type_]
            types.append(Type(name, url))

    return categories, sorted(types, key=lambda x: x.name)
Exemple #29
0
def developers(request, addon_id, page):
    addon = get_object_or_404(Addon.objects.valid(), id=addon_id)
    if addon.is_persona():
        raise http.Http404()
    author_addons = order_by_translation(addon.authors_other_addons, 'name')
    return jingo.render(request, 'addons/developers.html',
                        {'addon': addon, 'author_addons': author_addons,
                         'page': page})
Exemple #30
0
 def filter(self, field):
     if field == 'added':
         return self.base_queryset.order_by('collectionaddon__created')
     elif field == 'name':
         return order_by_translation(self.base_queryset, 'name')
     elif field == 'popular':
         return (self.base_queryset.order_by('-weekly_downloads')
                 .with_index(addons='downloads_type_idx'))
Exemple #31
0
 def app_categories(self):
     categories = sorted_groupby(order_by_translation(self.categories.all(),
                                                      'name'),
                                 key=lambda x: x.application_id)
     app_cats = []
     for app, cats in categories:
         app_cats.append((amo.APP_IDS[app], list(cats)))
     return app_cats
Exemple #32
0
 def filter(self, field):
     if field == 'added':
         return self.base_queryset.order_by('collectionaddon__created')
     elif field == 'name':
         return order_by_translation(self.base_queryset, 'name')
     elif field == 'popular':
         return (self.base_queryset.order_by('-weekly_downloads')
                 .with_index(addons='downloads_type_idx'))
Exemple #33
0
def extension_detail(request, addon):
    """Extensions details page."""

    # if current version is incompatible with this app, redirect
    comp_apps = addon.compatible_apps
    if comp_apps and request.APP not in comp_apps:
        prefixer = urlresolvers.get_url_prefix()
        prefixer.app = comp_apps.keys()[0].short
        return http.HttpResponsePermanentRedirect(reverse(
            'addons.detail', args=[addon.id]))

    # source tracking
    src = request.GET.get('src', 'addondetail')

    # get satisfaction only supports en-US
    lang = translation.to_locale(translation.get_language())
    addon.has_satisfaction = (lang == 'en_US' and
                              addon.get_satisfaction_company)

    # other add-ons from the same author(s)
    author_addons = order_by_translation(addon.authors_other_addons, 'name')

    # tags
    dev_tags, user_tags = addon.tags_partitioned_by_developer

    current_user_tags = []

    if request.user.is_authenticated():
        current_user_tags = user_tags.filter(
                addon_tags__user=request.amo_user)

    # addon recommendations
    recommended = Addon.objects.valid().only_translations().filter(
        recommended_for__addon=addon)[:5]

    # popular collections this addon is part of
    collections = Collection.objects.listed().filter(
        addons=addon, application__id=request.APP.id)

    data = {
        'addon': addon,
        'author_addons': author_addons,

        'src': src,

        'dev_tags': dev_tags,
        'user_tags': user_tags,
        'current_user_tags': current_user_tags,

        'recommendations': recommended,
        'review_form': ReviewForm(),
        'reviews': Review.objects.latest().filter(addon=addon),
        'get_replies': Review.get_replies,

        'collections': collections.order_by('-subscribers')[:3],
    }
    return jingo.render(request, 'addons/details.html', data)
Exemple #34
0
def _categories():
    public_cats = (AddonCategory.objects
                   .filter(addon__status=amo.STATUS_PUBLIC)
                   .values_list('category', flat=True).distinct())
    categories = Category.objects.filter(type=amo.ADDON_WEBAPP, weight__gte=0,
                                         id__in=public_cats)
    categories = order_by_translation(categories, 'name')
    t = env.get_template('browse/helpers/category_slider.html')
    return jinja2.Markup(t.render(categories=categories))
Exemple #35
0
 def sort(self, qs, field):
     if field == 'date':
         return qs.order_by('-last_updated')
     elif field == 'downloads':
         return qs.order_by('-weekly_downloads')
     elif field == 'rating':
         return qs.order_by('-bayesian_rating')
     else:
         return order_by_translation(qs, 'name')
Exemple #36
0
 def filter(self, field):
     qs = self.base_queryset
     if field == 'purchased':
         return (qs.filter(Q(addonpurchase__user=self.request.amo_user) |
                           Q(addonpurchase__isnull=True))
                 .order_by('-addonpurchase__created', 'id'))
     elif field == 'price':
         return qs.order_by('addonpremium__price__price', 'id')
     elif field == 'name':
         return order_by_translation(qs, 'name')
Exemple #37
0
 def filter(self, field):
     qs = self.base_queryset
     if field == "purchased":
         return qs.filter(Q(addonpurchase__user=self.request.amo_user) | Q(addonpurchase__isnull=True)).order_by(
             "-addonpurchase__created", "id"
         )
     elif field == "price":
         return qs.order_by("addonpremium__price__price", "id")
     elif field == "name":
         return order_by_translation(qs, "name")
Exemple #38
0
 def filter(self, field):
     qs = self.base_queryset
     if field == 'purchased':
         return (qs.filter(Q(addonpurchase__user=self.request.amo_user) |
                           Q(addonpurchase__isnull=True))
                 .order_by('-addonpurchase__created', 'id'))
     elif field == 'price':
         return qs.order_by('addonpremium__price__price', 'id')
     elif field == 'name':
         return order_by_translation(qs, 'name')
Exemple #39
0
def _categories_themes():
    public_cats = (
        AddonCategory.objects.filter(addon__status=amo.STATUS_PUBLIC, category__type=amo.ADDON_PERSONA)
        .values_list("category", flat=True)
        .distinct()
    )
    categories = Category.objects.filter(type=amo.ADDON_PERSONA, weight__gte=0, id__in=public_cats)
    categories = order_by_translation(categories, "name")

    t = env.get_template("browse/helpers/category_slider.html")
    return jinja2.Markup(t.render(categories=categories))
Exemple #40
0
 def sort(self, qs, field):
     if field == "updated":
         return qs.order_by("-last_updated")
     if field == "created":
         return qs.order_by("-created")
     elif field == "downloads":
         return qs.order_by("-weekly_downloads")
     elif field == "rating":
         return qs.order_by("-bayesian_rating")
     else:
         return order_by_translation(qs, "name")
Exemple #41
0
 def filter(self, field):
     qs = self.base_queryset
     if field == 'purchased':
         # Id's are in created order, so let's invert them for this query.
         # According to my testing we don't actually need to dedupe this.
         ids = list(reversed(self.ids[0])) + self.ids[1]
         return manual_order(qs.filter(id__in=ids), ids)
     elif field == 'price':
         return (qs.filter(id__in=self.uids)
                   .order_by('addonpremium__price__price', 'id'))
     elif field == 'name':
         return order_by_translation(qs.filter(id__in=self.uids), 'name')
Exemple #42
0
 def filter(self, field):
     qs = self.base_queryset
     if field == 'purchased':
         # Id's are in created order, so let's invert them for this query.
         # According to my testing we don't actually need to dedupe this.
         ids = list(reversed(self.ids[0])) + self.ids[1]
         return manual_order(qs.filter(id__in=ids), ids)
     elif field == 'price':
         return (qs.filter(id__in=self.uids).order_by(
             'addonpremium__price__price', 'id'))
     elif field == 'name':
         return order_by_translation(qs.filter(id__in=self.uids), 'name')
Exemple #43
0
 def filter(self, field):
     qs = self.base_queryset
     if field == 'featured':
         return qs.filter(type=amo.COLLECTION_FEATURED)
     elif field == 'followers':
         return qs.order_by('-subscribers')
     elif field == 'popular':
         return qs.order_by('-weekly_subscribers')
     elif field == 'updated':
         return qs.order_by('-modified')
     elif field == 'created':
         return qs.order_by('-created')
     elif field == 'name':
         return order_by_translation(qs, 'name')
Exemple #44
0
def impala_extension_detail(request, addon):
    """Extensions details page."""

    # if current version is incompatible with this app, redirect
    comp_apps = addon.compatible_apps
    if comp_apps and request.APP not in comp_apps:
        prefixer = urlresolvers.get_url_prefix()
        prefixer.app = comp_apps.keys()[0].short
        return http.HttpResponsePermanentRedirect(
            reverse('addons.detail', args=[addon.slug]))

    # source tracking
    src = request.GET.get('src', 'addon-detail')

    # get satisfaction only supports en-US
    lang = translation.to_locale(translation.get_language())
    addon.has_satisfaction = (lang == 'en_US'
                              and addon.get_satisfaction_company)

    # other add-ons from the same author(s)
    author_addons = order_by_translation(addon.authors_other_addons,
                                         'name')[:6]

    # tags
    tags = addon.tags.not_blacklisted()

    # addon recommendations
    recommended = MiniAddon.objects.valid().filter(
        recommended_for__addon=addon)[:5]

    # popular collections this addon is part of
    collections = Collection.objects.listed().filter(
        addons=addon, application__id=request.APP.id)

    data = {
        'addon': addon,
        'author_addons': author_addons,
        'src': src,
        'tags': tags,
        'grouped_ratings': GroupedRating.get(addon.id),
        'recommendations': recommended,
        'review_form': ReviewForm(),
        'reviews': Review.objects.latest().filter(addon=addon),
        'get_replies': Review.get_replies,
        'collections': collections.order_by('-subscribers')[:3],
    }
    if settings.REPORT_ABUSE:
        data['abuse_form'] = AbuseForm(request=request)

    return jingo.render(request, 'addons/impala/details.html', data)
Exemple #45
0
def personas_listing(request, category=None):
    # Common pieces using by browse and search.
    TYPE = amo.ADDON_PERSONA
    q = Category.objects.filter(application=request.APP.id, type=TYPE)
    categories = order_by_translation(q, 'name')

    base = (Addon.objects.public().filter(type=TYPE).extra(
        select={'_app': request.APP.id}))

    if category is not None:
        category = get_object_or_404(q, slug=category)
        base = base.filter(categories__id=category.id)

    filter = PersonasFilter(request, base, key='sort', default='up-and-coming')
    return categories, filter, base, category
Exemple #46
0
def search_tools(request, category=None):
    """View the search tools page.

    The default landing page will show you both featured
    extensions and featured search Add-ons.  However, any
    other type of sorting on this page will not show extensions.

    Since it's uncommon for a category to have
    featured add-ons the default view for a category will land you
    on popular add-ons instead.  Note also that CSS will hide the
    sort-by-featured link.
    """
    APP, TYPE = request.APP, amo.ADDON_SEARCH
    qs = Category.objects.filter(application=APP.id, type=TYPE)
    categories = order_by_translation(qs, 'name')

    types = [TYPE]
    if category:
        # Category pages do not have features.
        # Sort by popular add-ons instead.
        default = 'popular'
    else:
        default = 'featured'
        # When the non-category page is featured, include extensions.
        if request.GET.get('sort', default) == 'featured':
            types.append(amo.ADDON_EXTENSION)

    addons, filter = addon_listing(request, types, SearchToolsFilter, default)

    if category:
        category = get_object_or_404(qs, slug=category)
        addons = addons.filter(categories__id=category.id)

    addons = amo.utils.paginate(request, addons)

    base = (Addon.objects.listed(
        request.APP, amo.STATUS_PUBLIC).filter(type=amo.ADDON_EXTENSION))
    sidebar_ext = SearchExtensionsFilter(request, base, 'sort', 'popular')

    return render(
        request, 'browse/search_tools.html', {
            'categories': categories,
            'category': category,
            'addons': addons,
            'filter': filter,
            'search_extensions_filter': sidebar_ext
        })
Exemple #47
0
def _do_sort_webapp(request, qs, date_sort):
    """
    Column sorting logic based on request GET parameters.
    """
    sort_type, order = clean_sort_param(request, date_sort=date_sort)
    order_by = ('-' if order == 'desc' else '') + sort_type

    # Sort.
    if sort_type == 'name':
        # Sorting by name translation.
        return order_by_translation(qs, order_by)

    elif sort_type == 'num_abuse_reports':
        return (qs.annotate(
            num_abuse_reports=Count('abuse_reports')).order_by(order_by))

    else:
        return qs.order_by(order_by)
Exemple #48
0
def _categories(rand=False, limit=None):
    public_cats = (AddonCategory.objects.filter(
        addon__status=amo.STATUS_PUBLIC).values_list('category',
                                                     flat=True).distinct())
    categories = (Category.objects.filter(
        type=amo.ADDON_WEBAPP, weight__gte=0,
        id__in=public_cats).order_by('-weight'))

    if rand:
        categories = categories.order_by('-weight', '?')

    categories = order_by_translation(categories, 'name')

    if limit:
        categories = categories[:limit]

    t = env.get_template('browse/helpers/category_slider.html')
    return jinja2.Markup(t.render(categories=categories))
Exemple #49
0
def sidebar(app):
    """Populates the sidebar with (categories, types)."""
    from addons.models import Category
    if app is None:
        return [], []

    # We muck with query to make order_by and extra_order_by play nice.
    q = Category.objects.filter(application=app.id,
                                weight__gte=0,
                                type=amo.ADDON_EXTENSION)
    categories = order_by_translation(q, 'name')
    categories.query.extra_order_by.insert(0, 'weight')

    Type = collections.namedtuple('Type', 'id name url')
    base = urlresolvers.reverse('home')
    types = [Type(99, _('Collections'), base + 'collections/')]

    return categories, sorted(types, key=lambda x: x.name)
Exemple #50
0
    def test_other_addons(self):
        """Test "other add-ons by author" list."""

        # Grab a user and give them some add-ons.
        u = UserProfile.objects.get(pk=55021)
        thisaddon = u.addons.all()[0]
        qs = Addon.objects.valid().exclude(pk=thisaddon.pk)
        other_addons = order_by_translation(qs, 'name')[:3]
        for addon in other_addons:
            AddonUser.objects.create(user=u, addon=addon)

        page = self.client.get(reverse('addons.detail', args=[thisaddon.slug]),
                               follow=True)
        doc = pq(page.content)
        eq_(doc('.other-author-addons li').length, other_addons.count())
        for i in range(other_addons.count()):
            link = doc('.other-author-addons li a').eq(i)
            eq_(link.attr('href'), other_addons[i].get_url_path())
Exemple #51
0
def personas_listing(request, category_slug=None):
    # Common pieces using by browse and search.
    TYPE = amo.ADDON_PERSONA
    q = Category.objects.filter(application=request.APP.id,
                                type=TYPE)
    categories = order_by_translation(q, 'name')

    frozen = list(FrozenAddon.objects.values_list('addon', flat=True))

    base = (Addon.objects.public().filter(type=TYPE)
                 .exclude(id__in=frozen)
                 .extra(select={'_app': request.APP.id}))

    category = None
    if category_slug is not None:
        category = get_list_or_404(Category, slug=category_slug, type=TYPE)[0]
        base = base.filter(categories__id=category.id)

    filter = PersonasFilter(request, base, key='sort', default='up-and-coming')
    return categories, filter, base, category
Exemple #52
0
    def _categories_meta(self, results, **kwargs):
        r = results[self.queries['category']]

        if 'matches' not in r:
            return []

        category_ids = []
        for m in r['matches']:
            category_ids.extend(m['attrs']['category'])

        category_ids = set(category_ids)
        categories = []

        if category_ids:
            qs = Category.objects.filter(id__in=set(category_ids))
            if 'app' in kwargs:
                qs = qs.filter(
                    Q(application=kwargs['app']) | Q(type=amo.ADDON_SEARCH))
            categories = order_by_translation(qs, 'name')
        return categories
Exemple #53
0
def _do_sort(request, qs, date_field='created'):
    """Column sorting logic based on request GET parameters."""
    sort, order = clean_sort_param(request, date_field=date_field)

    if qs.model is not Webapp and sort != date_field:
        # For when `Webapp` isn't the base model of the queryset.
        sort = 'addon__' + sort

    if order == 'asc':
        order_by = sort
    else:
        order_by = '-%s' % sort

    if sort == 'name':
        return order_by_translation(qs, order_by)
    elif sort == 'num_abuse_reports':
        return (qs.annotate(
            num_abuse_reports=Count('abuse_reports')).order_by(order_by))
    else:
        return qs.order_by(order_by)
Exemple #54
0
def themes(request, category=None):
    q = Category.objects.filter(application=request.APP.id,
                                type=amo.ADDON_THEME)
    categories = order_by_translation(q, 'name')

    addons, filter = addon_listing(request, [amo.ADDON_THEME])

    if category is not None:
        try:
            category = dict((c.slug, c) for c in categories)[category]
        except KeyError:
            raise http.Http404()
        addons = addons.filter(categories__id=category.id)

    themes = amo.utils.paginate(request, addons, count=addons.count())
    return jingo.render(request, 'browse/themes.html',
                        {'categories': categories,
                         'themes': themes, 'category': category,
                         'sorting': filter.field,
                         'sort_opts': filter.opts,
                         'search_cat': '%s,0' % amo.ADDON_THEME})
Exemple #55
0
    def test_sorting_en(self):
        q = TranslatedModel.objects.all()
        expected = [4, 1, 3]

        eq_(ids(order_by_translation(q, 'name')), expected)
        eq_(ids(order_by_translation(q, '-name')), list(reversed(expected)))
Exemple #56
0
 def filter_name(self):
     return order_by_translation(self.base_queryset.all(), 'name')
Exemple #57
0
 def filter_name(self):
     return order_by_translation(Addon.objects.all(), 'name')
Exemple #58
0
 def my_apps(self, n=8):
     """Returns n apps"""
     qs = self.addons.filter(type=amo.ADDON_WEBAPP)
     qs = order_by_translation(qs, 'name')
     return qs[:n]