import json, os, subprocess from datetime import datetime, timezone with open("/tmp/bulk_results.json") as f: results = json.load(f) now = datetime.now(timezone.utc).strftime("%d %b %Y, %H:%M UTC") total = len(results) by_status = {} for r in results: by_status.setdefault(r["status"], []).append(r) up_to_date = by_status.get("up_to_date", []) small_difference = by_status.get("small_difference", []) position_drift = by_status.get("position_drift", []) sig_mismatch = by_status.get("significant_mismatch", []) not_in_insights = by_status.get("not_in_insights", []) not_on_spotify = by_status.get("not_on_spotify", []) spotify_error = by_status.get("spotify_error", []) lines = [] # ── Header ──────────────────────────────────────────────────────────────────── lines.append(f"*Priority Playlist Status* — {now}") lines.append(f"_{total} playlists checked_") lines.append("") # ── Score card ──────────────────────────────────────────────────────────────── lines.append(f":white_check_mark: Up to date: *{len(up_to_date)}*") if position_drift: lines.append(f":warning: Position drift: *{len(position_drift)}*") if small_difference: lines.append(f":warning: Small difference (1–5 ISRCs): *{len(small_difference)}*") if sig_mismatch: lines.append(f":x: Significant mismatch (>5 ISRCs): *{len(sig_mismatch)}*") if not_in_insights: lines.append(f":x: Not in Insights: *{len(not_in_insights)}*") if not_on_spotify: lines.append(f":x: Not on Spotify (404): *{len(not_on_spotify)}*") if spotify_error: lines.append(f":question: Spotify error: *{len(spotify_error)}*") # ── Small differences ───────────────────────────────────────────────────────── if small_difference: lines.append("") lines.append(f":warning: *Small differences ({len(small_difference)})*") lines.append("_1–5 ISRC gap vs Insights — may be null-ISRC or unavailable tracks; requires investigation_") # Split into "missing only" (likely NMF ingestion lag) vs "missing + extra" (likely ISRC swap) missing_only = [r for r in small_difference if r["only_insights"] == 0] swapped = [r for r in small_difference if r["only_insights"] > 0] if missing_only: lines.append(f"*Missing from Insights only ({len(missing_only)}) — possible ingestion lag:*") for r in sorted(missing_only, key=lambda x: x["playlist_name"]): n = r["only_spotify"] lines.append(f"• {r['playlist_name']} — {n} track{'s' if n != 1 else ''} missing from Insights") if swapped: lines.append(f"*Missing + extra ({len(swapped)}) — possible ISRC swap or recent update:*") for r in sorted(swapped, key=lambda x: x["playlist_name"]): variants = len(r.get("possible_variants", [])) variant_note = f" ({variants} possible ISRC variant{'s' if variants != 1 else ''})" if variants else "" lines.append( f"• {r['playlist_name']} — " f"{r['only_spotify']} missing, {r['only_insights']} extra{variant_note}" ) # ── Significant mismatches ──────────────────────────────────────────────────── if sig_mismatch: lines.append("") lines.append(f":x: *Significant mismatches ({len(sig_mismatch)})*") for r in sorted(sig_mismatch, key=lambda x: x["playlist_name"]): lines.append( f" • {r['playlist_name']} — " f"{r['only_spotify']} missing from Insights, {r['only_insights']} extra" ) # ── Not in Insights ─────────────────────────────────────────────────────────── if not_in_insights: lines.append("") lines.append(f":x: *Not in Insights ({len(not_in_insights)})*") for r in sorted(not_in_insights, key=lambda x: x["playlist_name"]): lines.append(f"• {r['playlist_name']}") # ── Not on Spotify ──────────────────────────────────────────────────────────── if not_on_spotify: lines.append("") lines.append(f":x: *Not on Spotify — 404 ({len(not_on_spotify)})*") lines.append("_These playlists returned 404 and may have been deleted or made private._") for r in sorted(not_on_spotify, key=lambda x: x["playlist_name"]): lines.append(f"• {r['playlist_name']}") # ── Spotify errors ──────────────────────────────────────────────────────────── if spotify_error: lines.append("") lines.append(f":question: *Spotify errors ({len(spotify_error)})*") for r in sorted(spotify_error, key=lambda x: x["playlist_name"]): code = r.get("spotify_error_code", "?") lines.append(f"• {r['playlist_name']} (HTTP {code})") # ── Position drift ──────────────────────────────────────────────────────────── if position_drift: lines.append("") lines.append(f":warning: *Position drift ({len(position_drift)})*") lines.append("_ISRCs match but track order differs from Spotify._") for r in sorted(position_drift, key=lambda x: x["playlist_name"]): lines.append(f"• {r['playlist_name']} — {r['pos_mismatches']} position mismatch{'es' if r['pos_mismatches'] != 1 else ''}") lines.append("") lines.append("_Full report: ~/Downloads/priority_playlist_status_report.html_") summary = "\n".join(lines) print(summary) # Copy to clipboard try: subprocess.run(["pbcopy"], input=summary.encode(), check=True) print("\n✓ Copied to clipboard", flush=True) except Exception: pass # Also write to file as a fallback out = os.path.expanduser("~/Downloads/priority_playlist_slack_summary.txt") with open(out, "w") as f: f.write(summary) print(f"✓ Saved to {out}", flush=True)