Skip to content

Commit 0717b17

Browse files
committed
ci: add corrected strict content patch orchestrator
1 parent 200e179 commit 0717b17

1 file changed

Lines changed: 149 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#!/usr/bin/env python3
2+
from __future__ import annotations
3+
4+
import importlib.util
5+
from pathlib import Path
6+
7+
ROOT = Path(__file__).resolve().parents[1]
8+
BASE_PATH = ROOT / "scripts" / "tmp_apply_strict_content_fix.py"
9+
10+
spec = importlib.util.spec_from_file_location("strict_fix_base", BASE_PATH)
11+
if spec is None or spec.loader is None:
12+
raise RuntimeError("cannot load base strict fix patcher")
13+
base = importlib.util.module_from_spec(spec)
14+
spec.loader.exec_module(base)
15+
16+
17+
def patch_shared_identity() -> None:
18+
path = "scripts/nuvio_client_lab.cjs"
19+
old = """ const metadataLabel = String(stream?.title || stream?.description || stream?.filename || stream?.name || '').trim();
20+
const mediaFilename = humanMediaFilename(stream?.url);
21+
const label = [metadataLabel, mediaFilename].filter(Boolean).join(' ');
22+
"""
23+
new = """ const metadataParts = [stream?.title, stream?.description, stream?.filename]
24+
.map((value) => String(value || '').trim())
25+
.filter(Boolean);
26+
if (!metadataParts.length && stream?.name) metadataParts.push(String(stream.name).trim());
27+
const metadataLabel = metadataParts.join(' ');
28+
const mediaFilename = humanMediaFilename(stream?.url);
29+
const label = [metadataLabel, mediaFilename].filter(Boolean).join(' ');
30+
"""
31+
base.replace_once(path, old, new)
32+
33+
old = """ const episodeOnly = /(?:^|\\D)(?:episode|ep)\\s*0*(\\d{1,4})(?:\\D|$)/i.exec(label);
34+
if (mediaType === 'movie' && seasonEpisode) return { status: 'contradiction', reason: 'movie_row_is_episode' };
35+
if (seasonEpisode && (mediaType === 'tv' || mediaType === 'anime')) {
36+
"""
37+
new = """ const episodeOnly = /(?:^|\\D)(?:episode|ep)\\s*0*(\\d{1,4})(?:\\D|$)/i.exec(label);
38+
const providerTokens = new Set(identityTokens(stream?.name || stream?.provider || ''));
39+
const genericIdentityTokens = new Set([
40+
'unknown', 'inconnue', 'inconnu', 'source', 'stream', 'streaming', 'player', 'lecteur',
41+
'audio', 'dual', 'multi', 'truefrench', 'french', 'vostfr', 'vf', 'vo', 'fr', 'en',
42+
'hd', 'fullhd', 'uhd', '4k', '2160p', '1440p', '1080p', '720p', '480p', '360p',
43+
'hls', 'dash', 'm3u8', 'mp4', 'web', 'webrip', 'webdl', 'bluray', 'brrip', 'hdr', 'dv',
44+
]);
45+
const contentTokens = (value) => identityTokens(value).filter((token) => !providerTokens.has(token) && !genericIdentityTokens.has(token));
46+
const strongIdentityLabels = [stream?.title, stream?.filename, mediaFilename]
47+
.map((value) => String(value || '').trim())
48+
.filter(Boolean);
49+
for (const strongLabel of strongIdentityLabels) {
50+
const strongTokens = contentTokens(strongLabel);
51+
if (strongTokens.length >= 2 && expectedTokens.size && !strongTokens.some((token) => expectedTokens.has(token))) {
52+
return { status: 'contradiction', reason: mediaFilename && strongLabel === mediaFilename ? 'media_filename_title_mismatch' : 'strong_title_mismatch' };
53+
}
54+
}
55+
if (mediaType === 'movie' && seasonEpisode) return { status: 'contradiction', reason: 'movie_row_is_episode' };
56+
if (seasonEpisode && (mediaType === 'tv' || mediaType === 'anime')) {
57+
"""
58+
base.replace_once(path, old, new)
59+
60+
old = """ if (normalized && forbiddenAliases.some((alias) => normalized.includes(alias))) return { status: 'contradiction', reason: 'forbidden_title_alias' };
61+
if (normalized && expected.some((alias) => normalized.includes(alias))) return { status: 'match', reason: 'expected_title_alias' };
62+
const providerTokens = new Set(identityTokens(stream?.name || stream?.provider || ''));
63+
const rowTokens = identityTokens(label).filter((token) => !providerTokens.has(token));
64+
"""
65+
new = """ if (normalized && forbiddenAliases.some((alias) => normalized.includes(alias))) return { status: 'contradiction', reason: 'forbidden_title_alias' };
66+
if (normalized && expected.some((alias) => normalized.includes(alias))) return { status: 'match', reason: 'expected_title_alias' };
67+
const rowTokens = contentTokens(label);
68+
"""
69+
base.replace_once(path, old, new)
70+
71+
72+
def strict_probe_gate(path: str) -> None:
73+
base.replace_once(
74+
path,
75+
'"ok": bool(parsed and int(parsed.get("playable_stream_count") or 0) > 0),',
76+
'"ok": bool(parsed and parsed.get("ok") and int(parsed.get("content_verified_count") or 0) > 0 and int(parsed.get("content_verified_count") or 0) == int(parsed.get("playable_stream_count") or 0) and int(parsed.get("identity_contradiction_count") or 0) == 0),',
77+
)
78+
79+
80+
def patch_provenance_preserve(path: str, variable: str) -> None:
81+
base.replace_once(path, ' "activation_eligible": True,\n', f' "activation_eligible": bool({variable}.get("activation_eligible", False)),\n')
82+
if variable == "current" and path == "scripts/publish_desktop_runtime_compat.py":
83+
base.replace_once(path, ' "strict_activation_eligible": bool(current.get("strict_activation_eligible", True)),\n', ' "strict_activation_eligible": bool(current.get("strict_activation_eligible", False)),\n')
84+
else:
85+
base.replace_once(path, ' "strict_activation_eligible": True,\n', f' "strict_activation_eligible": bool({variable}.get("strict_activation_eligible", False)),\n')
86+
base.replace_once(path, ' "runtime_evidence_eligible": True,\n', f' "runtime_evidence_eligible": bool({variable}.get("runtime_evidence_eligible", False)),\n')
87+
base.replace_once(path, ' "activation_blockers": [],\n', f' "activation_blockers": list({variable}.get("activation_blockers") or []),\n')
88+
89+
90+
def patch_publishers() -> None:
91+
global_path = "scripts/promote_global_nuvio_tv_candidates.py"
92+
strict_probe_gate(global_path)
93+
old = """ count = int(value.get("playable_stream_count") or 0)
94+
return (1 if count else 0, count)
95+
"""
96+
new = """ playable = int(value.get("playable_stream_count") or 0)
97+
verified = int(value.get("content_verified_count") or value.get("identity_verified_count") or 0)
98+
contradictions = int(value.get("identity_contradiction_count") or 0)
99+
strict = playable > 0 and verified == playable and contradictions == 0
100+
return (1 if strict else 0, verified if strict else 0)
101+
"""
102+
base.replace_once(global_path, old, new)
103+
base.preserve_enabled(global_path)
104+
patch_provenance_preserve(global_path, "row")
105+
106+
target_path = "scripts/promote_target_media_v3.py"
107+
strict_probe_gate(target_path)
108+
old = """ result = value.get("result") or {}
109+
count = int(result.get("playable_stream_count") or 0)
110+
return (1 if count else 0, count)
111+
"""
112+
new = """ result = value.get("result") or {}
113+
playable = int(result.get("playable_stream_count") or 0)
114+
verified = int(result.get("content_verified_count") or result.get("identity_verified_count") or 0)
115+
contradictions = int(result.get("identity_contradiction_count") or 0)
116+
strict = playable > 0 and verified == playable and contradictions == 0
117+
return (1 if strict else 0, verified if strict else 0)
118+
"""
119+
base.replace_once(target_path, old, new)
120+
base.preserve_enabled(target_path)
121+
patch_provenance_preserve(target_path, "current")
122+
123+
compat_path = "scripts/publish_nuvio_tv_compat_v2.py"
124+
base.replace_once(compat_path, ' "category": "movie",\n}', ' "category": "movie",\n "expectedDurationMinutes": 169,\n}')
125+
base.replace_once(
126+
compat_path,
127+
'"ok": bool(parsed and parsed.get("ok") and int(parsed.get("playable_stream_count") or 0) > 0),',
128+
'"ok": bool(parsed and parsed.get("ok") and int(parsed.get("content_verified_count") or 0) > 0 and int(parsed.get("content_verified_count") or 0) == int(parsed.get("playable_stream_count") or 0) and int(parsed.get("identity_contradiction_count") or 0) == 0),',
129+
)
130+
base.preserve_enabled(compat_path)
131+
patch_provenance_preserve(compat_path, "row")
132+
133+
desktop_path = "scripts/publish_desktop_runtime_compat.py"
134+
base.preserve_enabled(desktop_path)
135+
patch_provenance_preserve(desktop_path, "current")
136+
137+
138+
def main() -> None:
139+
patch_shared_identity()
140+
base.patch_tv_probe()
141+
patch_publishers()
142+
base.patch_audit()
143+
base.patch_tests()
144+
base.remove_obsolete_bypasses()
145+
print("strict content promotion patch v2 applied")
146+
147+
148+
if __name__ == "__main__":
149+
main()

0 commit comments

Comments
 (0)