addons-server/apps/versions/views.py

127 строки
4.6 KiB
Python

import posixpath
from django import http
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, redirect
import caching.base as caching
import commonware.log
import jingo
from mobility.decorators import mobile_template
import amo
from amo.urlresolvers import reverse
from amo.utils import HttpResponseSendFile, urlparams
from access import acl
from addons.decorators import addon_view_factory
from addons.models import Addon
from files.models import File
from versions.models import Version
# The version detail page redirects to the version within pagination, so we
# need to enforce the number of versions per page.
PER_PAGE = 30
addon_view = addon_view_factory(Addon.objects.valid)
log = commonware.log.getLogger('z.versions')
@addon_view
@mobile_template('versions/{mobile/}version_list.html')
def version_list(request, addon, template):
qs = (addon.versions.filter(files__status__in=amo.VALID_STATUSES)
.distinct().order_by('-created'))
versions = amo.utils.paginate(request, qs, PER_PAGE)
versions.object_list = list(versions.object_list)
Version.transformer(versions.object_list)
return jingo.render(request, template,
{'addon': addon, 'versions': versions})
@addon_view
def version_detail(request, addon, version_num):
qs = (addon.versions.filter(files__status__in=amo.VALID_STATUSES)
.distinct().order_by('-created'))
# Use cached_with since values_list won't be cached.
f = lambda: _find_version_page(qs, addon, version_num)
return caching.cached_with(qs, f, 'vd:%s:%s' % (addon.id, version_num))
def _find_version_page(qs, addon, version_num):
ids = list(qs.values_list('version', flat=True))
url = reverse('addons.versions', args=[addon.slug])
if version_num in ids:
page = 1 + ids.index(version_num) / PER_PAGE
to = urlparams(url, 'version-%s' % version_num, page=page)
return http.HttpResponseRedirect(to)
else:
raise http.Http404()
@addon_view
def update_info(request, addon, version_num):
qs = addon.versions.filter(version=version_num,
files__status__in=amo.VALID_STATUSES)
if not qs:
raise http.Http404()
serve_xhtml = ('application/xhtml+xml' in
request.META.get('HTTP_ACCEPT', '').lower())
return jingo.render(request, 'versions/update_info.html',
{'version': qs[0], 'serve_xhtml': serve_xhtml},
content_type='application/xhtml+xml')
def update_info_redirect(request, version_id):
version = get_object_or_404(Version, pk=version_id)
return redirect(reverse('addons.versions.update_info',
args=(version.addon.id, version.version)),
permanent=True)
# Should accept junk at the end for filename goodness.
def download_file(request, file_id, type=None):
file = get_object_or_404(File.objects, pk=file_id)
addon = get_object_or_404(Addon.objects, pk=file.version.addon_id)
if addon.is_premium():
raise PermissionDenied
if addon.is_disabled or file.status == amo.STATUS_DISABLED:
if (acl.check_addon_ownership(request, addon, viewer=True,
ignore_disabled=True) or
acl.check_reviewer(request)):
return HttpResponseSendFile(request, file.guarded_file_path,
content_type='application/xp-install')
else:
raise http.Http404()
attachment = (type == 'attachment' or not request.APP.browser)
loc = file.get_mirror(addon, attachment=attachment)
response = http.HttpResponseRedirect(loc)
response['X-Target-Digest'] = file.hash
return response
guard = lambda: Addon.objects.filter(_current_version__isnull=False)
@addon_view_factory(guard)
def download_latest(request, addon, type='xpi', platform=None):
platforms = [amo.PLATFORM_ALL.id]
if platform is not None and int(platform) in amo.PLATFORMS:
platforms.append(int(platform))
files = File.objects.filter(platform__in=platforms,
version=addon._current_version_id)
try:
# If there's a file matching our platform, it'll float to the end.
file = sorted(files, key=lambda f: f.platform_id == platforms[-1])[-1]
except IndexError:
raise http.Http404()
args = [file.id, type] if type else [file.id]
url = posixpath.join(reverse('downloads.file', args=args), file.filename)
if request.GET:
url += '?' + request.GET.urlencode()
return http.HttpResponseRedirect(url)