"""Assemble this repository's static site: a manifest of the submissions, the solution files, and the viewer page.""" from __future__ import annotations import argparse import json import shutil from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def main(): ap = argparse.ArgumentParser() ap.add_argument("--out", type=Path, default=ROOT / "site") args = ap.parse_args() out: Path = args.out if out.exists(): shutil.rmtree(out) out.mkdir(parents=True) manifest = {"challenges": {}} for p in sorted((ROOT / "solutions").glob("*/*.json")): sub = json.loads(p.read_text()) cid = p.parent.name entry = manifest["challenges"].setdefault(cid, {"submissions": []}) rel_dir = p.parent.relative_to(ROOT) for sol in sub["solutions"]: sol["output"] = f"{rel_dir.as_posix()}/{sol['output']}" if "fields" in sol and not sol["fields"]["path"].startswith("http"): sol["fields"]["path"] = f"{rel_dir.as_posix()}/{sol['fields']['path']}" entry["submissions"].append(sub) shutil.copytree(ROOT / "solutions", out / "solutions") shutil.copyfile(ROOT / "web" / "index.html", out / "index.html") shutil.copyfile(ROOT / "web" / "viewer.js", out / "viewer.js") # the shared Web Audio player, from the installed challenge-tools package from challenge_tools.build import player_js (out / "player.js").write_text(player_js()) # suggested playback gains, when the challenge repository is checked out beside us (as in the workflow) gains = {} for cj in sorted((ROOT / "challenge-repo" / "challenges").glob("*/challenge.json")) if (ROOT / "challenge-repo").exists() else []: ch = json.loads(cj.read_text()) gains[ch["challenge_id"]] = (ch.get("playback") or {}).get("gain_db") manifest["playback_gain_db"] = gains (out / "manifest.json").write_text(json.dumps(manifest, indent=1)) print(f"site written to {out}") if __name__ == "__main__": main()