Implement assetcache module with asset hashing.

Provides a module `assetcache` to support automatic cachebusting of
static web assets, rather than the current approach of incrementing
a version number.

On module load, it walks the file/assets/ dir, computes a CRC32 of
each asset, and provides those hashes via `assetcache_get(path)` at
runtime. The primary consumer of hashes at present is the new `asset`
filter for Jinja2, which accepts a relative asset path and returns the
full path, with cache busting, suitable for final use in the template.

Ex: `{{ 'css/main.css' | asset }}`
This commit is contained in:
TLSM 2022-08-30 16:00:24 -04:00
parent c00533dc6e
commit fcb51c09d3
No known key found for this signature in database
GPG key ID: E745A82778055C7E
2 changed files with 30 additions and 0 deletions

View file

@ -0,0 +1,20 @@
import os
import zlib
from collections import defaultdict
ASSET_DIR = 'files/assets'
ASSET_CACHE = defaultdict(lambda: None)
def assetcache_build(asset_dir):
for root, dirs, files in os.walk(asset_dir):
for fname in files:
fpath = root + '/' + fname
relpath = fpath[len(asset_dir) + 1:].replace('\\', '/')
with open(fpath, 'rb') as f:
fhash = zlib.crc32(f.read())
ASSET_CACHE[relpath] = '%x' % fhash
def assetcache_get(path):
return ASSET_CACHE[path]
assetcache_build(ASSET_DIR)

View file

@ -3,6 +3,7 @@ from .get import *
from os import listdir, environ
from .const import *
import time
from files.helpers.assetcache import assetcache_get
@app.template_filter("post_embed")
def post_embed(id, v):
@ -46,6 +47,15 @@ def timestamp(timestamp):
years = int(months / 12)
return f"{years}yr ago"
@app.template_filter("asset")
def template_asset(asset_path):
outpath = '/assets/' + asset_path
cachehash = assetcache_get(asset_path)
if cachehash:
outpath += '?v=' + cachehash
return outpath
@app.context_processor
def inject_constants():