Publish Armiger v3.0 (v3.0-gold-r5) clean-slate model cards and two headline charts
284d9ac verified Download zero_cue_plugin.py from NorviTech/armiger-ultra: direct link, hf CLI and curl.
- Browser
- Download file 40.8 kB
-
https://huggingface.co/NorviTech/armiger-ultra/resolve/main/zero_cue_plugin.py
- Command line
-
hf download hf://NorviTech/armiger-ultra/zero_cue_plugin.py
-
curl -L -o zero_cue_plugin.py https://huggingface.co/NorviTech/armiger-ultra/resolve/main/zero_cue_plugin.py
40.8 kB
| """Zero-Cue Catalog Lookup & Structural Disambiguation Plugin for Armiger & Armiger Ultra. | |
| Resolves bare-title ("zero-cue") torrent releases that omit explicit season/episode syntax | |
| (e.g. `Title (2024) [1080p].mkv`) and disambiguates multi-item media bundles, interactive | |
| software archives, and structured instructional materials before/after neural classification. | |
| Supports both zero-deserialization `ZCB3` `mmap` binary catalogs (`armiger.zero_cue_binary.ZCB3MmapCatalog`) | |
| and JSON catalog fallback (`validated_zero_cue_catalog.json`), plus schema-validated JSON | |
| rule/threshold overrides (`plugin_overrides["zero_cue"]`) from `calibration.json`. | |
| """ | |
| from __future__ import annotations | |
| from collections.abc import Mapping | |
| import hashlib | |
| import hmac | |
| import json | |
| import logging | |
| import pathlib | |
| import re | |
| import unicodedata | |
| from typing import Any | |
| logger = logging.getLogger(__name__) | |
| try: | |
| from armiger.zero_cue_binary import ZCB3_MAGIC, ZCB3MmapCatalog | |
| except ImportError: | |
| from zero_cue_binary import ZCB3_MAGIC, ZCB3MmapCatalog # type: ignore | |
| try: | |
| from armiger.calibration_and_dht import MAX_CUSTOM_REGEX_INPUT_CHARS, safe_regex_search | |
| except ImportError: | |
| try: | |
| from calibration_and_dht import MAX_CUSTOM_REGEX_INPUT_CHARS, safe_regex_search # type: ignore[no-redef] | |
| except ImportError: | |
| MAX_CUSTOM_REGEX_INPUT_CHARS = 512 | |
| def safe_regex_search(pattern: Any, text: str, **kwargs: Any) -> Any: | |
| if not pattern: | |
| return False | |
| return pattern.search(text[:MAX_CUSTOM_REGEX_INPUT_CHARS]) if hasattr(pattern, "search") else re.search(pattern, text[:MAX_CUSTOM_REGEX_INPUT_CHARS]) | |
| try: | |
| from armiger.audio_language_guard import detect_localized_foreign_title_stem, split_and_score_title_slug | |
| except ImportError: | |
| try: | |
| from audio_language_guard import detect_localized_foreign_title_stem, split_and_score_title_slug # type: ignore[no-redef] | |
| except ImportError: | |
| def detect_localized_foreign_title_stem(text: str) -> dict[str, Any]: | |
| return {"is_foreign_stem": False, "language": None} | |
| def split_and_score_title_slug(text: str) -> dict[str, Any]: | |
| return {"tokens": [], "is_foreign": False} | |
| CATS = [ | |
| "movie", "tv_show", "xxx", "music", "comic", | |
| "game", "audiobook", "software", "ebook", "course", "unknown", | |
| ] | |
| IDX_MOVIE = 0 | |
| IDX_TV = 1 | |
| IDX_XXX = 2 | |
| IDX_MUSIC = 3 | |
| IDX_COMIC = 4 | |
| IDX_GAME = 5 | |
| IDX_AUDIOBOOK = 6 | |
| IDX_SOFTWARE = 7 | |
| IDX_EBOOK = 8 | |
| IDX_COURSE = 9 | |
| EXPLICIT_TV_RE = re.compile( | |
| r"(?i)(?:\bS\d{1,2}E\d{1,3}\b|\bS\d{1,2}\s*-\s*S\d{1,2}\b|\bSeason\s*(?:0?[1-9]|[1-9]\d)\b|\bStagione\s*\d+\b|\bSaison\s*\d+\b|" | |
| r"\bTemporada\s*\d+\b|\bStaffel\s*\d+\b|\bComplete\s+Series\b|\bTV\s*Series\b|\bMini\s*Series\b|" | |
| r"\bEpisode\s+[1-9]\d*\b|\bEp\.?\s*[1-9]\d*\b|\bEpiz[oó]da\b|\bЭпизод\s*\d+\b|第[一二三四五六七八九十\d]+[季集]|【[^】]*日剧】|更新至\d+[期集]|\s-\s(?:SP|NCOP|NCED)\d*\b|\b\d{3}\s*\[(?:480p|720p|1080p|2160p)\]|" | |
| r"\b[1-9]\d{2,3}\s*\((?:WEBRip|WEB-DL|BDRip|DVDRip|1080p|720p|480p)\b|" | |
| r"\bFull[\s\._]Event\b|\bPPV\b|\b1-\d{2}\s*\+\s*OVA\b|\btemp\.\d+\.completa\b|" | |
| r"\b\d{2}\s*-\s*\d{2,3}\s+VOSTFR\b|\s-\s\d{2,3}(?:v\d)?\s*(?:\[|\(|\b1080p\b|\b720p\b))" | |
| ) | |
| EXPLICIT_MOVIE_PACK_RE = re.compile( | |
| r"(?i)(?:\bMovies?\s*\d{1,2}\s*[-~]\s*\d{1,2}\b|\bMovies?\s+Collection\b|\bTrilogy\b|\bQuadrilogy\b|\bTetralogy\b|" | |
| r"\bAnthology\b|\b\d+\s+Movies?\s+Pack\b|\[\d-\d\]\s*\[m?1080p\]\s*\[\d{4}-\d{4}\]|\bThe\s+Movie\b|" | |
| r"\(\s*Movies?\s*\)|\[\s*Movies?\s*\]|" | |
| r"\bMovie\s+-\s+00\b|\s-\s*Movie\s*(?:\[|\(|V\d)|\bMovie\s+\d{1,2}\s*-|\bMovie:\s|" | |
| r"\bGekijouban\b|\bFilm\s+Collection\b|\bIl\s+Film\b|\bLe\s+Film\b|\bDer\s+Film\b|\bKolekcja\b|" | |
| r"\bTheatrical\s+Cut\b|\bDirector'?s\s+Cut\b|\bExtra\s+Edition\b)" | |
| ) | |
| GAME_ARCHIVE_RE = re.compile( | |
| r"(?i)(?:\bNTSC-U\b|\bNTSC-J\b|\[linux-x86\]|\[linux-x64\]|\[win64\]|" | |
| r"\bInteractive\s+Fiction\b|\bGOG\s+Edition\b|\bLinux\s+Native\b|\((?:Europe|USA|Japan|World)\)\.(?:zip|7z|rar|iso|chd)\b|" | |
| r"supertux|super-tux-kart|org\.supertuxkart|\bfreeciv|\bopenttd|\b0ad[-_\b]|\bminetest|\bfreedoom|\bwesnoth|" | |
| r"\bsauerbraten|\bxonotic|\bopenarena|\bwarsow|\barx-libertatis|\bopenglad|\bcrispy-doom|\bflightgear|" | |
| r"\bendless-sky|\bmegaglest|\bastromenace|\bspeed-dreams|\btorcs\b|\bvdrift|\bstuntrally|\bredeclipse|" | |
| r"\bassaultcube|\bteeworlds|\bddnet\b|\bopenra\b|\bwz2100|\bwarzone2100|\bfheroes2|\bvcmi\b|\bopenmw|" | |
| r"\bopenxcom|\bcorsixth|\bsimutrans|\blincity|\bunknown-horizons|\bwidelands|\bhedgewars|\bpingus\b|" | |
| r"\bfrogatto|\bflare-game|\bvalyriatear|\bnaev\b|\boolite\b|\bpioneerspacesim|\bvegastrike|\burquan|\buqm\b|" | |
| r"segasoft|gremlin[\s\._-]+interactive|crosscountrycanada|petepilotti|\.levelset\.)" | |
| ) | |
| _SOUNDTRACK_AUDIO_EXCLUSION_RE = re.compile( | |
| r"(?i)(?:\b(?:ost|soundtrack|original[\s._-]*score|score|flac|mp3|cbr|vbr|320kbps|lossless|discography)\b)" | |
| ) | |
| ADULT_SITERIP_RE = re.compile( | |
| r"(?i)(?:\b(?:xxx|nsfw|18\+|adult[\s._-]+only)\b.*\b(?:1080p|720p|2160p|mp4|mkv|siterip)\b|" | |
| r"\bsiterip\b.*\b(?:xxx|18\+|adult|nsfw)\b)" | |
| ) | |
| EXPLICIT_COMIC_RE = re.compile( | |
| r"(?i)(?:\b(?:cbz|cbr|cb7|fumetti)\b|^bd[\.\s_-]+fr\b)" | |
| ) | |
| COURSE_BOOK_RE = re.compile( | |
| r"(?i)(?:\bTestbuch\b|\bKursbuch\b|\bArbeitsbuch\b|\bOpenCourseWare\b|\bVideo\s+Course\b|" | |
| r"\bData\s+Science\s+Course\b|\bLanguage\s+Course\b|\bFull\s+Tutorial\b|\bLecture\s+Series\b|\bStudy\s+Guide\b)" | |
| ) | |
| YEAR_RE = re.compile(r"(?<![\dA-Za-z])(?:19[2-9]\d|20[0-2]\d)(?![\dA-Za-z]|\s*[xX×]\s*\d)") | |
| NOISE_CUT_RE = re.compile( | |
| r"(?i)(?:\b2160p\b|\b1080p\b|\b720p\b|\b480p\b|\b576p\b|\b4k\b|\bbluray\b|\bblu-ray\b|\bweb-dl\b|\bwebdl\b|" | |
| r"\bwebrip\b|\bbdrip\b|\bdvdrip\b|\bdvd-remux\b|\bdvd\b|\bhdtv\b|\bremux\b|\bx264\b|\bx265\b|\bh264\b|" | |
| r"\bh265\b|\bhevc\b|\bav1\b|\bvostfr\b|\bmulti\b|\bdual[\s_-]*audio\b|\beng[\s_-]*sub|\bsub[\s_-]*ita|" | |
| r"\bita\b|\bfrench\b|\bgerman\b|\bspanish\b|\brepack\b|\bproper\b|\bremaster\b)" | |
| ) | |
| def _match_safe_tokens(text: str, tokens: list[str] | tuple[str, ...]) -> bool: | |
| if not tokens or not text: | |
| return False | |
| lowered = text.lower() | |
| for tok in tokens: | |
| t = str(tok).strip().lower() | |
| if not t: | |
| continue | |
| pat = r"(?<![a-z0-9])" + re.escape(t) + r"(?![a-z0-9])" | |
| if re.search(pat, lowered): | |
| return True | |
| return False | |
| def hash_catalog_key(key: str, hmac_key: bytes | str | None = None) -> str: | |
| """Compute deterministic 64-bit BLAKE2b / explicit-HMAC digest for a catalog lookup key. | |
| Offline catalog lookup IDs always use the canonical unkeyed BLAKE2b-64 digest | |
| (`person=b"armiger-zc-v2"`) unless an explicit `hmac_key` is passed by the caller; | |
| environment variables never implicitly alter offline catalog lookup IDs. | |
| """ | |
| if hmac_key is not None and hmac_key != b"" and hmac_key != "": | |
| k_bytes = hmac_key.encode("utf-8") if isinstance(hmac_key, str) else bytes(hmac_key) | |
| return hmac.new(k_bytes, key.encode("utf-8"), hashlib.sha256).hexdigest()[:16] | |
| return hashlib.blake2b(key.encode("utf-8"), digest_size=8, person=b"armiger-zc-v2").hexdigest() | |
| def norm_title(s: str) -> str: | |
| """Normalize a title string to NFKC lowercase alphanumeric tokens.""" | |
| if not s: | |
| return "" | |
| s = unicodedata.normalize("NFKC", s).casefold() | |
| s = re.sub(r"[\W_]+", " ", s, flags=re.UNICODE) | |
| return " ".join(s.split()) | |
| _AUTH_EPISODE_CUT_RE = re.compile( | |
| r"(?i)(?:\bS\d{1,2}(?:E\d{1,3}|\b)|\bSeason[\s._-]*\d+\b|\bComplete[\s._-]*Series\b|\s+-\s+\d{1,3}(?:\b|\s*[\[\(]))" | |
| ) | |
| def extract_authoritative_title(raw_name: str) -> tuple[str, int | None]: | |
| """Extract the authoritative clean title and release year without relaxed sequel-number stripping.""" | |
| s = raw_name.strip() | |
| if not s: | |
| return "", None | |
| s = re.sub(r"\.(?:mkv|mp4|avi|m2ts|ts|iso|zip|rar|tar\.bz2|epub|pdf|mp3|flac)$", "", s, flags=re.I) | |
| s_no_lead = re.sub(r"^(?:\s*[\[\(][^\]\)]{1,45}[\]\)]\s*|[_\s]+)+", "", s) | |
| base = s_no_lead if len(norm_title(s_no_lead)) >= 2 else s | |
| year_matches = [m for m in YEAR_RE.finditer(base) if m.start() >= 2] | |
| year = int(year_matches[0].group(0)) if year_matches else None | |
| cut_pos = len(base) | |
| if year_matches: | |
| cut_pos = min(cut_pos, year_matches[0].start()) | |
| m_ns = NOISE_CUT_RE.search(base) | |
| if m_ns and m_ns.start() >= 2: | |
| cut_pos = min(cut_pos, m_ns.start()) | |
| m_ep = _AUTH_EPISODE_CUT_RE.search(base) | |
| if m_ep and m_ep.start() >= 2: | |
| cut_pos = min(cut_pos, m_ep.start()) | |
| stem = base[:cut_pos] | |
| stem = re.split(r"[\[\(\|]", stem)[0] | |
| clean = norm_title(stem) | |
| if not clean: | |
| clean = norm_title(re.split(r"[\[\(\|]", base)[0]) | |
| return clean, year | |
| def parse_clean_candidates(raw_name: str, extra_spans: list[str] | None = None) -> tuple[list[tuple[str, int | None]], int | None]: | |
| """Extract ordered candidate `(clean_title, year)` pairs sorted longest/most-specific first.""" | |
| s = raw_name.strip() | |
| s = re.sub(r"\.(?:mkv|mp4|avi|m2ts|ts|iso|zip|rar|tar\.bz2|epub|pdf|mp3|flac)$", "", s, flags=re.I) | |
| s_no_lead = re.sub(r"^(?:\s*[\[\(][^\]\)]{1,45}[\]\)]\s*|[_\s]+)+", "", s) | |
| years = [int(m.group(0)) for m in YEAR_RE.finditer(s_no_lead)] | |
| year = years[0] if years else None | |
| raw_cands: list[tuple[str, int | None]] = [] | |
| def add(ct: str, cy: int | None) -> None: | |
| ct = ct.strip() | |
| if len(ct) >= 4: | |
| raw_cands.append((ct, cy)) | |
| for base in (s_no_lead, s): | |
| m_yr = YEAR_RE.search(base) | |
| if m_yr and m_yr.start() >= 3: | |
| prefix = base[:m_yr.start()] | |
| c1 = norm_title(prefix) | |
| add(c1, int(m_yr.group(0))) | |
| add(c1, None) | |
| for subp in re.split(r"(?i)\s+-\s+|\s+aka\s+", prefix): | |
| cs = norm_title(subp) | |
| if len(cs) >= 5: | |
| add(cs, int(m_yr.group(0))) | |
| m_ns = NOISE_CUT_RE.search(base) | |
| if m_ns and m_ns.start() >= 3: | |
| c2 = norm_title(base[:m_ns.start()]) | |
| add(c2, year) | |
| add(c2, None) | |
| c3_raw = re.split(r"[\[\(\|]", base)[0] | |
| c3 = norm_title(c3_raw) | |
| add(c3, year) | |
| add(c3, None) | |
| c4 = norm_title(re.sub(r"(?i)(?:\b(?:the\s+movie|movie|ova|oav|special)\b|\s+-\s+\d{1,3}|\s+\d{1,3})\s*$", "", c3_raw)) | |
| add(c4, year) | |
| add(c4, None) | |
| for grp in re.findall(r"\(([^()]{5,80})\)", s_no_lead) + s_no_lead.split("|")[1:]: | |
| if not NOISE_CUT_RE.search(grp) and not YEAR_RE.fullmatch(grp.strip()): | |
| for part in re.split(r"[/||]", grp): | |
| ca = norm_title(part) | |
| if len(ca) >= 6: | |
| add(ca, year) | |
| add(ca, None) | |
| if extra_spans: | |
| for sp in sorted(extra_spans, key=lambda x: len(x or ""), reverse=True): | |
| nsp = norm_title(sp) | |
| if len(nsp) >= 5: | |
| add(nsp, year) | |
| add(nsp, None) | |
| slug_res = split_and_score_title_slug(s_no_lead) | |
| if slug_res["found_concat_slug"] and len(slug_res["segmented_words"]) >= 2: | |
| segmented_title = norm_title(" ".join(slug_res["segmented_words"])) | |
| if len(segmented_title) >= 6: | |
| add(segmented_title, year) | |
| add(segmented_title, None) | |
| raw_cands.sort(key=lambda item: (item[1] is not None, len(item[0])), reverse=True) | |
| ordered: list[tuple[str, int | None]] = [] | |
| seen: set[tuple[str, int | None]] = set() | |
| for item in raw_cands: | |
| if item not in seen: | |
| seen.add(item) | |
| ordered.append(item) | |
| return ordered, year | |
| def lookup_zero_cue_catalog( | |
| raw_name: str, | |
| catalog: Mapping[str, Any], | |
| is_anime: bool = True, | |
| extra_spans: list[str] | None = None, | |
| ) -> tuple[str | None, str | None]: | |
| """Query the local validated catalog (either `ZCB3MmapCatalog` or Python `dict`) in strict specificity order: | |
| 1. `(title, year)` exact match in `title_year_map` (472,022 entries) | |
| 2. `title` match in `anime_map` when `is_anime=True` and stem length >= 8 (257,019 entries) | |
| 3. `title` match in unambiguous `title_only_map` (200,367 entries) | |
| """ | |
| cands, yr = parse_clean_candidates(raw_name, extra_spans=extra_spans) | |
| title_year_map = catalog.get("title_year_map", {}) | |
| anime_map = catalog.get("anime_map", {}) | |
| title_only_map = catalog.get("title_only_map", {}) | |
| for ct, cy in cands: | |
| if cy is not None and len(ct) >= 4: | |
| key = f"{ct}|{cy}" | |
| hkey = hash_catalog_key(key) | |
| hit = title_year_map.get(hkey) | |
| if hit is not None: | |
| return hit, "title_year" | |
| if isinstance(title_year_map, dict) and key in title_year_map: | |
| return title_year_map[key], "title_year" | |
| if is_anime: | |
| for ct, _ in cands: | |
| if len(ct) >= 8: | |
| hct = hash_catalog_key(ct) | |
| hit = anime_map.get(hct) | |
| if hit is not None: | |
| return hit, "anime_catalog" | |
| if isinstance(anime_map, dict) and ct in anime_map: | |
| return anime_map[ct], "anime_catalog" | |
| for ct, _ in cands: | |
| if len(ct) >= 14: | |
| hct = hash_catalog_key(ct) | |
| hit = title_only_map.get(hct) | |
| if hit is not None: | |
| return hit, "title_only" | |
| if isinstance(title_only_map, dict) and ct in title_only_map: | |
| return title_only_map[ct], "title_only" | |
| if cands and yr is None: | |
| ct0 = cands[0][0] | |
| if len(ct0) >= 7: | |
| hct0 = hash_catalog_key(ct0) | |
| hit = title_only_map.get(hct0) | |
| if hit is not None: | |
| return hit, "title_only" | |
| if isinstance(title_only_map, dict) and ct0 in title_only_map: | |
| return title_only_map[ct0], "title_only" | |
| return None, None | |
| _AUDIOBOOK_FILE_TREE_RE = re.compile( | |
| r"(?i)(?:_librivox\b|(?:^|[/\\\s._\-\[\(])chapter[\s._-]*\d{1,3}(?:[\s._-]+[a-z0-9_]+)?\.(?:mp3|m4b|ogg|flac|aac)\b|(?:^|[/\\\s._\-\[\(])part[\s._-]*\d{1,2}(?:[\s._-]+[a-z0-9_]+)?\.(?:m4b|mp3)\b|(?:^|[/\\\s._\-\[\(])\d{2,3}[\s._-]+chapter[\s._-]*\d+)" | |
| ) | |
| _COURSE_FILE_TREE_RE = re.compile( | |
| r"(?i)(?:(?:^|[/\\\s._\-\[\(])(?:module|lesson|lecture|section|week|unit)[\s._-]*\d{1,2}(?=$|[/\\\s._\-\]\)]).*\.(?:mp4|mkv|pdf|zip|srt|html)\b|(?:^|[/\\\s._\-\[\(])\d{1,2}[\s._-]+\d{1,2}[\s._-]+[a-z].*\.(?:mp4|srt)\b)" | |
| ) | |
| _COMIC_ALLOWED_COMPANION_EXTS = frozenset({ | |
| "cbr", "cbz", "cb7", "cbt", "cba", "pdf", "epub", "mobi", "azw3", | |
| "jpg", "jpeg", "png", "webp", "gif", "txt", "nfo", "sfv", "md5", "xml", "json", | |
| }) | |
| _AUDIOBOOK_ALLOWED_COMPANION_EXTS = _COMIC_ALLOWED_COMPANION_EXTS | frozenset({ | |
| "m4b", "mp3", "ogg", "flac", "m4a", "opus", "aac", "wav", "cue", "m3u", "pls", "log", | |
| }) | |
| _COURSE_ALLOWED_COMPANION_EXTS = _AUDIOBOOK_ALLOWED_COMPANION_EXTS | frozenset({ | |
| "mp4", "mkv", "avi", "mov", "webm", "ts", "srt", "vtt", "ass", "ssa", "sub", "html", "htm", "md", "csv", "py", "ipynb", "js", "css", "sql", "sh", "zip", "rar", "7z", | |
| }) | |
| def _is_primary_book_payload( | |
| raw_name: str, file_exts: set[str], target_exts: set[str], has_tv_cue: bool, has_movie_cue: bool, | |
| allowed_exts: frozenset[str] = _COMIC_ALLOWED_COMPANION_EXTS, | |
| ) -> bool: | |
| return bool( | |
| (file_exts & target_exts) and file_exts <= allowed_exts and not GAME_ARCHIVE_RE.search(raw_name) | |
| and not _V3_GAME_STRONG_RE.search(raw_name) and not _V3_SOFTWARE_RE.search(raw_name) | |
| and not has_tv_cue and not has_movie_cue | |
| ) | |
| def _extract_file_surface(files: list[Any] | tuple[Any, ...] | None) -> tuple[str, set[str], int]: | |
| """Return `(joined_paths_sample, lowercase_extensions_set, file_count)` from a torrent file list.""" | |
| if not files: | |
| return "", set(), 0 | |
| paths: list[str] = [] | |
| exts: set[str] = set() | |
| for f in files: | |
| p = str(f.get("path") or f.get("name") or "") if isinstance(f, Mapping) else str(f or "") | |
| p = p.strip() | |
| if not p: | |
| continue | |
| if len(paths) < 32: | |
| paths.append(p) | |
| if "." in p: | |
| ext = p.rsplit(".", 1)[-1].lower() | |
| if 1 <= len(ext) <= 6: | |
| exts.add(ext) | |
| return " | ".join(paths), exts, len(files) | |
| def apply_structural_and_zero_cue_disambiguation( | |
| raw_name: str, | |
| probs_category: list[float] | Any, | |
| p_adult: float, | |
| p_anime: float, | |
| catalog: Mapping[str, Any] | None = None, | |
| extra_spans: list[str] | None = None, | |
| plugin_rules: Mapping[str, Any] | None = None, | |
| files: list[Any] | tuple[Any, ...] | None = None, | |
| ) -> tuple[int, str]: | |
| """Apply deterministic structural rules (Stage 1) and Zero-Cue catalog lookup (Stage 2) | |
| to an 11-class category probability vector from Armiger or Armiger Ultra. | |
| """ | |
| rules = plugin_rules or {} | |
| p = [float(x) for x in probs_category] | |
| file_surface, file_exts, file_cnt = _extract_file_surface(files) | |
| zc_ceiling = float(rules.get("confidence_ceiling", rules.get("zero_cue_confidence_ceiling", 0.88))) | |
| anime_min_p = float(rules.get("anime_threshold", rules.get("anime_catalog_min_prob", 0.20))) | |
| adult_siterip_floor = float(rules.get("adult_siterip_floor", 0.92)) | |
| comic_archive_floor = float(rules.get("comic_archive_floor", 0.90)) | |
| movie_pack_sum_floor = float(rules.get("movie_pack_sum_floor", 0.45)) | |
| movie_pack_margin = float(rules.get("movie_pack_margin", 0.40)) | |
| tv_cue_adult_ceiling = float(rules.get("tv_cue_adult_ceiling", 0.65)) | |
| tv_cue_xxx_ceiling = float(rules.get("tv_cue_xxx_ceiling", 0.50)) | |
| tv_cue_margin = float(rules.get("tv_cue_margin", 0.40)) | |
| tv_cue_floor = float(rules.get("tv_cue_floor", 0.75)) | |
| game_archive_adult_ceiling = float(rules.get("game_archive_adult_ceiling", 0.70)) | |
| game_archive_floor = float(rules.get("game_archive_floor", 0.88)) | |
| course_book_floor = float(rules.get("course_book_floor", 0.88)) | |
| has_tv_cue = bool( | |
| EXPLICIT_TV_RE.search(raw_name) | |
| or _match_safe_tokens(raw_name, list(rules.get("extra_tv_tokens") or [])) | |
| or safe_regex_search(rules.get("explicit_tv_regex"), raw_name, field_name="zero_cue.explicit_tv_regex") | |
| ) | |
| has_movie_cue = bool( | |
| EXPLICIT_MOVIE_PACK_RE.search(raw_name) | |
| or _match_safe_tokens(raw_name, list(rules.get("extra_movie_tokens") or [])) | |
| or safe_regex_search(rules.get("explicit_movie_pack_regex"), raw_name, field_name="zero_cue.explicit_movie_pack_regex") | |
| ) | |
| if ADULT_SITERIP_RE.search(raw_name) or safe_regex_search(rules.get("adult_siterip_regex"), raw_name, field_name="zero_cue.adult_siterip_regex"): | |
| p[IDX_XXX] = max(p[IDX_XXX], adult_siterip_floor) | |
| return IDX_XXX, "structural_adult_siterip" | |
| top_i = int(max(range(len(p)), key=p.__getitem__)) | |
| has_primary_comic = _is_primary_book_payload(raw_name, file_exts, {"cbr", "cbz", "cb7"}, has_tv_cue, has_movie_cue) | |
| if ( | |
| EXPLICIT_COMIC_RE.search(raw_name) or has_primary_comic | |
| or safe_regex_search(rules.get("explicit_comic_regex"), raw_name, field_name="zero_cue.explicit_comic_regex") | |
| ) and not re.search(r"(?i)how\s+to\s+draw", raw_name): | |
| if top_i in (IDX_EBOOK, IDX_COMIC) or p[top_i] < comic_archive_floor: | |
| p[IDX_COMIC] = max(p[IDX_COMIC], comic_archive_floor) | |
| return IDX_COMIC, "structural_comic_archive" | |
| has_primary_ab = ( | |
| _is_primary_book_payload(raw_name, file_exts, {"m4b", "mp3", "ogg", "flac"}, has_tv_cue, has_movie_cue, _AUDIOBOOK_ALLOWED_COMPANION_EXTS) | |
| and ("m4b" in file_exts or (file_surface and _AUDIOBOOK_FILE_TREE_RE.search(file_surface))) | |
| and (top_i in (IDX_AUDIOBOOK, IDX_EBOOK, IDX_MUSIC) or p[top_i] < 0.90) | |
| ) | |
| if _AUDIOBOOK_FILE_TREE_RE.search(raw_name) or has_primary_ab: | |
| p[IDX_AUDIOBOOK] = max(p[IDX_AUDIOBOOK], 0.90) | |
| return IDX_AUDIOBOOK, "structural_audiobook_files" | |
| has_primary_course = ( | |
| bool(file_surface and _COURSE_FILE_TREE_RE.search(file_surface) and file_cnt >= 3) | |
| and _is_primary_book_payload(raw_name, file_exts, {"mp4", "mkv", "pdf", "zip", "srt", "html"}, has_tv_cue, has_movie_cue, _COURSE_ALLOWED_COMPANION_EXTS) | |
| and (top_i in (IDX_COURSE, IDX_EBOOK, IDX_TV, IDX_MOVIE) or p[top_i] < course_book_floor) | |
| ) | |
| if ( | |
| COURSE_BOOK_RE.search(raw_name) or _V3_COURSE_RE.search(raw_name) or has_primary_course | |
| or _match_safe_tokens(raw_name, list(rules.get("extra_course_tokens") or [])) | |
| or safe_regex_search(rules.get("course_book_regex"), raw_name, field_name="zero_cue.course_book_regex") | |
| ): | |
| p[IDX_COURSE] = max(p[IDX_COURSE], course_book_floor) | |
| return IDX_COURSE, "structural_course_book" | |
| if has_movie_cue and not has_tv_cue: | |
| if p[IDX_MOVIE] + p[IDX_TV] > movie_pack_sum_floor: | |
| p[IDX_MOVIE] = max(p[IDX_MOVIE], p[IDX_TV] + movie_pack_margin) | |
| return int(max(range(len(p)), key=p.__getitem__)), "structural_movie_pack" | |
| elif has_tv_cue and not has_movie_cue: | |
| if p[IDX_XXX] < tv_cue_xxx_ceiling and p_adult < tv_cue_adult_ceiling: | |
| p[IDX_TV] = max(p[IDX_TV], p[IDX_MOVIE] + tv_cue_margin, tv_cue_floor) | |
| return int(max(range(len(p)), key=p.__getitem__)), "structural_tv_cue" | |
| if ( | |
| (GAME_ARCHIVE_RE.search(raw_name) or _match_safe_tokens(raw_name, list(rules.get("extra_game_tokens") or [])) | |
| or safe_regex_search(rules.get("game_archive_regex"), raw_name, field_name="zero_cue.game_archive_regex")) | |
| and not _SOUNDTRACK_AUDIO_EXCLUSION_RE.search(raw_name) and p_adult < game_archive_adult_ceiling | |
| ): | |
| p[IDX_GAME] = max(p[IDX_GAME], game_archive_floor) | |
| return IDX_GAME, "structural_game_archive" | |
| pred_idx = int(max(range(len(p)), key=p.__getitem__)) | |
| if catalog is not None and pred_idx in (IDX_MOVIE, IDX_TV) and not has_tv_cue and not has_movie_cue: | |
| if max(p[IDX_MOVIE], p[IDX_TV]) < zc_ceiling: | |
| cat_hit, src_kind = lookup_zero_cue_catalog(raw_name, catalog, is_anime=bool(p_anime >= anime_min_p), extra_spans=extra_spans) | |
| if cat_hit in ("movie", "tv_show") and src_kind is not None: | |
| return (IDX_MOVIE if cat_hit == "movie" else IDX_TV), f"zero_cue_{src_kind}" | |
| return pred_idx, "neural_backbone" | |
| class ZeroCueCatalogPlugin: | |
| """High-level wrapper for loading `validated_zero_cue_catalog.zcb3` (via zero-deserialization `mmap`) | |
| with automatic fallback to `validated_zero_cue_catalog.json`. | |
| """ | |
| _DEFAULT_CATALOG_DIR: pathlib.Path = pathlib.Path(__file__).resolve().parent | |
| def __init__( | |
| self, | |
| catalog_path: str | pathlib.Path | Mapping[str, Any] | None = None, | |
| *, | |
| plugin_rules: Mapping[str, Any] | None = None, | |
| ) -> None: | |
| self.plugin_rules: dict[str, Any] = dict(plugin_rules or {}) | |
| self.catalog_mode: str = "empty" | |
| self.last_load_warning: str | None = None | |
| if isinstance(catalog_path, Mapping): | |
| self.catalog_path = None | |
| self.catalog: Mapping[str, Any] = catalog_path | |
| self.catalog_mode = "mmap_zcb3" if isinstance(catalog_path, ZCB3MmapCatalog) else "memory_dict" | |
| return | |
| if catalog_path is None: | |
| default_zcb3 = self._DEFAULT_CATALOG_DIR / "validated_zero_cue_catalog.zcb3" | |
| default_json = self._DEFAULT_CATALOG_DIR / "validated_zero_cue_catalog.json" | |
| catalog_path = default_zcb3 if default_zcb3.exists() else default_json | |
| self.catalog_path = pathlib.Path(catalog_path) | |
| self.catalog = self._load_catalog_with_fallback(self.catalog_path) | |
| def _load_catalog_with_fallback(self, path: pathlib.Path) -> Mapping[str, Any]: | |
| # 1. If path points to a .zcb3 / .zcb3.zlib / .zcb3.lzma file (or starts with b"ZCB3" magic) | |
| if path.exists(): | |
| suffix_lower = "".join(path.suffixes).lower() | |
| is_zcb3_ext = ".zcb3" in suffix_lower | |
| if not is_zcb3_ext: | |
| try: | |
| with path.open("rb") as f_peek: | |
| is_zcb3_ext = f_peek.read(4) == ZCB3_MAGIC | |
| except OSError: | |
| is_zcb3_ext = False | |
| if is_zcb3_ext: | |
| try: | |
| zcat = ZCB3MmapCatalog(path) | |
| self.catalog_mode = zcat.storage_mode | |
| return zcat | |
| except (ValueError, OSError) as exc: | |
| self.last_load_warning = f"zcb3_load_failed:{path.name}:{exc}" | |
| logger.warning( | |
| "Failed to load ZCB3 binary catalog %s (%s); attempting JSON fallback", | |
| path, | |
| exc, | |
| ) | |
| base_stem = path.name.split(".zcb3")[0] if ".zcb3" in path.name.lower() else path.stem | |
| sibling_json = path.with_name(f"{base_stem}.json") | |
| if sibling_json.exists() and sibling_json != path: | |
| self.catalog_mode = "json_fallback" | |
| return json.loads(sibling_json.read_text(encoding="utf-8")) | |
| raise | |
| # 2. If path points to .json, prefer a sibling .zcb3 file if present | |
| if path.suffix.lower() == ".json": | |
| sibling_zcb3 = path.with_suffix(".zcb3") | |
| if sibling_zcb3.exists(): | |
| try: | |
| zcat = ZCB3MmapCatalog(sibling_zcb3) | |
| self.catalog_mode = zcat.storage_mode | |
| return zcat | |
| except (ValueError, OSError) as exc: | |
| self.last_load_warning = f"zcb3_load_failed:{sibling_zcb3.name}:{exc}" | |
| logger.warning( | |
| "Failed to load sibling ZCB3 binary catalog %s (%s); falling back to JSON %s", | |
| sibling_zcb3, | |
| exc, | |
| path, | |
| ) | |
| # 3. Automatic fallback to JSON catalog | |
| self.catalog_mode = "json_fallback" | |
| return json.loads(path.read_text(encoding="utf-8")) | |
| # 4. If requested .zcb3 does not exist, fall back to sibling .json | |
| if path.suffix.lower() == ".zcb3": | |
| sibling_json = path.with_suffix(".json") | |
| if sibling_json.exists(): | |
| self.catalog_mode = "json_fallback" | |
| return json.loads(sibling_json.read_text(encoding="utf-8")) | |
| self.catalog_mode = "empty" | |
| return {} | |
| def close(self) -> None: | |
| if hasattr(self.catalog, "close"): | |
| self.catalog.close() | |
| def resolve( | |
| self, | |
| raw_name: str, | |
| probs_category: list[float] | Any, | |
| p_adult: float = 0.0, | |
| p_anime: float = 0.0, | |
| extra_spans: list[str] | None = None, | |
| plugin_rules: Mapping[str, Any] | None = None, | |
| files: list[Any] | tuple[Any, ...] | None = None, | |
| ) -> dict[str, Any]: | |
| eff_rules = plugin_rules if plugin_rules is not None else self.plugin_rules | |
| idx, source = apply_structural_and_zero_cue_disambiguation( | |
| raw_name=raw_name, probs_category=probs_category, p_adult=p_adult, p_anime=p_anime, | |
| catalog=self.catalog, extra_spans=extra_spans, plugin_rules=eff_rules, files=files, | |
| ) | |
| if source == "neural_backbone": | |
| idx_v3, src_v3, probs_v3 = resolve_category_v3( | |
| raw_name=raw_name, probs_category=probs_category, p_adult=p_adult, p_anime=p_anime, | |
| catalog=self.catalog, extra_spans=extra_spans, plugin_rules=eff_rules, files=files, | |
| ) | |
| if src_v3 != "v3_neural_calibrated" or eff_rules: | |
| return { | |
| "category_index": idx_v3, "category": CATS[idx_v3], "resolution_source": src_v3, | |
| "calibrated_probs": probs_v3, "catalog_mode": self.catalog_mode, | |
| } | |
| return {"category_index": idx, "category": CATS[idx], "resolution_source": source, "catalog_mode": self.catalog_mode} | |
| # --- Armiger v3.0 Structural Disambiguator & Prior-Corrected Logit Calibrator --- | |
| _V3_COMIC_RE = re.compile( | |
| r"(?i)(?:\.(?:cbr|cbz|cb7)$|\b(?:cbr|cbz|cb7)\b|\([0-9]{4}\)\s*\(digital\)|\bc2c\b.*\.(?:cbr|cbz|rar|zip)$)" | |
| ) | |
| _V3_AUDIOBOOK_RE = re.compile(r"(?i)(?:\.m4b$|\baudiobook\b|\bunabridged\b|\babridged\b|_librivox\b)") | |
| _V3_EBOOK_RE = re.compile(r"(?i)(?:\.(?:epub|mobi|azw3)$|\b(?:epub|mobi|azw3)\b)") | |
| _V3_GAME_STRONG_RE = re.compile( | |
| r"(?i)(?:\.(?:nsp|xci|cia|3ds|vpk|wbfs)$|\b(?:fitgirl|dodi[\s._-]*repack|elamigos|kaos[\s._-]*repack|" | |
| r"codex|skidrow|plaza|flt|rune|tenoke|razor1911|reloaded|cpy|empress|rg[\s._-]*mechanics)\b|" | |
| r"\bgog[\s._-]+(?:repack|edition|rip|v\d)\b|(?:^|[\s._\-\[\(])plus[\s._-]+\d+[\s._-]+trainer(?=$|[\s._\-\]\)])|" | |
| r"\bbuild[\s._-]+\d{5,9}\b|\bps[2345]\b.*\b(?:usa|eur|jpn|pkg|iso)\b|\bxbox\s*360\b|\bnintendo\s+switch\b|\brpg\s+maker\b)" | |
| ) | |
| _V3_COURSE_RE = re.compile( | |
| r"(?i)(?:(?:^|[\s._\-\[\(])(?:udemy|coursera|pluralsight|lynda|linkedin[\s._-]*learning|skillshare|masterclass|" | |
| r"the[\s._-]+great[\s._-]+courses|ttc[\s._-]+video|packt|oreilly|cbt[\s._-]+nuggets|ine[\s._-]+ccie|" | |
| r"laracasts|frontend[\s._-]+masters|egghead)(?=$|[\s._\-\]\)])|" | |
| r"(?:^|[\s._\-\[\(])(?:testbuch|kursbuch|arbeitsbuch|lehrbuch|übungsbuch)(?=$|[\s._\-\]\)])|" | |
| r"(?:^|[\s._\-\[\(])(?:ucberkeley|mit)[\s._-]+(?:webcast|opencourseware)(?=$|[\s._\-\]\)])|" | |
| r"(?:^|[\s._\-\[\(])(?:lecture[\s._-]+series|video[\s._-]+training|video[\s._-]+course|full[\s._-]+tutorial|study[\s._-]+guide|open\s*course\s*ware)(?=$|[\s._\-\]\)]))" | |
| ) | |
| _V3_SOFTWARE_RE = re.compile( | |
| r"(?i)(?:\b(?:macos|macosx|mac\s+os\s+x|win32|win64|x86_64|pre-activated|crack|keygen)\b.*\b(?:v?\d+\.\d+|20[12]\d)\b|" | |
| r"\b(?:multilingual|portable|bootable)\b.*\b(?:v\d+\.\d+\.\d+|x64|win64|macos|dmg|setup|installer)\b|" | |
| r"\b(?:adobe|autodesk|jetbrains|microsoft\s+office|windows\s+(?:10|11|server)|" | |
| r"vmware|parallels|ableton|fl\s+studio|native\s+instruments|kontakt|waves\s+complete)\b)" | |
| ) | |
| _V3_MUSIC_RE = re.compile( | |
| r"(?i)(?:\.(?:flac|alac|ape|wv|dsf|dff)$|\b(?:discography|discografia|ost|soundtrack|" | |
| r"lossless|24bit|16bit|44\.1khz|96khz|192khz|cd-rip|vinyl[\s._-]*rip|web-flac|mp3[\s._-]*320)\b)" | |
| ) | |
| _V3_CONCERT_OR_DOC_VIDEO_RE = re.compile( | |
| r"(?i)(?:^|[\s._\-\[\(])(?:philharmoniker|symphony[\s._-]+orchestra|live[\s._-]+in[\s._-]+[a-z]+|live[\s._-]+at[\s._-]+[a-z]+)(?=$|[\s._\-\]\)]).*\b(?:1080i|1080p|720p|bluray|mkv|ts)\b" | |
| ) | |
| _V3_ADULT_STUDIO_RE = re.compile( | |
| r"(?i)(?:\b(?:xxx|siterip|onlyfans|manyvids|brazzers|naughtyamerica|realitykings|mofos|" | |
| r"bangbros|vixen|tushy|blacked|deeper|slayed|metart|sexart|hegre|twistys|playboy|penthouse|" | |
| r"jav|fc2[\s._-]*ppv|uncensored[\s._-]*leak|1pondo|caribbeancom|heyzo|pacopacomama)\b|" | |
| r"\b[a-z]{2,5}-\d{3,5}\b.*\b(?:mp4|mkv|wmv|avi|1080p|720p|fhd|hd)\b)" | |
| ) | |
| def _boost_and_normalize_v3(p: list[float], idx: int, min_prob: float) -> list[float]: | |
| target = min(0.99, max(float(p[idx]), float(min_prob))) | |
| rem_budget = max(0.0, 1.0 - target) | |
| other_sum = sum(float(p[i]) for i in range(len(p)) if i != idx) | |
| out: list[float] = [] | |
| for i in range(len(p)): | |
| if i == idx: | |
| out.append(round(target, 6)) | |
| elif other_sum > 0.0: | |
| out.append(round(rem_budget * (float(p[i]) / other_sum), 6)) | |
| else: | |
| out.append(round(rem_budget / max(1, len(p) - 1), 6)) | |
| diff = round(1.0 - sum(out), 6) | |
| out[idx] = round(max(0.0, min(1.0, out[idx] + diff)), 6) | |
| return out | |
| DEFAULT_V3_CATEGORY_PRIOR_BOOST: tuple[float, ...] = ( | |
| 0.0, 0.0, 0.0, 0.05, 0.15, 0.12, 0.15, 0.12, 0.15, 0.18, -0.35 | |
| ) | |
| def calibrate_category_logits_v3( | |
| logits_or_probs: list[float] | Any, | |
| temperature: float = 0.85, | |
| prior_boost: list[float] | tuple[float, ...] | None = None, | |
| ) -> list[float]: | |
| """Apply prior-shift log-odds correction and temperature scaling to 11-class category probabilities.""" | |
| import math | |
| arr = [float(x) for x in logits_or_probs] | |
| s = sum(arr) | |
| is_prob = all(x >= 0.0 for x in arr) and (0.98 <= s <= 1.02) | |
| logits = [math.log(max(x, 1e-12)) for x in arr] if is_prob else list(arr) | |
| eff_boost = list(prior_boost) if prior_boost is not None and len(prior_boost) >= 11 else list(DEFAULT_V3_CATEGORY_PRIOR_BOOST) | |
| scaled = [(logits[i] + float(eff_boost[i])) / max(float(temperature), 0.1) for i in range(min(len(logits), 11))] | |
| m = max(scaled) | |
| exps = [math.exp(x - m) for x in scaled] | |
| z = sum(exps) or 1.0 | |
| out = [round(x / z, 6) for x in exps] | |
| if out: | |
| diff = round(1.0 - sum(out), 6) | |
| best_i = max(range(len(out)), key=out.__getitem__) | |
| out[best_i] = round(max(0.0, min(1.0, out[best_i] + diff)), 6) | |
| return out | |
| def resolve_category_v3( | |
| raw_name: str, | |
| probs_category: list[float] | Any, | |
| p_adult: float = 0.0, | |
| p_anime: float = 0.0, | |
| catalog: Mapping[str, Any] | None = None, | |
| extra_spans: list[str] | None = None, | |
| plugin_rules: Mapping[str, Any] | None = None, | |
| files: list[Any] | tuple[Any, ...] | None = None, | |
| ) -> tuple[int, str, list[float]]: | |
| """Armiger v3.0 11-class category resolver combining calibrated neural probabilities, | |
| structural/format rules, and zero-cue BLAKE2b-64 catalog lookup (`ZCB3` or JSON). | |
| """ | |
| rules = plugin_rules or {} | |
| file_surface, file_exts, file_cnt = _extract_file_surface(files) | |
| cat_temp = float(rules.get("category_temperature", 0.85)) | |
| cat_prior = rules.get("category_prior_boost") | |
| zc_ceiling = float(rules.get("zero_cue_confidence_ceiling", rules.get("confidence_ceiling", 0.93))) | |
| anime_min_p = float(rules.get("anime_catalog_min_prob", rules.get("anime_threshold", 0.15))) | |
| adult_siterip_floor = float(rules.get("adult_siterip_floor", 0.94)) | |
| comic_archive_floor = float(rules.get("comic_archive_floor", 0.92)) | |
| movie_pack_sum_floor = float(rules.get("movie_pack_sum_floor", 0.40)) | |
| movie_pack_margin = float(rules.get("movie_pack_margin", 0.40)) | |
| tv_cue_adult_ceiling = float(rules.get("tv_cue_adult_ceiling", 0.65)) | |
| tv_cue_xxx_ceiling = float(rules.get("tv_cue_xxx_ceiling", 0.50)) | |
| tv_cue_margin = float(rules.get("tv_cue_margin", 0.40)) | |
| tv_cue_floor = float(rules.get("tv_cue_floor", 0.85)) | |
| game_archive_adult_ceiling = float(rules.get("game_archive_adult_ceiling", 0.70)) | |
| game_archive_floor = float(rules.get("game_archive_floor", 0.90)) | |
| course_book_floor = float(rules.get("course_book_floor", 0.91)) | |
| p = calibrate_category_logits_v3(probs_category, temperature=cat_temp, prior_boost=cat_prior) | |
| s = raw_name.strip() | |
| has_tv_cue = bool( | |
| EXPLICIT_TV_RE.search(s) | |
| or _match_safe_tokens(s, list(rules.get("extra_tv_tokens") or [])) | |
| or safe_regex_search(rules.get("explicit_tv_regex"), s, field_name="zero_cue.explicit_tv_regex") | |
| ) | |
| has_movie_cue = bool( | |
| EXPLICIT_MOVIE_PACK_RE.search(s) | |
| or _match_safe_tokens(s, list(rules.get("extra_movie_tokens") or [])) | |
| or safe_regex_search(rules.get("explicit_movie_pack_regex"), s, field_name="zero_cue.explicit_movie_pack_regex") | |
| ) | |
| has_video_ext_or_codec = bool( | |
| re.search(r"(?i)(?:\.(?:mkv|mp4|avi|m2ts|ts|wmv|mov)$|\b(?:1080p|720p|2160p|480p|bluray|web-dl|webrip|bdrip|dvdrip|x264|x265|hevc|h264|h265|xvid)\b)", s) | |
| or (file_exts & {"mkv", "mp4", "avi", "m2ts", "ts", "wmv", "mov"}) | |
| ) | |
| if ( | |
| ADULT_SITERIP_RE.search(s) | |
| or safe_regex_search(rules.get("adult_siterip_regex"), s, field_name="zero_cue.adult_siterip_regex") | |
| or (_V3_ADULT_STUDIO_RE.search(s) and p_adult >= 0.25) | |
| ): | |
| return IDX_XXX, "v3_structural_adult", _boost_and_normalize_v3(p, IDX_XXX, adult_siterip_floor) | |
| top_i = int(max(range(len(p)), key=p.__getitem__)) | |
| has_primary_comic = _is_primary_book_payload(s, file_exts, {"cbr", "cbz", "cb7"}, has_tv_cue, has_movie_cue) and ( | |
| top_i in (IDX_EBOOK, IDX_COMIC) or p[top_i] < comic_archive_floor | |
| ) | |
| if ( | |
| _V3_COMIC_RE.search(s) or EXPLICIT_COMIC_RE.search(s) or has_primary_comic | |
| or safe_regex_search(rules.get("explicit_comic_regex"), s, field_name="zero_cue.explicit_comic_regex") | |
| ) and not re.search(r"(?i)how\s+to\s+draw", s): | |
| return IDX_COMIC, "v3_structural_comic", _boost_and_normalize_v3(p, IDX_COMIC, comic_archive_floor) | |
| has_primary_ab_v3 = ( | |
| _is_primary_book_payload(s, file_exts, {"m4b", "mp3", "ogg", "flac"}, has_tv_cue, has_movie_cue, _AUDIOBOOK_ALLOWED_COMPANION_EXTS) | |
| and ("m4b" in file_exts or (file_surface and _AUDIOBOOK_FILE_TREE_RE.search(file_surface))) | |
| and (top_i in (IDX_AUDIOBOOK, IDX_EBOOK, IDX_MUSIC) or p[top_i] < 0.92) | |
| ) | |
| if _V3_AUDIOBOOK_RE.search(s) or has_primary_ab_v3: | |
| return IDX_AUDIOBOOK, "v3_structural_audiobook", _boost_and_normalize_v3(p, IDX_AUDIOBOOK, 0.92) | |
| has_primary_course_v3 = ( | |
| bool(file_surface and _COURSE_FILE_TREE_RE.search(file_surface) and file_cnt >= 3) | |
| and _is_primary_book_payload(s, file_exts, {"mp4", "mkv", "pdf", "zip", "srt", "html"}, has_tv_cue, has_movie_cue, _COURSE_ALLOWED_COMPANION_EXTS) | |
| and (top_i in (IDX_COURSE, IDX_EBOOK, IDX_TV, IDX_MOVIE) or p[top_i] < course_book_floor) | |
| ) | |
| if ( | |
| _V3_COURSE_RE.search(s) or COURSE_BOOK_RE.search(s) or has_primary_course_v3 | |
| or _match_safe_tokens(s, list(rules.get("extra_course_tokens") or [])) | |
| or safe_regex_search(rules.get("course_book_regex"), s, field_name="zero_cue.course_book_regex") | |
| ): | |
| return IDX_COURSE, "v3_structural_course", _boost_and_normalize_v3(p, IDX_COURSE, course_book_floor) | |
| has_primary_ebook = _is_primary_book_payload(s, file_exts, {"epub", "mobi", "azw3"}, has_tv_cue, has_movie_cue) and ( | |
| top_i in (IDX_EBOOK, IDX_COMIC) or p[top_i] < 0.91 | |
| ) | |
| if (_V3_EBOOK_RE.search(s) or has_primary_ebook) and not _V3_COMIC_RE.search(s) and not _V3_AUDIOBOOK_RE.search(s): | |
| return IDX_EBOOK, "v3_structural_ebook", _boost_and_normalize_v3(p, IDX_EBOOK, 0.91) | |
| if ( | |
| GAME_ARCHIVE_RE.search(s) or _V3_GAME_STRONG_RE.search(s) or (file_exts & {"nsp", "xci", "cia", "3ds", "vpk", "wbfs"}) | |
| or _match_safe_tokens(s, list(rules.get("extra_game_tokens") or [])) | |
| or safe_regex_search(rules.get("game_archive_regex"), s, field_name="zero_cue.game_archive_regex") | |
| ) and p_adult < game_archive_adult_ceiling and not has_tv_cue: | |
| if not _SOUNDTRACK_AUDIO_EXCLUSION_RE.search(s) and not (file_exts and file_exts <= {"mp3", "flac", "ogg", "m4a", "wav", "cue", "log", "jpg", "png", "txt", "nfo"}): | |
| return IDX_GAME, "v3_structural_game", _boost_and_normalize_v3(p, IDX_GAME, game_archive_floor) | |
| if _V3_CONCERT_OR_DOC_VIDEO_RE.search(s) and not has_tv_cue: | |
| return IDX_MOVIE, "v3_structural_video_override", _boost_and_normalize_v3(p, IDX_MOVIE, 0.88) | |
| if _V3_MUSIC_RE.search(s) and not has_video_ext_or_codec and not has_tv_cue: | |
| return IDX_MUSIC, "v3_structural_music", _boost_and_normalize_v3(p, IDX_MUSIC, 0.90) | |
| if _V3_SOFTWARE_RE.search(s) and not has_video_ext_or_codec and not has_tv_cue and p_adult < 0.50: | |
| if not (file_exts and file_exts <= {"epub", "pdf", "mobi", "azw3", "mp3", "flac", "m4b", "txt", "nfo"}): | |
| return IDX_SOFTWARE, "v3_structural_software", _boost_and_normalize_v3(p, IDX_SOFTWARE, 0.89) | |
| if has_movie_cue and not has_tv_cue: | |
| if p[IDX_MOVIE] + p[IDX_TV] > movie_pack_sum_floor: | |
| floor_m = min(0.99, max(p[IDX_MOVIE], p[IDX_TV] + movie_pack_margin, 0.85)) | |
| return IDX_MOVIE, "v3_structural_movie_pack", _boost_and_normalize_v3(p, IDX_MOVIE, floor_m) | |
| elif has_tv_cue and not has_movie_cue: | |
| if p[IDX_XXX] < tv_cue_xxx_ceiling and p_adult < tv_cue_adult_ceiling: | |
| floor_t = min(0.99, max(p[IDX_TV], p[IDX_MOVIE] + tv_cue_margin, tv_cue_floor)) | |
| return IDX_TV, "v3_structural_tv_cue", _boost_and_normalize_v3(p, IDX_TV, floor_t) | |
| pred_idx = int(max(range(len(p)), key=p.__getitem__)) | |
| if catalog is not None and pred_idx in (IDX_MOVIE, IDX_TV) and not has_tv_cue and not has_movie_cue: | |
| if max(p[IDX_MOVIE], p[IDX_TV]) < zc_ceiling: | |
| cat_hit, src_kind = lookup_zero_cue_catalog( | |
| s, catalog, is_anime=bool(p_anime >= anime_min_p), extra_spans=extra_spans | |
| ) | |
| if cat_hit in ("movie", "tv_show") and src_kind is not None: | |
| idx_hit = IDX_MOVIE if cat_hit == "movie" else IDX_TV | |
| return idx_hit, f"v3_zero_cue_{src_kind}", _boost_and_normalize_v3(p, idx_hit, 0.90) | |
| return pred_idx, "v3_neural_calibrated", p | |