a27848b351
Calculates MD5 hash of static assets on server start. These are appended to the file name's when url_for is used, telling browsers to download the latest version of the files, e.g. style.css?q=81cf0ee. Inspired by https://github.com/ChrisTM/Flask-CacheBust but uses query strings instead of rewriting the path because fonts inside CSS files break when the path is rewritten.
58 lines
2.0 KiB
Python
58 lines
2.0 KiB
Python
# Inspired by https://github.com/ChrisTM/Flask-CacheBust
|
|
# Uses query strings so CSS font files are found without having to resort to absolute URLs
|
|
|
|
import hashlib
|
|
import os
|
|
|
|
|
|
def init_cache_busting(app):
|
|
"""
|
|
Configure `app` to so that `url_for` adds a unique query string to URLs generated
|
|
for the `'static'` endpoint.
|
|
|
|
This allows setting long cache expiration values on static resources
|
|
because whenever the resource changes, so does its URL.
|
|
"""
|
|
|
|
static_folder = app.static_folder # the rooted path to the static file folder
|
|
|
|
hash_table = {} # map of file hashes
|
|
|
|
app.logger.debug('Computing cache-busting values...')
|
|
# compute file hashes
|
|
for dirpath, dirnames, filenames in os.walk(static_folder):
|
|
for filename in filenames:
|
|
# compute version component
|
|
rooted_filename = os.path.join(dirpath, filename)
|
|
with open(rooted_filename, 'r') as f:
|
|
version = hashlib.md5(f.read()).hexdigest()[:7]
|
|
|
|
# save version to tables
|
|
file_path = rooted_filename.replace(static_folder + "/", "")
|
|
hash_table[file_path] = version
|
|
app.logger.debug('Finished computing cache-busting values')
|
|
|
|
def bust_filename(filename):
|
|
return hash_table.get(filename, "")
|
|
|
|
def unbust_filename(filename):
|
|
return filename.split("?", 1)[0]
|
|
|
|
@app.url_defaults
|
|
def reverse_to_cache_busted_url(endpoint, values):
|
|
"""
|
|
Make `url_for` produce busted filenames when using the 'static' endpoint.
|
|
"""
|
|
if endpoint == 'static':
|
|
values["q"] = bust_filename(values['filename'])
|
|
|
|
def debusting_static_view(filename):
|
|
"""
|
|
Serve a request for a static file having a busted name.
|
|
"""
|
|
return original_static_view(filename=unbust_filename(filename))
|
|
|
|
# Replace the default static file view with our debusting view.
|
|
original_static_view = app.view_functions['static']
|
|
app.view_functions['static'] = debusting_static_view
|