57 lines
1.8 KiB
Python
57 lines
1.8 KiB
Python
from jinja2_simple_tags import StandaloneTag
|
|
import jinja2
|
|
from copy import deepcopy
|
|
from mkdocs.structure.files import File, Files
|
|
from mkdocs.plugins import event_priority, get_plugin_logger
|
|
import hashlib
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
from pathlib import Path
|
|
|
|
logger = get_plugin_logger("static")
|
|
|
|
|
|
def transform_file_url(url: str, hash: str):
|
|
url_path = Path(url)
|
|
return str(url_path.with_stem(url_path.stem + "." + hash[:10]))
|
|
|
|
def hash_file(file: File) -> File:
|
|
logger.debug("Hashing %s", file.url)
|
|
|
|
hashed_file = deepcopy(file)
|
|
|
|
with open(file.abs_src_path, "rb") as f:
|
|
digest = hashlib.file_digest(f, "md5").hexdigest()
|
|
|
|
hashed_file.abs_dest_path = transform_file_url(hashed_file.abs_dest_path, digest)
|
|
hashed_file.dest_uri = transform_file_url(hashed_file.dest_uri, digest)
|
|
hashed_file.url = transform_file_url(hashed_file.url, digest)
|
|
|
|
return hashed_file
|
|
|
|
@event_priority(-100)
|
|
def on_files(files: Files, config):
|
|
with ThreadPoolExecutor() as executor:
|
|
for hashed_file in executor.map(hash_file, files.media_files()):
|
|
files.append(hashed_file)
|
|
|
|
# HACK: Add a fake file with a `src_uri` of the hashed path so other integrations can find the right file
|
|
hashed_src_file = deepcopy(hashed_file)
|
|
hashed_src_file.src_uri = hashed_src_file.dest_uri
|
|
files.append(hashed_src_file)
|
|
|
|
return files
|
|
|
|
def on_env(env: jinja2.Environment, config, files):
|
|
env.add_extension(make_static_extension(files))
|
|
|
|
return env
|
|
|
|
def make_static_extension(files: Files):
|
|
class StaticExtension(StandaloneTag):
|
|
tags = {"static"}
|
|
|
|
def render(self, filename):
|
|
file = files.get_file_from_path(filename)
|
|
return file.url
|
|
|
|
return StaticExtension
|