diff --git a/readiness.py b/readiness.py index 10c1f09..f0bf9a2 100644 --- a/readiness.py +++ b/readiness.py @@ -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): diff --git a/tests/test_readiness.py b/tests/test_readiness.py index e53db96..8f1f4c2 100644 --- a/tests/test_readiness.py +++ b/tests/test_readiness.py @@ -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 = []