changeset 699071b74405 in www.tryton.org:default
details: https://hg.tryton.org/www.tryton.org?cmd=changeset;node=699071b74405
description:
Add Link header to preload javascript, css and fonts
diffstat:
app.py | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 69 insertions(+), 1 deletions(-)
diffs (206 lines):
diff -r beea3b045d99 -r 699071b74405 app.py
--- a/app.py Sat Jul 27 10:28:38 2019 +0200
+++ b/app.py Sat Jul 27 10:29:13 2019 +0200
@@ -1,11 +1,12 @@
#!/bin/env python3
import datetime
+import functools
import logging
import os
import re
import unicodedata
-from collections import OrderedDict
+from collections import OrderedDict, namedtuple
from functools import partial
from http import HTTPStatus
from logging.handlers import SMTPHandler
@@ -89,6 +90,56 @@
return _slugify_hyphenate_re.sub('-', value)
+LinkHeader = namedtuple(
+ 'LinkHeader', ['endpoint', 'args', 'kwargs', 'params'])
+
+JS_LINK_HEADERS = [
+ LinkHeader('static', [], {'filename': 'js/all.js'}, {
+ 'rel': 'preload', 'as': 'script', 'nopush': True}),
+ ]
+CSS_LINK_HEADERS = [
+ LinkHeader(
+ 'static', [], {'filename': 'css/screen.min.css'}, {
+ 'rel': 'preload', 'as': 'style', 'nopush': True}),
+ LinkHeader(
+ 'static', [], {'filename': 'fonts/RobotoCondensed-Light.woff'}, {
+ 'rel': 'preload', 'as': 'font', 'nopush': True}),
+ LinkHeader(
+ 'static', [], {'filename': 'fonts/RobotoCondensed-Regular.woff'}, {
+ 'rel': 'preload', 'as': 'font', 'nopush': True}),
+ LinkHeader(
+ 'static', [], {'filename': 'fonts/RobotoCondensed-Bold.woff'}, {
+ 'rel': 'preload', 'as': 'font', 'nopush': True}),
+ LinkHeader(
+ 'static', [], {'filename': 'fonts/MaterialIcons-Regular.woff2'}, {
+ 'rel': 'preload', 'as': 'font', 'nopush': True}),
+ ]
+
+
+def add_links(links):
+ def format_param(param):
+ key, value = param
+ if value is True:
+ return key
+ else:
+ return '%s=%s' % (key, value)
+
+ def decorator(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ response = make_response(func(*args, **kwargs))
+ for link in links:
+ url = cdn_url_for(link.endpoint, *link.args, **link.kwargs)
+ params = '; '.join(map(format_param, link.params.items()))
+ value = '<{url}>; {params}'.format(
+ url=url,
+ params=params)
+ response.headers.add('Link', value)
+ return response
+ return wrapper
+ return decorator
+
+
@app.after_request
def add_cache_control_header(response):
if 'Cache-Control' not in response.headers:
@@ -106,6 +157,7 @@
@app.route('/')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def index():
return render_template(
'index.html',
@@ -311,6 +363,7 @@
@app.route('/success-stories')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def success_stories():
cases = sorted(
sample(CASES, len(CASES)), key=attrgetter('story'), reverse=True)
@@ -324,6 +377,7 @@
@app.route('/success-stories/<story>')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def success_story(story):
cases = [c for c in CASES if c.story or c.name == story]
try:
@@ -346,6 +400,7 @@
@app.route('/download')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def download():
return render_template('download.html')
@@ -357,12 +412,14 @@
@app.route('/forum')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def forum():
return render_template('forum.html')
@app.route('/presentations')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def presentations():
return render_template('presentations.html')
@@ -374,6 +431,7 @@
@app.route('/events/<event>')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def event(event):
class Day:
def __init__(self, date, *events, location=None, full=False):
@@ -432,6 +490,7 @@
@app.route('/contribute')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def contribute():
return render_template('contribute.html')
@@ -443,12 +502,14 @@
@app.route('/develop')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def develop():
return render_template('develop.html')
@app.route('/foundation')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def foundation():
return render_template('foundation.html')
@@ -460,6 +521,7 @@
@app.route('/supporters')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def supporters():
def url(supporter, start):
for website in supporter['websites']:
@@ -490,6 +552,7 @@
@app.route('/donate')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def donate():
headers = {'Content-Type': 'application/json'}
try:
@@ -516,18 +579,21 @@
@app.route('/donate/thanks')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def donate_thanks():
return render_template('donate_thanks.html')
@app.route('/donate/cancel')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def donate_cancel():
return render_template('donate_cancel.html')
@app.route('/service-providers')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def service_providers():
shuffle(PROVIDERS)
return render_template('service_providers.html', providers=PROVIDERS)
@@ -540,6 +606,7 @@
@app.route('/service-providers/start')
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def service_providers_start():
return render_template('service_providers_start.html')
@@ -551,6 +618,7 @@
@app.errorhandler(HTTPStatus.NOT_FOUND)
@cache.cached()
+@add_links(JS_LINK_HEADERS + CSS_LINK_HEADERS)
def not_found(error):
return render_template('not_found.html'), HTTPStatus.NOT_FOUND