TRACKS OUT builds the locations' sets (Location Setup PDF): SC and WS in their own PCO keys (pitched stems transposed, locator, Waves Tune, pads, CtW/Salvation), consolidated in Live; AB as NA; key check per location; never edits a set open in Live
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+79
-12
@@ -553,7 +553,21 @@ for f in P["finished"]:
|
||||
out["finished"][f] = sorted(n for n in os.listdir(f) if "[" in n) if os.path.isdir(f) else None
|
||||
for loc in P["locations"]:
|
||||
d = folder(loc)
|
||||
out["bundles"][loc] = {"folder": d, "als": bool(newest_als(d)), "copying": os.path.isdir(d + ".copying")}
|
||||
a = newest_als(d)
|
||||
b = {"folder": d, "als": bool(a), "copying": os.path.isdir(d + ".copying")}
|
||||
if a and loc in P.get("transpose_locs", []):
|
||||
try:
|
||||
r = ET.parse(gzip.open(a)).getroot()
|
||||
b["locators"] = [l.find("Name").get("Value") for l in r.findall("LiveSet/Locators/Locators/Locator")]
|
||||
b["transposed"] = sum(1 for c in r.iter("AudioClip") if c.find("PitchCoarse") is not None
|
||||
and float(c.find("PitchCoarse").get("Value")) != 0)
|
||||
except Exception:
|
||||
pass
|
||||
out["bundles"][loc] = b
|
||||
try:
|
||||
out["loc_job"] = json.load(open(os.path.expanduser("~/Library/Caches/status-panel-locations.json")))
|
||||
except Exception:
|
||||
out["loc_job"] = {}
|
||||
print(json.dumps(out))
|
||||
'''
|
||||
|
||||
@@ -565,7 +579,7 @@ def ableton_params(rc, plan):
|
||||
"finished": rc.get("finished_folders", []), "tune_track": rc.get("tune_track", "WAVES TUNE"),
|
||||
"tune_library": rc.get("tune_library", ""), "lighting_track": rc.get("lighting_track", "LIGHTING CUES"),
|
||||
"hit_notes": rc.get("light_hit_notes", list(range(30, 40))), "hit_stems": rc.get("hit_stems", ["DRUMS"]),
|
||||
"light_library": rc.get("light_library", "")}
|
||||
"light_library": rc.get("light_library", ""), "transpose_locs": rc.get("transpose_locations", [])}
|
||||
|
||||
|
||||
def ableton_look(cfg, rc, plan):
|
||||
@@ -1257,13 +1271,38 @@ def eval_tune(rc, plan, look, sent=None):
|
||||
return line
|
||||
|
||||
|
||||
def eval_track_bundle(rc, look):
|
||||
LOCATOR = re.compile(r"^\s*(\d+)\s*-\s*(.*?)\s*-\s*([A-G](?:#|b)?m?)\s*$")
|
||||
|
||||
|
||||
def eval_track_bundle(rc, look, keys=None, now=None):
|
||||
"""Every location has this weekend's set; the ones in `transpose_locations` in the keys their own plan has
|
||||
(`keys`: {"WS": [{"title", "key"}]}) and consolidated."""
|
||||
line = Line()
|
||||
job = look.get("loc_job") or {}
|
||||
now = now or time.time()
|
||||
running = job.get("state") == "running" and now - (job.get("time") or 0) < 1800
|
||||
if running:
|
||||
line.fault(WARN, (job.get("step") or "WORKING")[:24], "TRACKS OUT is making the locations' sets: %s" % job.get("step"))
|
||||
elif job.get("state") == "failed" and now - (job.get("time") or 0) < 7 * 86400:
|
||||
line.fault(ERR, "FAILED " + (job.get("step") or "")[:16], "the last TRACKS OUT job stopped: %s" % job.get("step"))
|
||||
if not running and now - (job.get("time") or 0) < 86400:
|
||||
line.notes.extend(job.get("log") or [])
|
||||
for loc, b in sorted((look.get("bundles") or {}).items()):
|
||||
if b.get("copying"):
|
||||
line.fault(WARN, "COPYING TO " + loc, "the copy to %s is still running" % loc)
|
||||
elif not b.get("als"):
|
||||
line.fault(ERR, "NOT SENT " + loc, "no set in %s" % b.get("folder"))
|
||||
elif "locators" in b and not running:
|
||||
for name in b["locators"]:
|
||||
m = LOCATOR.match(name or "")
|
||||
want = next((x["key"] for x in (keys or {}).get(loc) or [] if m and x.get("key") and same(x["title"], m.group(2))), None)
|
||||
if want and not same_key(m.group(3), want, mode=False):
|
||||
line.fault(ERR, "%s %s %s NOT %s" % (loc, short(m.group(2), 10), m.group(3), want),
|
||||
"%s's plan has %s in %s; its set's locator \"%s\" says %s: hold TRACKS OUT" % (
|
||||
loc, m.group(2), want, name, m.group(3)))
|
||||
if b.get("transposed"):
|
||||
line.fault(WARN, "CONSOLIDATE " + loc, "%s's set has %d transposed clips not consolidated: hold TRACKS OUT" % (
|
||||
loc, b["transposed"]))
|
||||
line.info = " ".join(sorted(look.get("bundles") or {})) or "NO LOCATIONS"
|
||||
return line
|
||||
|
||||
@@ -1835,6 +1874,8 @@ def look(cfg, now=None, data_dir=None, sources=None):
|
||||
continue
|
||||
try:
|
||||
cplan = src["pco_campus"](campus["service_type"])
|
||||
LAST.setdefault("campus_keys", {})[campus.get("short")] = [
|
||||
{"title": it["title"], "key": it["key"]} for it in plan_songs(rc, cplan)]
|
||||
res = campus_ltc(rc, plan, na_songs, campus, cplan)
|
||||
eval_campus_ltc(rc, res, lines["timecode"])
|
||||
others.append(dict(res, songs=[dict(s, item={"id": s["item"]["id"], "note_ids": s["item"]["note_ids"]}) for s in res["songs"]]))
|
||||
@@ -1844,7 +1885,8 @@ def look(cfg, now=None, data_dir=None, sources=None):
|
||||
lines["timecode"].fault(WARN, "%s %s" % (tag, msg), "%s: %s" % (campus.get("name") or tag, e))
|
||||
LAST["ltc_other"] = others
|
||||
if rc.get("locations"):
|
||||
lines["track_bundle"] = eval_track_bundle(rc, al)
|
||||
lines["track_bundle"] = eval_track_bundle(rc, al, LAST.get("campus_keys"), now)
|
||||
loc_job_handback(cfg, rc, al.get("loc_job") or {})
|
||||
except Exception as e: # noqa: BLE001
|
||||
failed(["tracks", "mix_foh", "lights", "keys", "tune", "light_timing"] + (["track_bundle"] if rc.get("locations") else []), e)
|
||||
# START first: while it consolidates in Live it holds AbletonOSC's answers on the Tracks Mac.
|
||||
@@ -2161,9 +2203,17 @@ def start_look(cfg, rc, services):
|
||||
|
||||
|
||||
def start_in_live():
|
||||
"""START is consolidating in Live just now (it holds AbletonOSC's answers on the Tracks Mac)."""
|
||||
st = LAST.get("start_status") or {}
|
||||
return st.get("state") == "running" and time.time() - (st.get("live") or 0) < 600
|
||||
"""START or TRACKS OUT is consolidating in Live just now (it holds AbletonOSC's answers on the Tracks Mac)."""
|
||||
return any(st.get("state") == "running" and time.time() - (st.get("live") or 0) < 600
|
||||
for st in (LAST.get("start_status") or {}, LAST.get("loc_job") or {}))
|
||||
|
||||
|
||||
def loc_job_handback(cfg, rc, st):
|
||||
"""TRACKS OUT's job used AbletonOSC from the Tracks Mac: give it back to Companion once it is done."""
|
||||
LAST["loc_job"] = st
|
||||
if st.get("live") and st.get("state") != "running" and LAST.get("loc_handed") != st["live"]:
|
||||
hand_back(cfg, rc["tracks_host"])
|
||||
LAST["loc_handed"] = st["live"]
|
||||
|
||||
|
||||
def eval_start(rc, services, look, now):
|
||||
@@ -2464,11 +2514,28 @@ def run_action(cfg, action, chk=None, sleep=time.sleep):
|
||||
plan = LAST.get("plan")
|
||||
if not plan:
|
||||
return "NO PLAN YET"
|
||||
r = run_remote(cfg, rc["tracks_host"], COPY_SCRIPT % json.dumps(ableton_params(rc, plan)), timeout=60)
|
||||
if not r.get("source"):
|
||||
return "NO SET TO COPY"
|
||||
log.info("FIX tracks copy started to %s", ", ".join(r["started"]) or "nowhere (all there)")
|
||||
return True
|
||||
if not rc.get("transpose_locations"):
|
||||
r = run_remote(cfg, rc["tracks_host"], COPY_SCRIPT % json.dumps(ableton_params(rc, plan)), timeout=60)
|
||||
if not r.get("source"):
|
||||
return "NO SET TO COPY"
|
||||
log.info("FIX tracks copy started to %s", ", ".join(r["started"]) or "nowhere (all there)")
|
||||
return True
|
||||
# WS and SC in their own plans' keys (read now), AB as NA's: one job on the Tracks Mac, consolidating in Live.
|
||||
keys = {}
|
||||
for c in rc.get("ltc_campuses") or []:
|
||||
if c.get("short") in rc["transpose_locations"] and c.get("service_type"):
|
||||
cplan = pco_plan(rc, time.time(), c["service_type"], team=False)
|
||||
keys[c["short"]] = [{"title": it["title"], "key": it["key"]} for it in plan_songs(rc, cplan)]
|
||||
missing = [x for x in rc["transpose_locations"] if x not in keys]
|
||||
if missing:
|
||||
return "NO PLAN FOR " + " ".join(missing)
|
||||
params = dict(start_params(rc, [], "run"), **ableton_params(rc, plan))
|
||||
params.update(job="locations", site=rc.get("site_folder", ""), transpose=keys)
|
||||
r = run_remote(cfg, rc["tracks_host"], start_script(params), timeout=60)
|
||||
if r.get("busy"):
|
||||
return "START IS BUSY"
|
||||
log.info("FIX TRACKS OUT: the locations' sets (%s in their own keys)", ", ".join(sorted(keys)))
|
||||
return True if r.get("started") else "DID NOT START"
|
||||
if action == "mount_share":
|
||||
# The computer's keep-mounted agent (remote-access/mac-keep-mounted.sh) mounts it again, now.
|
||||
label = "org.waterschurch.keep-mounted." + rc.get("prop_bundle_share_agent", "location-assets")
|
||||
|
||||
Reference in New Issue
Block a user