From 4bdc5faf333f391dc4d80ad0ddf0cee19c9fe666 Mon Sep 17 00:00:00 2001 From: Niklas Elsbrock Date: Sat, 15 Aug 2026 16:39:05 +0200 Subject: [PATCH] introduce brotli compression to build script --- build.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/build.py b/build.py index 34192d2..ab5f2a7 100755 --- a/build.py +++ b/build.py @@ -1,31 +1,84 @@ #!/usr/bin/env python import contextlib -from io import BufferedWriter, FileIO import os import shutil +from io import BufferedWriter, FileIO + +import brotli import git +import magic from jinja2 import Environment, FileSystemLoader SOURCES_DIR = "src" DIST_DIR = "dist" +BROTLI_THRESHOLD = 1024 + +# taken from https://caddyserver.com/docs/caddyfile/directives/encode +BROTLI_MIME_PREFIXES = [ + "application/atom+xml", + "application/eot", + "application/font", + "application/geo+json", + "application/graphql+json", + "application/javascript", + "application/json", + "application/ld+json", + "application/manifest+json", + "application/opentype", + "application/otf", + "application/rss+xml", + "application/truetype", + "application/ttf", + "application/vnd.api+json", + "application/vnd.ms-fontobject", + "application/wasm", + "application/x-httpd-cgi", + "application/x-javascript", + "application/x-opentype", + "application/x-otf", + "application/x-perl", + "application/x-protobuf", + "application/x-ttf", + "application/xhtml+xml", + "application/xml", + "font/", + "image/svg+xml", + "image/vnd.microsoft.icon", + "image/x-icon", + "multipart/bag", + "multipart/mixed", + "text/", +] + def latest_git_commit_year() -> int: return git.Repo(".").head.commit.authored_datetime.year -def build_template(env: Environment, src_path: str): +def build_template(env: Environment, src_path: str) -> tuple[str, int]: rel_path = os.path.relpath(src_path, SOURCES_DIR) dist_path = os.path.splitext(os.path.join(DIST_DIR, rel_path))[0] template = env.get_template(rel_path) rendered_text = template.render(copyright_year = latest_git_commit_year()) + size = 0 with BufferedWriter(FileIO(dist_path, "wb")) as writer: for line in rendered_text.splitlines(): line = line.strip() if len(line) > 0: - writer.write(line.encode()) - writer.write(b"\n") + line_b = line.encode() + size += len(line_b) + 1 + _ = writer.write(line.encode()) + _ = writer.write(b"\n") + + return dist_path, size + +def compress(path: str, mode): + with open(path, "rb") as reader, open(path + ".br", "wb") as writer: + content = reader.read() + compressed = brotli.compress(content, mode) + writer.write(compressed) def main(): with contextlib.suppress(FileNotFoundError): @@ -36,6 +89,8 @@ def main(): autoescape=True ) + mime = magic.Magic(mime=True) + for root, _, files in os.walk(SOURCES_DIR): rel_dir_path = os.path.relpath(root, SOURCES_DIR) dist_root = os.path.join(DIST_DIR, rel_dir_path) @@ -46,11 +101,19 @@ def main(): if src_name.endswith(".jinja"): if not src_name.startswith("_"): - build_template(env, src_path) - + dist_path, size = build_template(env, src_path) + if size > BROTLI_THRESHOLD: + compress(dist_path, brotli.MODE_TEXT) else: dist_path = os.path.join(dist_root, src_name) shutil.copy(src_path, dist_path) + if os.path.getsize(dist_path) > BROTLI_THRESHOLD: + mimetype = mime.from_file(dist_path) + if any(mimetype.startswith(prefix) for prefix in BROTLI_MIME_PREFIXES): + mode = brotli.MODE_FONT if mimetype == "font/woff2" else brotli.MODE_GENERIC + compress(dist_path, mode) + + if __name__ == '__main__': main()