Files
OrbitTv/docs/replays/editorial-categories.py
T
pauljdandClaude Opus 5.5 f0804b6469
pauljd/davidson-ci: Davidson CI / quality (push) Failing after 2m15s
pauljd/davidson-ci: Davidson CI / ai-review (push) Failing after 1m21s
Editorial audit: per-category airtime figures and per-block tallies (read-only)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-03 23:29:32 +00:00

43 lines
2.4 KiB
Python

import json, re, sys, glob, os
D='/home/pauljd/Documents/Codex/orbit-tv/docs/channels'
J=json.load(open('/tmp/claude-1000/-home-pauljd-Projects/c539a8ea-4816-4f5b-8d2a-3efd663b12ac/scratchpad/replay/schedule-audit.json'))
def norm(t):
t=t.lower().replace('&','and')
t=re.sub(r"\(\d{4}\)","",t); t=re.sub(r"[^a-z0-9 ]+"," ",t)
t=re.sub(r"\b(the|a|an)\b"," ",t)
return ' '.join(t.split())
files={}
for f in glob.glob(D+'/*.md'):
m=re.search(r'\((\d{3})\)', open(f).readline())
if m: files[m.group(1)]=f
out={}
for num,ch in J.items():
f=files.get(num); txt=open(f).read() if f else ''
secs=re.findall(r'^\*\*([^*]+?):?\*\*:?\s*(.*)$', txt, re.M)
pool={p['title']:p for p in ch['pool']}
steady=ch['steady']; total=sum(v['minutes'] for v in steady.values()) or 1
assign={}
for label,body in secs:
lab=label.strip().rstrip(':')
if lab.lower().startswith(('status','identity','history','order','new arrivals','crossover','catalogue','known limit','rest period','built in','future artwork','to measure','precedence','new suggestions','band of brothers','long episodes','thin copies','not added','the old','presentation','not built','possible crossover','library','0.87','time of day')): continue
nb=' '+norm(body)+' '
for t in pool:
if t in assign: continue
k=norm(t)
if k and (' '+k+' ') in nb: assign[t]=lab
cats={}
for t,p in pool.items():
c=assign.get(t,'(not in brief)')
d=cats.setdefault(c,{'titles':0,'aired':0,'minutes':0,'never':[], 'files':0})
d['titles']+=1; d['files']+=p['files']
m=steady.get(t,{}).get('minutes',0)
d['minutes']+=m
if m: d['aired']+=1
else: d['never'].append(t)
# brief titles not in pool (approx): split by commas on core/supporting/surprises lines
print(f"\n### {num} {ch['name']} (pool {len(pool)}, film={ch['film']}, finishTogether={ch['finishTogether']}, committedReasons={ch['committedReasons'][:4]})")
for c,d in sorted(cats.items(), key=lambda x:-x[1]['minutes']):
print(f" {c[:40]:40s} titles {d['titles']:3d} aired {d['aired']:3d} share {100*d['minutes']//total:3d}% files {d['files']:5d} never: {', '.join(d['never'][:8])}{' +'+str(len(d['never'])-8) if len(d['never'])>8 else ''}")
top=sorted(steady.items(), key=lambda x:-x[1]['minutes'])[:6]
print(' top:', '; '.join(f"{t[:28]} {100*v['minutes']//total}% ({assign.get(t,'-')[:10]})" for t,v in top))