#!/usr/bin/env python3 """Regenerate a vendored copy of the dashboard UI for an app that embeds it. Sanad's "Hands" tab serves a CODE COPY of this dashboard's HTML with every /api/ call rewritten to /api/hands/, and proxies those calls back to :8088. A hand copy goes stale the moment hand_web.py changes — a button appears here and not there, and nobody notices until it is needed. This regenerates that copy from the real source, so re-vendoring is one command instead of an extraction by hand. # write Sanad's copy (run after any dashboard change, then redeploy Sanad) python3 tools/export_ui.py --prefix hands \ --out ~/Sanad_Package_5/Sanad/dashboard/static/hands.html # check an existing copy is current, without writing (exit 1 if stale) python3 tools/export_ui.py --prefix hands --check The HTML is taken from hand_web.py itself rather than re-parsed from a file, so what gets vendored is exactly what the server serves. """ import argparse import os import re import sys HERE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.join(HERE, "..", "web")) def build(prefix): import hand_web # noqa: E402 (path set above) html = hand_web.HTML if not prefix: return html # Only rewrite the API root. Absolute URLs that merely contain "api" (there are # none today, but a future /api/... inside a string literal would be caught by # the same rule) go through unchanged unless they start a request path. out, n = re.subn(r"(? /api/hands/)") ap.add_argument("--out", help="write here (default: stdout)") ap.add_argument("--check", metavar="PATH", help="compare against PATH and exit 1 if it is stale") a = ap.parse_args() html = build(a.prefix) if a.check: try: cur = open(a.check, encoding="utf-8").read() except OSError as e: sys.exit("cannot read %s: %s" % (a.check, e)) if cur == html: print("up to date: %s" % a.check) return print("STALE: %s (%d bytes) differs from the current dashboard (%d bytes)" % (a.check, len(cur), len(html))) sys.exit(1) if a.out: with open(a.out, "w", encoding="utf-8") as f: f.write(html) print("wrote %s (%d bytes, prefix /api/%s/)" % (a.out, len(html), a.prefix)) else: sys.stdout.write(html) if __name__ == "__main__": main()