import os import yaml import shutil from os import path from typing import Any from jinja2 import Template from PIL import Image PATH_ROOT = path.dirname(__file__) PATH_DIST = path.join(PATH_ROOT, "dist") PATH_DATA = path.join(PATH_ROOT, "data") PATH_HTML = path.join(PATH_ROOT, "html") PATH_PUBLIC = path.join(PATH_ROOT, "public") PATH_IMAGES = path.join(PATH_ROOT, "images") PATH_DIST_ASSETS = path.join(PATH_DIST, "assets") COLOR_RED = "31" COLOR_GREEN = "32" COLOR_YELLOW = "33" COLOR_BLUE = "34" def handle_webp(filename: str): src = path.join(PATH_IMAGES, filename) dst = path.join(PATH_DIST_ASSETS, file_chext(filename, "webp")) file_ensure_prefix(dst) image = Image.open(src).convert("RGBA") image.save(dst, "WEBP") dist_log("WEBP", dst, COLOR_YELLOW) def handle_copy(filename: str, src_root: str = PATH_PUBLIC, dst_root: str = PATH_DIST): src = path.join(src_root, filename) dst = path.join(dst_root, filename) file_ensure_prefix(dst) shutil.copy(src, dst) dist_log("COPY", dst, COLOR_GREEN) def handle_html(filename: str): yaml_filename = path.join(PATH_DATA, file_chext(filename, "yaml")) html_filename = path.join(PATH_HTML, filename) dest_filename = path.join(PATH_DIST, filename) data = {} file_ensure_prefix(dest_filename) if path.exists(yaml_filename): with open(yaml_filename, "r", encoding="utf-8") as f: data = yaml.safe_load(f) with open(html_filename, "r", encoding="utf-8") as f: template = Template(f.read()) with open(dest_filename, "w+", encoding="utf-8") as f: f.write(template.render(data)) dist_log("HTML", dest_filename, COLOR_YELLOW) def dist_log(tag: str, filename: str, color: str): root = path.abspath(PATH_DIST) filename = path.abspath(filename) relpath = path.relpath(filename, root) size = path.getsize(filename) hsize = f"{humanize_size(size):>10}" if size > 1024 * 1024: hsize = f"\033[01;31m{hsize}\033[00m" if size > 300 * 1024: hsize = f"\033[01;33m{hsize}\033[00m" if size > 100 * 1024: hsize = f"\033[01;35m{hsize}\033[00m" else: hsize = f"\033[01;32m{hsize}\033[00m" print(f"\033[01;{color}m{tag:<6}\033[00m {relpath:<50} | {hsize}") def humanize_size(size: int) -> str: if size < 1024: return f"{size} B" if size < 1024 ** 2: return f"{size / 1024:.2f} KB" if size < 1024 ** 3: return f"{size / 1024 ** 2:.2f} MB" return f"{size / 1024 ** 3:.2f} GB" def file_noext(filename: str) -> str: return ".".join(filename.split(".")[:-1]) def file_chext(filename: str, ext: str) -> str: return f"{file_noext(filename)}.{ext}" def file_ensure_prefix(filename: str): os.makedirs(path.dirname(filename), exist_ok=True) def file_should_skip(filename: str) -> bool: basename = path.basename(filename) if basename.startswith("."): return True def file_rpath(root: str, dirname: str, filename: str) -> str: return path.relpath(path.join(root, dirname, filename), root) def main(): shutil.rmtree("dist", ignore_errors=True) for dirname, _, filenames in os.walk(PATH_HTML): for filename in filenames: if file_should_skip(filename) or (not filename.endswith(".html")): continue handle_html(file_rpath(PATH_HTML, dirname, filename)) for dirname, _, filenames in os.walk(PATH_IMAGES): for filename in filenames: if file_should_skip(filename): continue if filename.split(".")[-1] in ["png", "jpg", "jpeg"]: handle_webp(file_rpath(PATH_IMAGES, dirname, filename)) continue if filename.split(".")[-1] in ["webp", "ico", "svg"]: handle_copy(file_rpath(PATH_IMAGES, dirname, filename), PATH_IMAGES, PATH_DIST_ASSETS) continue continue for dirname, _, filenames in os.walk(PATH_PUBLIC): for filename in filenames: if file_should_skip(filename): continue handle_copy(file_rpath(PATH_PUBLIC, dirname, filename)) if __name__ == "__main__": main()