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
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)
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)
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)
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})
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 })
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})
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)
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})
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})
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")
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
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]
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})
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, }, )
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 })
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')
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
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}, )
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
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})
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
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)
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})
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'))
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
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)
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))
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')
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')
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")
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))
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")
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')
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')
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')
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)
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
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 })
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)
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))
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)
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())
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
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
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)
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})
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)))
def filter_name(self): return order_by_translation(self.base_queryset.all(), 'name')
def filter_name(self): return order_by_translation(Addon.objects.all(), 'name')
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]