addons-server/mkt/site/views.py

160 строки
5.1 KiB
Python

import json
import logging
import os
import subprocess
from django.conf import settings
from django.http import HttpResponse, HttpResponseForbidden
from django.template import RequestContext
from django.views.decorators.cache import cache_page
from django.views.decorators.csrf import csrf_exempt
from django_statsd.clients import statsd
from django_statsd.views import record as django_statsd_record
import jingo
from jingo import render_to_string
import jingo_minify
from session_csrf import anonymous_csrf, anonymous_csrf_exempt
from amo.context_processors import get_collect_timings
from amo.decorators import post_required, no_login_required
from amo.helpers import media
import api.views
def handler404(request):
if request.path_info.startswith('/api/'):
# Pass over to API handler404 view if API was targeted.
return api.views.handler404(request)
else:
return jingo.render(request, 'site/404.html', status=404)
log = logging.getLogger('z.mkt.site')
def handler500(request):
if request.path_info.startswith('/api/'):
return api.views.handler500(request)
else:
return jingo.render(request, 'site/500.html', status=500)
def csrf_failure(request, reason=''):
return jingo.render(request, 'site/403.html',
{'because_csrf': 'CSRF' in reason}, status=403)
def manifest(request):
ctx = RequestContext(request)
data = {
'name': getattr(settings, 'WEBAPP_MANIFEST_NAME',
'Firefox Marketplace'),
'description': 'The Firefox Marketplace',
'developer': {
'name': 'Mozilla',
'url': 'http://mozilla.org',
},
'icons': {
# Using the default addon image until we get a marketplace logo.
'32': media(ctx, 'img/mkt/logos/32.png'),
'64': media(ctx, 'img/mkt/logos/64.png'),
'128': media(ctx, 'img/mkt/logos/128.png'),
},
# TODO: when we have specific locales, add them in here.
'locales': {},
'default_locale': 'en-US'
}
return HttpResponse(json.dumps(data),
mimetype='application/x-web-app-manifest+json')
def robots(request):
"""Generate a robots.txt"""
template = jingo.render(request, 'site/robots.txt')
return HttpResponse(template, mimetype="text/plain")
@anonymous_csrf
@anonymous_csrf_exempt
@post_required
def csrf(request):
"""A CSRF for anonymous users only."""
if not request.amo_user:
data = json.dumps({'csrf': RequestContext(request)['csrf_token']})
return HttpResponse(data, content_type='application/json')
return HttpResponseForbidden()
@csrf_exempt
@post_required
def record(request):
# The rate limiting is done up on the client, but if things go wrong
# we can just turn the percentage down to zero.
if get_collect_timings():
return django_statsd_record(request)
return HttpResponseForbidden()
# Cache this for an hour so that newly deployed changes are available within
# an hour. This will be served from the CDN which mimics these headers.
@cache_page(60 * 60)
@no_login_required
def mozmarket_js(request):
vendor_js = []
for lib, path in (('receiptverifier',
'receiptverifier/receiptverifier.js'),):
if lib in settings.MOZMARKET_VENDOR_EXCLUDE:
continue
with open(os.path.join(settings.ROOT,
'vendor', 'js', path), 'r') as fp:
vendor_js.append((lib, fp.read()))
js = render_to_string(request, 'site/mozmarket.js',
{'vendor_js': vendor_js})
if settings.MINIFY_MOZMARKET:
js = minify_js(js)
return HttpResponse(js, content_type='text/javascript')
@statsd.timer('mkt.mozmarket.minify')
def minify_js(js):
if settings.UGLIFY_BIN:
log.info('minifying JS with uglify')
return _minify_js_with_uglify(js)
else:
# The YUI fallback here is important
# because YUI compressor is bundled with jingo
# minify and therefore doesn't require any deps.
log.info('minifying JS with YUI')
return _minify_js_with_yui(js)
def _minify_js_with_uglify(js):
sp = _open_pipe([settings.UGLIFY_BIN])
js, err = sp.communicate(js)
if sp.returncode != 0:
raise ValueError('Compressing JS with uglify failed; error: %s'
% err.strip())
return js
def _minify_js_with_yui(js):
jar = os.path.join(os.path.dirname(jingo_minify.__file__), 'bin',
'yuicompressor-2.4.7.jar')
if not os.path.exists(jar):
raise ValueError('Could not find YUI compressor; tried %r' % jar)
sp = _open_pipe([settings.JAVA_BIN, '-jar', jar, '--type', 'js',
'--charset', 'utf8'])
js, err = sp.communicate(js)
if sp.returncode != 0:
raise ValueError('Compressing JS with YUI failed; error: %s'
% err.strip())
return js
def _open_pipe(cmd):
return subprocess.Popen(cmd,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)