From c5a77f43976e1e846b7aefffffdb93907796be33 Mon Sep 17 00:00:00 2001 From: Pauljd Date: Thu, 5 Nov 2026 11:37:19 +0000 Subject: [PATCH] Premiere eligibility: read-only check for Paul's corrected policy Release profile (recent, major theatrical studio, high-profile, not a streaming original or TV film), kept apart from Orbit status (aired, scheduled, never scheduled). Examples only; the first-on-Orbit premiere code on main is superseded and won't ship until the corrected policy is approved. Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/replays/premiere-profile.py | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 docs/replays/premiere-profile.py diff --git a/docs/replays/premiere-profile.py b/docs/replays/premiere-profile.py new file mode 100644 index 00000000..1bebe1f6 --- /dev/null +++ b/docs/replays/premiere-profile.py @@ -0,0 +1,60 @@ +# Read-only Premiere eligibility check (Paul's corrected policy, 5 Nov 2026): python3 premiere-profile.py +import json,sys,re,sqlite3,datetime,collections,glob +S=sys.argv[1]; SNAP=sys.argv[2] +sys.argv=['x',S,S+'/fixture'] +src=open('/home/pauljd/Documents/Codex/orbit-tv/docs/replays/stage-d-trial-7.py').read().split("if __name__=='__main__':")[0] +g={}; exec(src,g) +ev,score,B,c=g['ev'],g['score'],g['B'],g['c'] +TODAY=datetime.date(2026,11,5) +MAJOR=re.compile(r"Warner Bros|DC Studios|Universal Pictures|Paramount Pictures|Walt Disney Pictures|Marvel Studios|Lucasfilm|Pixar|20th Century|Columbia Pictures|Sony Pictures|Legendary|Lionsgate|New Line|DreamWorks|Amblin|Blumhouse|Metro-Goldwyn-Mayer|Illumination|Skydance|A24|NEON|Focus Features|Searchlight|TriStar|Screen Gems|Village Roadshow|Working Title|StudioCanal|Toho",re.I) +STREAMER=re.compile(r"\bNetflix\b|Amazon MGM|Amazon Studios|Apple Studios|Apple Original|Hulu|Peacock|Paramount\+|Disney\+|Max Original|Hallmark|Lifetime|Great American",re.I) +cols={x['name']:set(x['members']) for x in map(json.loads,open(f'{S}/collections-0.jsonl'))} +TREND=cols['Trending Movies']|cols['Trakt Trending']|cols['IMDB Top 250 Movies']|cols['Letterboxd Top 500'] +# Orbit status: scheduled-not-aired from plans; aired = booked and not only in future +now=int(datetime.datetime(2026,11,5,11,30,tzinfo=datetime.timezone.utc).timestamp()*1000) +future=set(); past=set() +for f in glob.glob(f'{SNAP}/schedule-*.json'): + for e in json.load(open(f))['entries']: + (future if e['s'] and e['a']>now else past).add(e.get('i') or '') +booked=set(json.load(open(f'{SNAP}/booked-0.json'))['ids']) +def status(i): + if i in future and i not in past: return 'scheduled, not yet aired' + if i in booked or i in past: return 'aired on Orbit' + return 'never scheduled' +rows=c.execute("select id,title,year,genres,studios,premiere,rating,runtime_ms from items where type='Movie' and premiere>='1970-01-01'").fetchall() +out=[] +STREAMLIST=set().union(*[cols[n] for n in cols if n in ('Netflix','Prime','Apple TV','Hulu','Peacock','Max','Disney+','Paramount+',"Netflix Top 10's","Prime Top 10's","Apple TV+ Top 10's")]) +for i,t,y,gen,stu,prem,rat,rt in rows: + r=ev.get(i) + d=prem[:10] + try: age=(TODAY-datetime.date.fromisoformat(d)).days + except: continue + if age<0: continue + genres=set((gen or '').split('|')) + reasons=[]; ok=True + if age>365: ok=False; reasons.append('older catalogue film (over 12 months)') + if 'TV Movie' in genres: ok=False; reasons.append('made for TV') + if 'Documentary' in genres: ok=False; reasons.append('documentary') + major=MAJOR.search(stu or ''); streamer=STREAMER.search(stu or '') + if (rt or 0)<75*60000: ok=False; reasons.append('under 75 minutes') + ask=[] + if streamer and not major: ok=False; reasons.append('streaming original ('+streamer.group(0)+')') + elif not major: + # The library's studio lists are often incomplete (Street Fighter lists only CAPCOM): an event film with a decent rating is asked about, not ruled out. + if r and score(r,'301')[0]>=.45 and (r.get('community') or 0)>=6: ask.append('event film, but no major studio in the library data') + else: ok=False; reasons.append('no major theatrical studio') + elif streamer: ask.append('a streamer ('+streamer.group(0)+') among its studios') + if major and i in STREAMLIST and age<=365: ask.append('already on a streaming service list, so theatrical release unconfirmed') + high=i in TREND or (r and (r.get('community') or 0)>=6.5) + if ok and not high: ask.append('not trending and no rating of 6.5 or more') + homes=[] + if r: + sc=sorted(((score(r,ch)[0],B[ch]['name']) for ch in B if ch!='301'),reverse=True) + homes=[n for s,n in sc[:1] if s>=.35] + prem_fit=score(r,'301')[0] + else: prem_fit=None + verdict='qualifies' if ok and not ask else ('needs your eye' if ok else 'does not qualify') + out.append(dict(verdict=verdict,ask=ask,id=i,title=t,year=y,date=d,studio=(major.group(0) if major else (stu or '').split('|')[0])[:30],eligible=ok,why=reasons,home=homes[0] if homes else None, + stays=bool(ok and prem_fit is not None and prem_fit>=.45),trend=i in TREND,community=(r or {}).get('community'),status=status(i),read=r is not None)) +json.dump(out,open(f'{S}/prem/profile.json','w'),indent=0) +print(len(out),collections.Counter(o['verdict'] for o in out),collections.Counter(o['status'] for o in out))