feat(gamebook): --json-only for BOX-3 + bump fw #188

Merged
electron merged 1 commits from feat/gamebook-json-only into main 2026-06-19 22:38:53 +00:00
2 changed files with 11 additions and 7 deletions
+10 -6
View File
@@ -114,7 +114,8 @@ def narration(text: str, choices: list[dict]) -> str:
return " ".join(parts)
def build_book(path: Path, force: bool, dry: bool, ip: str) -> dict | None:
def build_book(path: Path, force: bool, dry: bool, ip: str,
json_only: bool = False) -> dict | None:
"""Synthesise + (optionally) stage one book. Returns its library entry."""
bid = path.stem
book = yaml.safe_load(path.read_text())
@@ -133,8 +134,9 @@ def build_book(path: Path, force: bool, dry: bool, ip: str) -> dict | None:
print(f" ! {bid}/{pid} -> '{c['goto']}' inconnu"); return None
wav = f"{bid}_{pid}.wav"
out = OUT_DIR / wav
if not say_wav(narration(p["text"], choices), voice, out, force):
print(f" ✗ synth {bid}/{pid}"); n_fail += 1; continue
if not json_only: # text-only (BOX-3 touch) skips audio
if not say_wav(narration(p["text"], choices), voice, out, force):
print(f" ✗ synth {bid}/{pid}"); n_fail += 1; continue
n_ok += 1
manifest["passages"][pid] = {
"wav": wav,
@@ -143,7 +145,7 @@ def build_book(path: Path, force: bool, dry: bool, ip: str) -> dict | None:
"choices": [{"label": fold(c["label"])[:38], "goto": c["goto"]}
for c in choices],
}
if not dry:
if not dry and not json_only:
good, _ = push(ip, wav, out.read_bytes())
n_push += 1 if good else 0
n_fail += 0 if good else 1
@@ -162,9 +164,11 @@ def build_book(path: Path, force: bool, dry: bool, ip: str) -> dict | None:
def main() -> int:
ap = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
ap.add_argument("--ip", default="192.168.0.188", help="master IP (default .188)")
ap.add_argument("--ip", default="192.168.0.188", help="board IP (default .188)")
ap.add_argument("--force", action="store_true", help="re-synthesise cached WAVs")
ap.add_argument("--dry-run", action="store_true", help="synthesise only, no push")
ap.add_argument("--json-only", action="store_true",
help="build/push only the JSON (no WAVs) — for the BOX-3 touch UI")
args = ap.parse_args()
books = sorted(p for p in BOOKS_DIR.glob("*.yaml") if p.stem not in EXCLUDE)
@@ -176,7 +180,7 @@ def main() -> int:
entries, fail = [], 0
for path in books:
e = build_book(path, args.force, args.dry_run, args.ip)
e = build_book(path, args.force, args.dry_run, args.ip, args.json_only)
if e is None:
fail += 1
continue