addons-server/apps/browse/views.py

178 строки
6.1 KiB
Python
Исходник Обычный вид История

2010-02-06 01:06:16 +03:00
import collections
import itertools
2010-03-24 04:05:50 +03:00
from django.shortcuts import get_object_or_404
2010-02-10 22:35:25 +03:00
2010-03-24 04:05:50 +03:00
from l10n import ugettext as _, ugettext_lazy as _lazy
2010-02-06 01:06:16 +03:00
import jingo
import product_details
2010-02-10 22:35:25 +03:00
import amo.utils
from addons.models import Addon, Category
from translations.query import order_by_translation
2010-02-06 01:06:16 +03:00
languages = dict((lang.lower(), val)
for lang, val in product_details.languages.items())
def locale_display_name(locale):
"""
Return (english name, native name) for the locale.
Raises KeyError if the locale can't be found.
"""
if not locale:
raise KeyError
if locale.lower() in languages:
v = languages[locale.lower()]
return v['English'], v['native']
else:
# Take out the regional portion and try again.
hyphen = locale.rfind('-')
if hyphen == -1:
raise KeyError
else:
return locale_display_name(locale[:hyphen])
Locale = collections.namedtuple('Locale', 'locale display native dicts packs')
def language_tools(request):
types = (amo.ADDON_DICT, amo.ADDON_LPAPP)
q = (Addon.objects.public().exclude(target_locale='')
.filter(type__in=types, target_locale__isnull=False))
2010-02-06 01:06:16 +03:00
addons = [a for a in q.all() if request.APP in a.compatible_apps]
for addon in addons:
locale = addon.target_locale.lower()
try:
english, native = locale_display_name(locale)
# Add the locale as a differentiator if we had to strip the
# regional portion.
if locale not in languages:
native = '%s (%s)' % (native, locale)
addon.locale_display, addon.locale_native = english, native
except KeyError:
english = u'%s (%s)' % (addon.name, locale)
addon.locale_display, addon.locale_native = english, ''
locales = {}
for locale, addons in itertools.groupby(addons, lambda x: x.target_locale):
addons = list(addons)
dicts = [a for a in addons if a.type_id == amo.ADDON_DICT]
packs = [a for a in addons if a.type_id == amo.ADDON_LPAPP]
addon = addons[0]
locales[locale] = Locale(addon.target_locale, addon.locale_display,
addon.locale_native, dicts, packs)
locales = sorted(locales.items(), key=lambda x: x[1].display)
return jingo.render(request, 'browse/language_tools.html',
{'locales': locales})
2010-02-10 22:35:25 +03:00
# Placeholder for the All category.
_Category = collections.namedtuple('Category', 'name count slug')
class AddonFilter(object):
2010-02-10 22:35:25 +03:00
"""
Support class for sorting add-ons. Sortable fields are defined as
(value, title) pairs in ``opts``. Pass in a request and a queryset and
AddonFilter will figure out how to sort the queryset.
2010-02-10 22:35:25 +03:00
self.sorting: the field we're sorting by
self.opts: all the sort options
self.qs: the sorted queryset
"""
opts = (('name', _lazy(u'Name')),
('updated', _lazy(u'Updated')),
('created', _lazy(u'Created')),
('downloads', _lazy(u'Downloads')),
('rating', _lazy(u'Rating')))
2010-02-10 22:35:25 +03:00
def __init__(self, request, queryset, default):
self.sorting = self.options(request, default)
self.qs = self.sort(queryset, self.sorting)
def __iter__(self):
"""Cleverness: this lets you unpack the class like a tuple."""
return iter((self.sorting, self.opts, self.qs))
def options(self, request, default):
opts_dict = dict(self.opts)
if 'sort' in request.GET and request.GET['sort'] in opts_dict:
sort = request.GET['sort']
return sort
else:
return default
def sort(self, qs, field):
if field == 'updated':
2010-02-18 01:05:02 +03:00
return qs.order_by('-last_updated')
if field == 'created':
return qs.order_by('-created')
2010-02-10 22:35:25 +03:00
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 themes(request, category=None):
q = Category.objects.filter(application=request.APP.id,
type=amo.ADDON_THEME)
2010-02-10 22:35:25 +03:00
categories = order_by_translation(q, 'name')
addons, filter, experimental = _listing(request, amo.ADDON_THEME)
2010-02-10 22:35:25 +03:00
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)
return jingo.render(request, 'browse/themes.html',
{'categories': categories, 'total_count': total_count,
'themes': themes, 'selected': selected,
'sorting': filter.sorting,
'sort_opts': filter.opts,
2010-02-10 22:35:25 +03:00
'experimental': experimental})
def _listing(request, addon_type, default='downloads'):
# Set up the queryset and filtering for themes & extension listing pages.
status = [amo.STATUS_PUBLIC]
experimental = 'on' if request.GET.get('experimental', False) else None
if experimental:
status.append(amo.STATUS_SANDBOX)
qs = (Addon.objects.listed(request.APP, *status)
.filter(type=addon_type).distinct())
filter = AddonFilter(request, qs, default)
return filter.qs, filter, experimental
2010-03-24 04:05:50 +03:00
def extensions(request, category=None):
TYPE = amo.ADDON_EXTENSION
addons, filter, experimental = _listing(request, TYPE)
if category is not None:
q = Category.objects.filter(application=request.APP.id, type=TYPE)
category = get_object_or_404(q, slug=category)
addons = addons.filter(categories__id=category.id)
addons = amo.utils.paginate(request, addons)
return jingo.render(request, 'browse/extensions.html',
{'category': category, 'addons': addons,
'experimental': experimental,
'sorting': filter.sorting,
'sort_opts': filter.opts})