Files
matrix-screen-controller/核桃派软件源代码/app/fonts/render_cache.py
T

65 lines
2.1 KiB
Python

"""Version only thumbnails that use a bundled font; preserve scene revisions."""
from __future__ import annotations
import hashlib
import json
from pathlib import Path
from app.persistence import atomic_write_bytes
STAMP_SUFFIX = ".font-version"
def scene_font_version(scene: dict, resolver) -> str | None:
owner = getattr(resolver, "__self__", None)
version_for = getattr(owner, "render_version", None)
if version_for is None:
return None
elements = scene.get("elements", []) if scene.get("version") == 1 else [
element for layer in scene.get("layers", []) if layer.get("type") == "text"
for element in layer.get("elements", [])
]
versions = sorted({version for element in elements
if (version := version_for(element.get("font", "default")))})
if not versions:
return None
return hashlib.sha256(json.dumps(versions, separators=(",", ":")).encode("ascii")).hexdigest()[:16]
def stamp_path(path: Path) -> Path:
return path.with_name(path.name + STAMP_SUFFIX)
def cache_stale(path: Path, scene: dict, resolver) -> bool:
version = scene_font_version(scene, resolver)
if version is None:
return False
try:
return stamp_path(path).read_text(encoding="ascii").strip() != version
except (OSError, UnicodeError):
return True
def stamp_cache(path: Path, scene: dict, resolver) -> None:
version = scene_font_version(scene, resolver)
stamp = stamp_path(path)
if version is not None:
atomic_write_bytes(stamp, (version + "\n").encode("ascii"))
else:
stamp.unlink(missing_ok=True)
def versioned_url(url: str, scene: dict, resolver) -> str:
version = scene_font_version(scene, resolver)
return url + f"&font_v={version}" if version else url
def cached_versioned_url(url: str, path: Path) -> str:
try:
version = stamp_path(path).read_text(encoding="ascii").strip()
except (OSError, UnicodeError):
return url
if len(version) == 16 and all(ch in "0123456789abcdef" for ch in version):
return url + f"&font_v={version}"
return url