63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Build a self-contained HTML artifact for sandboxed Gallery viewers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import base64
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
SITE = ROOT / "prototype" / "site"
|
|
DEFAULT_OUTPUT = ROOT / "prototype" / "gallery" / "aetherbound-guild-prototype.html"
|
|
|
|
|
|
def data_uri(path: Path) -> str:
|
|
mime = "image/webp" if path.suffix == ".webp" else "application/octet-stream"
|
|
encoded = base64.b64encode(path.read_bytes()).decode("ascii")
|
|
return f"data:{mime};base64,{encoded}"
|
|
|
|
|
|
def main() -> None:
|
|
index = (SITE / "index.html").read_text(encoding="utf-8")
|
|
styles = (SITE / "styles.css").read_text(encoding="utf-8")
|
|
app = (SITE / "app.js").read_text(encoding="utf-8")
|
|
catalog = json.loads((SITE / "data" / "catalog.json").read_text(encoding="utf-8"))
|
|
|
|
asset_paths = sorted((SITE / "assets" / "web").glob("*.webp"))
|
|
asset_paths.append(SITE / "favicon.webp")
|
|
for path in asset_paths:
|
|
relative = path.relative_to(SITE).as_posix()
|
|
uri = data_uri(path)
|
|
index = index.replace(relative, uri)
|
|
app = app.replace(relative, uri)
|
|
|
|
catalog_json = json.dumps(catalog, ensure_ascii=False, separators=(",", ":"))
|
|
catalog_json = catalog_json.replace("<", "\\u003c")
|
|
app = app.replace("</script", "<\\/script")
|
|
styles = styles.replace("</style", "<\\/style")
|
|
|
|
index = index.replace(
|
|
'<link rel="stylesheet" href="styles.css" />',
|
|
f"<style>\n{styles}\n</style>",
|
|
)
|
|
index = index.replace(
|
|
'<script src="app.js" defer></script>',
|
|
f'<script id="prototype-data" type="application/json">{catalog_json}</script>\n'
|
|
f"<script>\n{app}\n</script>",
|
|
)
|
|
|
|
if 'href="styles.css"' in index or 'src="app.js"' in index:
|
|
raise RuntimeError("external stylesheet or script remains in bundle")
|
|
if "assets/web/" in index:
|
|
raise RuntimeError("external prototype asset remains in bundle")
|
|
|
|
DEFAULT_OUTPUT.parent.mkdir(parents=True, exist_ok=True)
|
|
DEFAULT_OUTPUT.write_text(index, encoding="utf-8")
|
|
print(f"ABG_GALLERY_BUNDLE_OK bytes={DEFAULT_OUTPUT.stat().st_size} output={DEFAULT_OUTPUT}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|