Other campuses' LTC: match against North Attleboro's plan order, not only the songs with timecode

With the weekend's set not on Tracks yet, every campus song looked out of order. The campuses now
pair with the home plan itself; a song the home set has no timecode for yet is matched but neither
faulted nor written, and the campuses are not looked at at all until the home set gives some timecode.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 10:30:43 -04:00
co-authored by Claude Fable 5.1
parent 3ccaea0076
commit f1cd42a437
2 changed files with 27 additions and 11 deletions
+14 -8
View File
@@ -655,12 +655,16 @@ def match_in_order(na_songs, campus_songs):
return pairs, skipped
def campus_ltc(rc, na_songs, campus, plan):
"""One other campus's plan against the home timecode: its songs in home order, each with the
timecode it should carry and what its LTC note says now."""
def campus_ltc(rc, na_plan, na_songs, campus, plan):
"""One other campus's plan against the home timecode: its songs in the home plan's order, each
with the timecode the home set gives that song (None while the set has none) and what its LTC
note says now."""
note = rc.get("ltc_note", "LTC")
pairs, skipped = match_in_order(na_songs, plan_songs(rc, plan))
songs = [{"item": it, "title": it["title"], "tracks": s["tracks"], "pco": (it["notes"].get(note) or "").strip()} for it, s in pairs]
pairs, skipped = match_in_order(plan_songs(rc, na_plan), plan_songs(rc, plan))
songs = []
for it, home in pairs:
tc = next((s["tracks"] for s in na_songs if same(home["title"], s["title"])), None)
songs.append({"item": it, "title": it["title"], "tracks": tc, "pco": (it["notes"].get(note) or "").strip()})
return {"name": campus.get("name") or campus.get("short") or str(campus.get("service_type")), "short": campus.get("short") or (campus.get("name") or "?")[:2].upper(),
"service_type": str(campus.get("service_type")), "plan_id": plan["id"], "dates": plan.get("dates", ""), "songs": songs, "skipped": skipped}
@@ -669,6 +673,8 @@ def eval_campus_ltc(rc, result, line):
"""The other campus's notes must say the home timecode for every matched song."""
tag = result["short"]
for s in result["songs"]:
if s["tracks"] is None: # the home set has no timecode for it yet: the home line says so
continue
if not s["pco"]:
line.fault(ERR, "%s NO LTC %s" % (tag, short(s["title"], 12)), "%s: %s has no %s note; the tracks start it at %s" % (
result["name"], s["title"], rc.get("ltc_note", "LTC"), s["tracks"]))
@@ -1070,12 +1076,12 @@ def look(cfg, now=None, data_dir=None, sources=None):
LAST["ltc"] = [dict(s, item={"id": s["item"]["id"], "note_ids": s["item"]["note_ids"]}) for s in na_songs]
LAST["service_type"], LAST["plan_id"] = plan.get("service_type"), plan["id"]
others = []
for campus in rc.get("ltc_campuses") or []:
for campus in (rc.get("ltc_campuses") or []) if na_songs else []: # nothing to give the others yet
if not campus.get("service_type"):
continue
try:
cplan = src["pco_campus"](campus["service_type"])
res = campus_ltc(rc, na_songs, campus, 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"]]))
except Exception as e: # noqa: BLE001 - one campus's plan down must not hide the home one
@@ -1140,7 +1146,7 @@ class Poller(threading.Thread):
def write_ltc(rc, songs, service_type, plan_id):
"""Write the tracks' timecode into PCO's LTC note of every song where it is missing or different."""
todo = [s for s in songs if s["pco"] != s["tracks"]]
todo = [s for s in songs if s["tracks"] and s["pco"] != s["tracks"]]
if not todo:
return True
if not (service_type and plan_id):
+13 -3
View File
@@ -568,7 +568,7 @@ class TestOtherCampuses(unittest.TestCase):
self.assertGreaterEqual(len(titles), 3)
# the campus plays song 2 first, then 1, then 3: song 1 breaks the order and is skipped; a song NA does not play is skipped too
cp = self.campus_plan([titles[1], titles[0], titles[2], "Something Else"])
res = rd.campus_ltc(RC, na, self.CAMPUS, cp)
res = rd.campus_ltc(RC, plan(), na, self.CAMPUS, cp)
self.assertEqual([s["title"] for s in res["songs"]], [titles[1], titles[2]])
self.assertEqual(res["skipped"], [titles[0], "Something Else"])
self.assertEqual(res["songs"][0]["tracks"], na[1]["tracks"])
@@ -576,12 +576,22 @@ class TestOtherCampuses(unittest.TestCase):
self.assertEqual([m for _, m, _ in line.faults], ["AB NO LTC " + rd.short(titles[1], 12), "AB NO LTC " + rd.short(titles[2], 12)])
self.assertTrue(any("left alone" in d for d in line.as_dict()["details"]))
right = self.campus_plan(titles, notes={t: {"LTC": s["tracks"]} for t, s in zip(titles, na)})
self.assertEqual(rd.eval_campus_ltc(RC, rd.campus_ltc(RC, na, self.CAMPUS, right), rd.Line()).faults, [])
self.assertEqual(rd.eval_campus_ltc(RC, rd.campus_ltc(RC, plan(), na, self.CAMPUS, right), rd.Line()).faults, [])
def test_a_song_without_home_timecode_is_matched_but_not_faulted_or_written(self):
"""The set is not on Tracks yet: the campus's songs are still in order, nothing is wrong at the campus, nothing is written."""
p = plan()
cp = self.campus_plan([it["title"] for it in rd.plan_songs(RC, p)])
res = rd.campus_ltc(RC, p, [], self.CAMPUS, cp)
self.assertEqual(res["skipped"], [])
self.assertTrue(res["songs"] and all(s["tracks"] is None for s in res["songs"]))
self.assertEqual(rd.eval_campus_ltc(RC, res, rd.Line()).faults, [])
self.assertIs(rd.write_ltc(RC, res["songs"], "1113969", "ab-1"), True)
def test_the_fix_writes_every_campus(self):
na = rd.song_ltc(RC, plan(), ableton())
cp = self.campus_plan([s["title"] for s in na])
res = rd.campus_ltc(RC, na, self.CAMPUS, cp)
res = rd.campus_ltc(RC, plan(), na, self.CAMPUS, cp)
rd.LAST["ltc"], rd.LAST["service_type"], rd.LAST["plan_id"] = na, "275974", "92013595"
rd.LAST["ltc_other"] = [res]
calls = []