Files
status-indicators/nav_keys.py
T

127 lines
4.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""Make the page nav keys on every page follow the status page's ALL button.
Which keys follow it is "nav_keys" in config.json (now just the page number).
The status page (page 19) carries coloured copies of Companion's own nav keys
(see make_page.py and nav_templates.json). This copies those over the built-in
keys on every other page, using the same "copy button" call as the Companion UI,
and puts back the built-in key for any kind no longer listed. Each key keeps
its normal press action.
python3 nav_keys.py --dry-run list what would change
python3 nav_keys.py apply (also refreshes keys already converted)
python3 nav_keys.py --revert put Companion's built-in nav keys back everywhere
Only nav keys are touched. Every location changed is recorded in nav_locations.json.
"""
import argparse
import gzip
import json
import os
import urllib.error
import urllib.request
from make_page import NAV_LOCATIONS, NAV_MARKER
from push_page import Trpc, WebSocket
HERE = os.path.dirname(os.path.abspath(__file__))
RECORD = os.path.join(HERE, "nav_locations.json")
NAV_TYPES = ("pageup", "pagenum", "pagedown")
def page_export(host, port, page):
url = "http://%s:%d/int/export/page/%d?includeSecrets=false" % (host, port, page)
try:
with urllib.request.urlopen(url, timeout=10) as r:
raw = r.read()
except urllib.error.HTTPError:
return None
try:
raw = gzip.decompress(raw)
except OSError:
pass
return json.loads(raw)
def nav_kind(control):
if control.get("type") in NAV_TYPES:
return control["type"]
notes = control.get("options", {}).get("notes", "") or ""
if control.get("type") == "button-layered" and notes.startswith(NAV_MARKER):
for kind in NAV_TYPES:
if "(%s)" % kind in notes:
return kind
return None
def is_ours(control):
return (control.get("options", {}).get("notes", "") or "").startswith(NAV_MARKER)
def find_nav_keys(host, port, status_page):
"""[(page, row, column, kind, ours)] for every nav key outside the status page."""
found, page = [], 1
while True:
export = page_export(host, port, page)
if export is None:
break
if page != status_page:
for r, cols in export["page"]["controls"].items():
for c, control in cols.items():
kind = nav_kind(control or {})
if kind:
found.append((page, int(r), int(c), kind, is_ours(control)))
page += 1
return found
def main():
cfg = json.load(open(os.path.join(HERE, "config.json")))
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
ap.add_argument("--host", default=cfg.get("site", {}).get("ingest_hostname") or cfg["companion"].get("host", "127.0.0.1"))
ap.add_argument("--port", type=int, default=cfg["companion"].get("port", 8000))
ap.add_argument("--dry-run", action="store_true")
ap.add_argument("--revert", action="store_true")
args = ap.parse_args()
status_page = cfg["page"]
coloured = cfg.get("nav_keys", list(NAV_LOCATIONS))
record = json.load(open(RECORD)) if os.path.exists(RECORD) else {}
found = find_nav_keys(args.host, args.port, status_page)
if args.revert:
work = [(p, r, c, k, "restore") for p, r, c, k, ours in found if ours]
else:
work = [(p, r, c, k, "colour") for p, r, c, k, ours in found if k in coloured]
work += [(p, r, c, k, "restore") for p, r, c, k, ours in found if ours and k not in coloured]
print("%d nav keys to colour, %d to restore, on %d pages" % (
sum(1 for w in work if w[4] == "colour"), sum(1 for w in work if w[4] == "restore"), len({w[0] for w in work})))
if args.dry_run:
for w in work:
print(" page %d row %d col %d: %s -> %s" % w)
return
ws = WebSocket(args.host, args.port, "/trpc")
done = 0
try:
api = Trpc(ws)
for page, row, col, kind, what in work:
location = {"pageNumber": page, "row": row, "column": col}
if what == "restore":
api.mutation("controls.resetControl", {"location": location, "newType": kind})
record.pop("%d/%d/%d" % (page, row, col), None)
else:
r, c = NAV_LOCATIONS[kind]
source = {"pageNumber": status_page, "row": int(r), "column": int(c)}
if not api.mutation("controls.copyControl", {"fromLocation": source, "toLocation": location}):
raise RuntimeError("copy to page %d row %d col %d failed" % (page, row, col))
record["%d/%d/%d" % (page, row, col)] = kind
done += 1
finally:
ws.close()
json.dump(record, open(RECORD, "w"), indent=1, sort_keys=True)
print("done: %d nav keys changed" % done)
if __name__ == "__main__":
main()