Publish Armiger v3.0.0 (Rule-3 Gold mit3): weights, calibration, cards and receipts-synced docs
25cbd40 verified Download armiger_inference.py from NorviTech/armiger: direct link, hf CLI and curl.
- Browser
- Download file 37.3 kB
-
https://huggingface.co/NorviTech/armiger/resolve/main/armiger_inference.py
- Command line
-
hf download hf://NorviTech/armiger/armiger_inference.py
-
curl -L -o armiger_inference.py https://huggingface.co/NorviTech/armiger/resolve/main/armiger_inference.py
37.3 kB
| """Standalone Armiger v2.1 / Armiger Ultra ONNX Featurizer & Inference Runtime (`armiger_inference.py`). | |
| Implements exact feature parity with the Armiger v2.1 training pipeline (`sift/prepare.py` + | |
| `enrich_side21_v2` 36-dim `stats` vector + `vocab.json` 4,096-extension lookup + CRC32 | |
| digit-folded path-word hashing) with zero external codebase dependencies beyond `numpy` | |
| and `onnxruntime`. | |
| All release-group and publisher token tables are stored as 8-byte BLAKE2b-64 hex digests | |
| so zero copyrighted or scene group strings appear in plaintext. | |
| """ | |
| from __future__ import annotations | |
| import hashlib | |
| import json | |
| import math | |
| import os | |
| from pathlib import Path | |
| import re | |
| from typing import Any, Dict, List, Mapping, Optional, Sequence, Tuple | |
| import zlib | |
| try: | |
| import numpy as np | |
| except ImportError: | |
| np = None # type: ignore[assignment] | |
| SPAN_BIO_CLASSES: Tuple[str, ...] = ( | |
| "O", | |
| "B-TITLE", | |
| "I-TITLE", | |
| "B-YEAR", | |
| "I-YEAR", | |
| "B-EP", | |
| "I-EP", | |
| ) | |
| NEURAL_HEAD_CLASSES: Dict[str, List[str]] = { | |
| "category": [ | |
| "movie", "tv_show", "xxx", "music", "comic", | |
| "game", "audiobook", "software", "ebook", "course", "unknown", | |
| ], | |
| "adult": ["non_adult", "adult"], | |
| "junk": ["clean", "junk"], | |
| "anime": ["non_anime", "anime"], | |
| "english_subs": ["no_eng_subs", "has_eng_subs", "unknown"], | |
| "lang": ["english", "non_english", "multi_or_unknown"], | |
| "owner_scope": ["allowed_type", "excluded"], | |
| "title_language": ["english_title", "non_english_title"], | |
| "span_bio": list(SPAN_BIO_CLASSES), | |
| } | |
| _VOCAB_EXT_MAP: Optional[Dict[str, int]] = None | |
| _PREP_KIND_EXTS = { | |
| 0: frozenset("mkv mp4 avi ts m2ts mts vob wmv mpg mpeg mov flv rmvb rm m4v divx webm 3gp asf f4v ogv mxf m2v bik".split()), | |
| 1: frozenset("mp3 flac m4a m4b aac ogg opus wav wma ape alac aif aiff aifc ac3 dts mka mpc wv shn mid midi dff dsf".split()), | |
| 2: frozenset("zip rar 7z gz tgz bz2 xz zst lz lzma tar cab iso img dmg mdf mds nrg wim par par2 z".split()), | |
| 3: frozenset("exe msi apk ipa dll bat cmd sh vbs ps1 com scr jar deb rpm appimage run lnk".split()), | |
| 4: frozenset("jpg jpeg png gif webp bmp tif tiff avif jxl heic heif psd ai svg ico tga cr2 nef arw dng raw eps".split()), | |
| 5: frozenset("pdf epub mobi azw azw3 djvu djv fb2 txt rtf doc docx odt xls xlsx ppt pptx csv chm cbz cbr cb7 html htm mht mhtml md tex lit".split()), | |
| 6: frozenset("srt ass ssa sub idx vtt sup smi sbv ttml dfxp usf scc stl mks".split()), | |
| } | |
| _PREP_EXT_TO_KIND = {e: k for k, es in _PREP_KIND_EXTS.items() for e in es} | |
| _PREP_SPLIT_ARC_RE = re.compile(r"[rsz]\d{2,3}|\d{3}") | |
| _PREP_WORD_RE = re.compile(r"[^\W_]+") | |
| _PREP_DIGIT_RE = re.compile(r"\d") | |
| _PREP_SAMPLE_RE = re.compile(r"(?<![a-z])samples?(?![a-z])", re.IGNORECASE) | |
| # BLAKE2b-64 digest sets for release-tag disambiguation (zero plaintext group names) | |
| _SUB_ONLY_GRP_H = frozenset(['00d47045a1f1cd70', '0380c309e464115a', '0665f92d474878ff', '0f8f3809c6074d35', '1bc080c5d14b4eae', '1bf62e9b91086379', '22325081668ed28b', '26503f6826942362', '33b21e80d5dbfa62', '3e370e64b7539495', '4297edae7e25ba02', '4491be5b41a66832', '44e08227cfda9421', '4b956de9c462ee70', '519230ab4d0911f7', '581a8006ea8bd801', '65dfe6849ae4bb0d', '66ced9df20d8f558', '6a437c446b5778d6', '6cff013c3e752ac8', '6d3b6a62beedc878', '7bc52c5f863149cc', '867c636203d0524d', 'a7637cb5c531d8e9', 'b61d75b73d8e0c59', 'bed3322685febfa5', 'c603a601b7cb9d4c', 'd4eaba2bc7ef10d6', 'e20a8d50ddf1aa2e', 'e3fd326207da261c', 'fc94bcdf9fcb0164']) | |
| _DUAL_DUB_GRP_H = frozenset(['16bdcdbbbd493d9e', '17addcc669201a7b', '1cb486cd76cea8c6', '1cc2f6b1aa24d6f7', '236a71bfa2d47ca3', '24eee113ee4bddb0', '341556a463a4784b', '3658912d4f05f762', '6149de24f7784f27', '627dcb38527b8e4c', '6f09d409143a679c', '727c5e1f0f05ad51', '8b7c320e1df4bf3e', '9e64e0c8c213bf00', 'ac3675ff37aaf11e', 'b2c26515563660f5', 'bd672057ff15b985', 'd9621931df7eb664', 'e20db1736162ba0c', 'e2ee075c6b5545ad', 'eb446df9e0b5f645', 'f7a175e4cf1907fb', 'fe0fe2b14bb48506']) | |
| _GAME_GRP_H = frozenset(['03f22fe2a782da12', '0ae36a7939ac0be1', '1217fb0deda20335', '1c8f3166691fa2c6', '306372c75c8ceaa2', '32ba70bb6b5ae022', '4509f87fe97d6ed9', '4afe068be7dcf016', '6f7a14ce24f000a0', '7403ff2453c8a173', '7de6d237db23b5fa', '9641051915abdbb6', 'a491e84e39e2064e', 'a65a1816debe0915', 'aa89d2a9d5d18f01', 'aaac60aa2d75341b', 'bb98906accdd6e05', 'c200372b38fb6d26', 'c430ddffd526c993', 'cc81415c4d797870', 'e37a0da20d8d24ac', 'ed5d3b0f00026714', 'ee7b45399bcf968a', 'f0982ea7c2028c50', 'f1737c198253be9d', 'f766dbb74e38db04', 'fbe41c3bbd33ac19']) | |
| _SW_GRP_H = frozenset(['09455d377a262608', '0e30392b37df5495', '103064b4fea08f1c', '11a120607b793e4c', '158ba6de7392b368', '193a01c7e1bd0f62', '2199b8b3ff553486', '240843438078b817', '2508ee34b17c2225', '2a4eb6e114be0fab', '352836dac99f04b7', '391bd8a58914224a', '4185301675b9d80c', '4472c2744066912a', '4c4684b615a127b2', '522a470219d3a4f1', '5a6bb90382b6c1f6', '5ca7613c608a9ea5', '63f15e4687bfc135', '66a7555e70f0872e', '73d877e885d34562', '77c343b865d05e31', '780409423e866d09', '7e0a43f55a6714fd', '97409999bccb98f4', '996bd865c828c8f9', '9b60cdfff0e2ab1c', 'a330b94802e4b6c6', 'a9c5a9029bc6a596', 'b48e9326bf6316ef', 'c595d125bfd5ebe9', 'c8575232dac0347d', 'd64fa92611ac0eb2', 'e182e241e26cb119', 'e88087f130a6e7d6']) | |
| _BOOK_COMIC_GRP_H = frozenset(['0cad54552908fa65', '338c3fad71b18311', '5913147687b3c1e5', '712f82b4b85131a0', '7f5fc23af41380b2', '8d8b63a8bb00b7e4', '913bd80742a62e95', 'c00722c39b756d92', 'ecfebbed5476af20', 'ee2807f40b38f779', 'f89c7ccfb7b1338c', 'fdffac028227e18e', 'ffb2c2ead4c7ba7e']) | |
| _BENIGN_README_EXE_H = frozenset(['062b96e72d602b6e', '9a9f15179701c6ae', 'ddf05591355cf7e0']) | |
| _TOKEN_SCAN_RE = re.compile(r"[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*") | |
| _SIDE_ANIME_KW_RE = re.compile( | |
| r"(?i)\b(?:anime|ova|ona|donghua|aeni|bdrip[ ._-]*1080p[ ._-]*flac|dual[ ._-]*audio[ ._-]*\[?(?:jpn|jap))\b" | |
| ) | |
| _SIDE_VID_CLAIM_RE = re.compile( | |
| r"(?i)\b(?:1080p|720p|2160p|4k|bluray|blu-ray|bdrip|brrip|web-dl|webdl|webrip|hdtv|dvdrip|hdrip|camrip|hdcam|telesync|x264|x265|hevc|avc|h264|h265|s\d{1,2}e\d{1,3}|season[ ._-]*\d+|fc2-?ppv)\b|高清首发|更新至第" | |
| ) | |
| _SIDE_DECEPTIVE_SUB_STRIP_RE = re.compile( | |
| r"(?i)\b(?:eng(?:lish)?|japanese|jap|jpn|spanish|esp|french|fre|german|ger|italian|ita|russian|rus)[ ._-]+(?:hard|soft)?sub(?:s|bed|titled|titles)?\b|" | |
| r"\b(?:hard|soft)?sub(?:s|bed|titled|titles)?[ ._-]+(?:eng|english|esp|ja|jpn|fr|de|it|ru)\b|" | |
| r"\b(?:m[ ._-]?subs?|multi[ ._-]?subs?|esubs?|vostfr|hardsubs?)\b" | |
| ) | |
| _SIDE_ANIME_DUB_KW_RE = re.compile( | |
| r"(?i)\b(?:dual[ ._-]?audio|dubbed|eng(?:lish)?[ ._-]?dub(?:bed)?|multi[ ._-]?audio)\b" | |
| ) | |
| _SIDE_SW_APP_TITLE_RE = re.compile( | |
| r"(?i)\b(?:v?\d+\.\d+\.\d+|repack|portable|cracked|keygen|patch|patcher|activat(?:ed|or)|" | |
| r"multilingual|win(?:32|64)|x64|x86|macos|macosx|android|apk|pc[ ._-]?game|nintendo[ ._-]?switch|ps4|ps5|" | |
| r"emulator|driver|firmware|setup|installer|downloader|studio|vst3?|" | |
| r"pro[ ._-]+v?\d|ce[ ._-]+v?\d)\b" | |
| ) | |
| _SIDE_COURSE_RE = re.compile( | |
| r"(?i)\b(?:complete[ ._-]+course|video[ ._-]+course|masterclass|bootcamp|tutorial[ ._-]+series|certification[ ._-]+course|hands-on[ ._-]+training)\b" | |
| ) | |
| _SIDE_BOOK_COMIC_KW_RE = re.compile( | |
| r"(?i)\b(?:audiobooks?|audible|m4b|unabridged|narrated[ ._-]?by|ebook|e-book|epub|mobi|azw3|calibre)\b" | |
| ) | |
| _SIDE_VPN_TRAP_RE = re.compile( | |
| r"(?i)免费安装下载vpn|打不开网页|codec[ ._-]?(?:pack|setup|install)|player[ ._-]?setup|instructions?[ ._-]?to[ ._-]?watch" | |
| ) | |
| _SIDE_CJK_RE = re.compile(r"[\u4e00-\u9fff]") | |
| _SIDE_EP_ZIP_RE = re.compile( | |
| r"(?i)(?:^\[[^\[\]]{2,30}\].*?(?:\s-\s*\d{1,3}\b|\bS\d{1,2}E\d{1,3}\b).*?\b(?:1080p|720p|2160p|480p)\b|" | |
| r"\bS\d{1,2}E\d{1,3}\b.*?\b(?:1080p|720p|2160p|480p|WEB-DL|WEBRip|BluRay|BDRip|HDTV|x264|x265|HEVC)\b|" | |
| r"\b(?:1080p|720p|2160p|480p|576p|4k)\b.*?\b(?:WEB-DL|WEBRip|BluRay|BDRip|BRRip|HDRip|HDTV|HDCAM|CAMRip|DVDRip|x264|x265|H\.?264|H\.?265|HEVC|AV1|XviD|DivX)\b|" | |
| r"\b(?:WEB-DL|WEBRip|BDRip|BRRip|HDRip|HDTV|HDCAM|CAMRip|DVDRip)\b(?:.*?\b(?:x264|x265|H\.?264|H\.?265|HEVC|AV1|XviD|DivX))?)" | |
| ) | |
| _SIDE_BENIGN_ZIP_RE = re.compile( | |
| r"(?i)\b(?:batch|complete|season[ ._-]*\d+|s\d{1,2}[ ._-]*complete|e?\d{1,3}[ ._-]*[~-][ ._-]*e?\d{1,3}|시즌\s*\d+|완결|全集|合集|" | |
| r"ost|soundtrack|artbook|scans?|wallpapers?|fonts?|subs?|subtitles?)\b" | |
| ) | |
| def _h64(s: str) -> str: | |
| return hashlib.blake2b(s.strip().lower().encode("utf-8"), digest_size=8).hexdigest() | |
| def _extract_token_hashes(text: str) -> frozenset[str]: | |
| toks = [m.group(0).lower() for m in _TOKEN_SCAN_RE.finditer(text)] | |
| out = {_h64(t) for t in toks} | |
| for i in range(len(toks) - 1): | |
| out.add(_h64(f"{toks[i]} {toks[i + 1]}")) | |
| return frozenset(out) | |
| def _get_vocab_ext_map(vocab_path: Optional[Path] = None) -> Dict[str, int]: | |
| global _VOCAB_EXT_MAP | |
| if _VOCAB_EXT_MAP is not None and len(_VOCAB_EXT_MAP) > 64: | |
| return _VOCAB_EXT_MAP | |
| vpath = vocab_path if (vocab_path and vocab_path.exists()) else Path(__file__).resolve().with_name("vocab.json") | |
| if not vpath.exists() and os.environ.get("ARMIGER_MODEL_DIR"): | |
| vpath = Path(os.environ["ARMIGER_MODEL_DIR"]) / "vocab.json" | |
| if vpath.exists(): | |
| data = json.loads(vpath.read_text(encoding="utf-8")) | |
| _VOCAB_EXT_MAP = {e: i + 1 for i, e in enumerate(data.get("exts", []))} | |
| else: | |
| _VOCAB_EXT_MAP = { | |
| "mp3": 2, "mp4": 3, "mkv": 4, "avi": 7, "srt": 10, "zip": 12, | |
| "rar": 17, "exe": 23, "flac": 24, "png": 25, "dll": 31, "m4b": 53, | |
| "epub": 81, "cbz": 96, "lnk": 150, "scr": 310, | |
| } | |
| return _VOCAB_EXT_MAP | |
| def _hash_ext(ext: str) -> int: | |
| if not ext: | |
| return 4096 | |
| return _get_vocab_ext_map().get(ext.lower(), 4096) | |
| def _hash_word(w: str) -> int: | |
| if not w: | |
| return 0 | |
| folded = _PREP_DIGIT_RE.sub("0", w.lower()) | |
| return (zlib.crc32(folded.encode("utf-8")) % 32767) + 1 | |
| def _log2_size_bucket(sz: int) -> int: | |
| return min(47, max(int(sz), 1).bit_length() - 1) | |
| def _prep_split_path(path: str) -> Tuple[str, str, str, int]: | |
| p_norm = path.replace("\\", "/") | |
| parent, _, base = p_norm.rpartition("/") | |
| i = base.rfind(".") | |
| ext = base[i + 1:].lower() if i > 0 else "" | |
| if len(ext) <= 10 and ext.isascii() and ext.isalnum(): | |
| stem = base[:i] | |
| else: | |
| ext, stem = "", base | |
| return parent.rpartition("/")[2], stem, ext, p_norm.count("/") | |
| def _prep_path_words(parent: str, stem: str) -> List[int]: | |
| p_words = [_hash_word(w) for w in _PREP_WORD_RE.findall(parent.lower())][-2:] if parent else [] | |
| s_words = [_hash_word(w) for w in _PREP_WORD_RE.findall(stem.lower())][-(4 - len(p_words)):] | |
| res = p_words + s_words | |
| while len(res) < 4: | |
| res.append(0) | |
| return res[:4] | |
| def encode_torrent_features( | |
| row: Mapping[str, Any], | |
| max_name_len: int = 256, | |
| max_files: int = 64, | |
| ) -> Dict[str, Any]: | |
| """Encode a torrent metadata dictionary into the exact ONNX tensor inputs for Armiger v2.1.""" | |
| name = str(row.get("name") or row.get("title") or "") | |
| b_name = name.encode("utf-8", "replace") | |
| if len(b_name) > max_name_len: | |
| b_name = b_name[:max_name_len].decode("utf-8", "ignore").encode("utf-8") | |
| raw_bytes = list(b_name) if b_name else [32] | |
| raw_files = row.get("files") or [] | |
| total_size = int(row.get("size") or 0) | |
| all_items: List[Tuple[str, int]] = [] | |
| for f in raw_files: | |
| if isinstance(f, Mapping): | |
| p = str(f.get("path") or f.get("p") or f.get("name") or "") | |
| sz = int(f.get("size") or f.get("s") or 0) | |
| else: | |
| p = str(f or "") | |
| sz = 0 | |
| if p and "/.____padding_file/" not in p and not p.startswith(".____padding_file"): | |
| all_items.append((p, sz)) | |
| all_items.sort(key=lambda x: -x[1]) | |
| items: List[Tuple[str, int]] = all_items[:max_files] | |
| if not items and (row.get("ext") or row.get("extension") or "." in name): | |
| items.append((name, total_size)) | |
| ext_map = _get_vocab_ext_map() | |
| exts: List[int] = [] | |
| sizes: List[int] = [] | |
| depths: List[int] = [] | |
| words_list: List[List[int]] = [] | |
| f_exts_str: List[str] = [] | |
| kbytes = [0.0] * 8 | |
| kcount = [0] * 8 | |
| has_sample = False | |
| for path, sz in items: | |
| parent, stem, ext, depth = _prep_split_path(path) | |
| f_exts_str.append(ext) | |
| exts.append(ext_map.get(ext, 4096)) | |
| sizes.append(_log2_size_bucket(sz)) | |
| depths.append(min(depth, 7)) | |
| words_list.append(_prep_path_words(parent, stem)) | |
| k = _PREP_EXT_TO_KIND.get(ext) | |
| if k is None: | |
| k = 2 if _PREP_SPLIT_ARC_RE.fullmatch(ext) else 7 | |
| kbytes[k] += max(sz, 0) | |
| kcount[k] += 1 | |
| has_sample = has_sample or (_PREP_SAMPLE_RE.search(path) is not None) | |
| tot_k = sum(kbytes) | |
| weights = kbytes if tot_k > 0 else [float(c) for c in kcount] | |
| wsum = sum(weights) | |
| count = max(int(row.get("file_count") or 0), len(all_items), len(items)) | |
| biggest = max((max(s, 0) for _, s in items), default=0) | |
| max_share = (biggest / tot_k if tot_k > 0 else (1.0 / len(items) if items else 0.0)) | |
| base_stats = [ | |
| math.log1p(max(count, 0)), | |
| math.log1p(max(total_size if total_size > 0 else int(tot_k), 0)), | |
| ] | |
| base_stats += [w / wsum if wsum > 0 else 0.0 for w in weights] | |
| base_stats += [max_share, float(has_sample)] | |
| side = [0.0] * 24 | |
| n_f = float(max(1, len(items))) | |
| m_grp = re.match(r"^\[([^\[\]]{2,30})\]", name) | |
| grp_lc = m_grp.group(1).strip().lower() if m_grp else "" | |
| grp_h = _h64(grp_lc) if grp_lc else "" | |
| title_tok_h = _extract_token_hashes(name) | |
| has_sub_grp = (grp_h in _SUB_ONLY_GRP_H) or bool(title_tok_h & _SUB_ONLY_GRP_H) | |
| has_dub_grp = (grp_h in _DUAL_DUB_GRP_H) or bool(title_tok_h & _DUAL_DUB_GRP_H) | |
| has_game_grp = bool(title_tok_h & _GAME_GRP_H) | |
| has_sw_grp = bool(title_tok_h & _SW_GRP_H) | |
| has_book_grp = bool(title_tok_h & _BOOK_COMIC_GRP_H) | |
| if items: | |
| ebk_set = {"epub", "mobi", "azw3", "azw", "djvu", "fb2", "lit", "iba"} | |
| pdf_set = {"pdf"} | |
| m4b_set = {"m4b", "aa", "aax"} | |
| com_set = {"cbz", "cbr", "cb7", "cbt"} | |
| con_set = {"nsp", "xci", "xcz", "nsz", "wbfs", "rvz", "gcz", "cia", "3ds", "vpk", "ps4", "fpkg"} | |
| app_set = {"dmg", "pkg", "apk", "ipa", "deb", "rpm", "appimage"} | |
| exe_dll_set = {"exe", "msi", "bat", "cmd", "sh", "com", "dll"} | |
| iso_set = {"iso", "bin", "cue", "mdf", "mds", "nrg", "img"} | |
| arc_set = {"rar", "zip", "7z", "tar", "gz", "xz", "bz2", "001"} | |
| htm_set = {"html", "htm", "url", "mht", "torrent"} | |
| scr_set = {"scr", "lnk", "vbs", "hta", "pif", "ps1", "wsf", "reg"} | |
| vid_set = {"mkv", "mp4", "avi", "ts", "m2ts", "wmv", "mov", "webm", "flv", "mpg", "mpeg", "m4v", "vob", "ogv", "rmvb", "3gp", "asf", "divx"} | |
| bd_game_benign = {"vcdiff", "apk", "bdmv", "clpi", "mpls", "ifo", "bup", "vob", "npa", "vpk", "pck", "umd", "pak", "xp3", "rgss3a", "wolf", "nsp", "xci", "wbfs"} | |
| side[0] = sum(1 for e in f_exts_str if e in ebk_set) / n_f | |
| side[1] = sum(1 for e in f_exts_str if e in pdf_set) / n_f | |
| side[2] = sum(1 for e in f_exts_str if e in m4b_set) / n_f | |
| side[3] = sum(1 for e in f_exts_str if e in com_set) / n_f | |
| side[4] = sum(1 for e in f_exts_str if e in con_set) / n_f | |
| side[5] = sum(1 for e in f_exts_str if e in app_set) / n_f | |
| vc = bool(_SIDE_VID_CLAIM_RE.search(name) or _SIDE_ANIME_KW_RE.search(name) or has_sub_grp or has_dub_grp) | |
| has_any_vid_inf = any(e in vid_set for e in f_exts_str) | |
| has_renpy_structure = ( | |
| not vc | |
| and not has_any_vid_inf | |
| and any( | |
| p_i.replace("\\", "/").lower().endswith((".rpa", ".rpyb")) and int(sz_i or 0) >= 65536 | |
| for p_i, sz_i in items | |
| ) | |
| ) | |
| renpy_say_re = re.compile(r"(?i)(?:^|/)lib/(?:py\d+-)?windows-[^/]+/say\.vbs$") | |
| n_real_exec_dll = 0 | |
| has_real_exe = False | |
| has_dll = False | |
| has_scr_trap = False | |
| has_oversized_lnk = False | |
| has_root_launcher = False | |
| has_unconditional_trap_ext = False | |
| has_any_scr_ext = False | |
| vid_depths: List[int] = [] | |
| for (p_i, _), e_str, s_b, d_i, w_i in zip(items, f_exts_str, sizes, depths, words_list): | |
| p_posix = p_i.replace("\\", "/") | |
| if has_renpy_structure and renpy_say_re.search(p_posix): | |
| continue | |
| if e_str in scr_set: | |
| has_any_scr_ext = True | |
| if e_str in {"scr", "vbs", "vbe", "hta", "pif", "wsf", "wsh", "cpl"}: | |
| has_unconditional_trap_ext = True | |
| p_tok_h = _extract_token_hashes(p_i) | |
| is_benign_stub = (e_str == "exe") and (s_b < 15 or 16570 in w_i or bool(p_tok_h & _BENIGN_README_EXE_H)) | |
| if e_str in exe_dll_set and not is_benign_stub: | |
| n_real_exec_dll += 1 | |
| if e_str == "exe" and not is_benign_stub and s_b >= 15: | |
| has_real_exe = True | |
| if d_i == 0: | |
| has_root_launcher = True | |
| elif e_str == "dll": | |
| has_dll = True | |
| if e_str in {"scr", "lnk", "hta", "vbs", "pif", "ps1", "wsf", "cmd", "com", "one", "xll", "xlam"} and s_b >= 12: | |
| has_scr_trap = True | |
| if d_i == 0: | |
| has_root_launcher = True | |
| if e_str == "lnk" and s_b >= 15: | |
| has_oversized_lnk = True | |
| if e_str in vid_set: | |
| vid_depths.append(d_i) | |
| side[6] = n_real_exec_dll / n_f | |
| side[7] = sum(1 for e in f_exts_str if e in iso_set) / n_f | |
| side[8] = sum(1 for e in f_exts_str if e in arc_set) / n_f | |
| side[9] = sum(1 for e in f_exts_str if e in htm_set) / n_f | |
| side[10] = 1.0 if has_any_scr_ext else 0.0 | |
| is_sw_or_game = bool( | |
| has_game_grp | |
| or has_sw_grp | |
| or (not vc and _SIDE_SW_APP_TITLE_RE.search(name)) | |
| or any(e in bd_game_benign for e in f_exts_str) | |
| ) | |
| vid_share = base_stats[2] | |
| flagged = has_unconditional_trap_ext | |
| if not is_sw_or_game: | |
| if vc and has_real_exe and has_dll: | |
| flagged = True | |
| elif vc and len(vid_depths) >= 1 and (has_real_exe or has_root_launcher or has_scr_trap): | |
| flagged = True | |
| elif (vc or len(vid_depths) > 0) and has_oversized_lnk: | |
| flagged = True | |
| elif vc and vid_share == 0.0 and (has_real_exe or has_scr_trap): | |
| flagged = True | |
| elif len(items) <= 2 and any(e in ("zip", "zipx", "rar", "7z") for e in f_exts_str) and vid_share == 0.0: | |
| if _SIDE_EP_ZIP_RE.search(name) and not _SIDE_BENIGN_ZIP_RE.search(name): | |
| flagged = True | |
| elif len(items) <= 2 and any(e in ("iso", "img", "vhd", "vhdx", "udf") for e in f_exts_str) and vid_share == 0.0: | |
| name_stem = re.sub(r"\.(?:iso|img|vhd|vhdx|udf|dmg)$", "", name.strip(), flags=re.IGNORECASE) | |
| if _SIDE_EP_ZIP_RE.search(name_stem) and not re.search(r"(?i)\b(?:dvd|bd25|bd50|remux|untouched|pal|ntsc|iso)\b", name_stem): | |
| flagged = True | |
| if flagged or _SIDE_VPN_TRAP_RE.search(name) or (vc and vid_share == 0.0 and (side[6] > 0 or side[9] > 0 or side[10] > 0)): | |
| side[11] = 1.0 | |
| if vc and vid_share > 0 and 0 < base_stats[1] < 14.22: | |
| side[12] = 1.0 | |
| ag = bool(_SIDE_ANIME_KW_RE.search(name)) or has_sub_grp or has_dub_grp | |
| if ag: | |
| side[15] = 1.0 | |
| clean_audio_name = _SIDE_DECEPTIVE_SUB_STRIP_RE.sub(" ", name) | |
| clean_tok_h = _extract_token_hashes(clean_audio_name) | |
| ad = bool(_SIDE_ANIME_DUB_KW_RE.search(clean_audio_name)) or (grp_h in _DUAL_DUB_GRP_H) or bool(clean_tok_h & _DUAL_DUB_GRP_H) | |
| if ad: | |
| side[16] = 1.0 | |
| if (grp_h in _SUB_ONLY_GRP_H) and not ad: | |
| side[14] = 1.0 | |
| if has_game_grp: | |
| side[17] = 1.0 | |
| if has_sw_grp and not _SIDE_CJK_RE.search(name): | |
| side[18] = 1.0 | |
| if _SIDE_COURSE_RE.search(name) and not ag: | |
| side[19] = 1.0 | |
| if _SIDE_BOOK_COMIC_KW_RE.search(name) or has_book_grp: | |
| side[20] = 1.0 | |
| lang_str = (row.get("language") or "").strip().lower() | |
| if lang_str in ("ja", "ru", "fr", "es", "de", "it", "pt", "zh", "ko", "hi", "pl", "nl", "tr", "ar") or _SIDE_CJK_RE.search(name) or ((grp_h in _SUB_ONLY_GRP_H) and not ad): | |
| side[22] = 1.0 | |
| elif lang_str in ("en", "eng", "english") or ad: | |
| side[21] = 1.0 | |
| else: | |
| side[23] = 1.0 | |
| return { | |
| "name_bytes": raw_bytes, | |
| "ext": exts if exts else [0], | |
| "size": sizes if sizes else [0], | |
| "depth": depths if depths else [0], | |
| "words": words_list if words_list else [[0, 0, 0, 0]], | |
| "stats": base_stats + side, | |
| } | |
| def build_onnx_batch_inputs( | |
| rows: Sequence[Mapping[str, Any]], | |
| max_name_len: int = 256, | |
| max_files: int = 64, | |
| ) -> Dict[str, np.ndarray]: | |
| """Collate a sequence of torrent dicts into padded NumPy arrays for ONNX Runtime.""" | |
| encoded = [encode_torrent_features(r, max_name_len=max_name_len, max_files=max_files) for r in rows] | |
| bsz = len(encoded) | |
| max_l = max(len(e["name_bytes"]) for e in encoded) | |
| max_f = max(len(e["ext"]) for e in encoded) | |
| name_b = np.zeros((bsz, max_l), dtype=np.int64) | |
| name_l = np.zeros((bsz,), dtype=np.int64) | |
| ext_t = np.zeros((bsz, max_f), dtype=np.int32) | |
| size_t = np.zeros((bsz, max_f), dtype=np.int64) | |
| depth_t = np.zeros((bsz, max_f), dtype=np.int64) | |
| words_t = np.zeros((bsz, max_f, 4), dtype=np.int32) | |
| stats_t = np.zeros((bsz, 36), dtype=np.float32) | |
| for i, e in enumerate(encoded): | |
| lb = len(e["name_bytes"]) | |
| lf = len(e["ext"]) | |
| name_b[i, :lb] = e["name_bytes"] | |
| name_l[i] = lb | |
| ext_t[i, :lf] = e["ext"] | |
| size_t[i, :lf] = e["size"] | |
| depth_t[i, :lf] = e["depth"] | |
| words_t[i, :lf, :] = e["words"] | |
| stats_t[i, :] = e["stats"] | |
| return { | |
| "name_bytes": name_b, | |
| "name_len": name_l, | |
| "ext": ext_t, | |
| "size": size_t, | |
| "depth": depth_t, | |
| "words": words_t, | |
| "stats": stats_t, | |
| } | |
| def _softmax(logits: np.ndarray) -> np.ndarray: | |
| shifted = logits - np.max(logits, axis=-1, keepdims=True) | |
| exps = np.exp(shifted) | |
| return exps / np.sum(exps, axis=-1, keepdims=True) | |
| class ArmigerStandaloneONNX: | |
| """Self-contained ONNX Runtime classifier for `NorviTech/armiger` and `NorviTech/armiger-ultra`.""" | |
| def __init__( | |
| self, | |
| onnx_path: Optional[str | Path] = None, | |
| vocab_path: Optional[str | Path] = None, | |
| calibration_path: Optional[str | Path] = None, | |
| ) -> None: | |
| import onnxruntime as ort | |
| base = Path(__file__).resolve().parent | |
| if onnx_path is None: | |
| for cand in ("armiger.onnx", "armiger.int8.onnx", "armiger_ultra.fp32.onnx"): | |
| if (base / cand).exists(): | |
| onnx_path = base / cand | |
| break | |
| if onnx_path is None: | |
| raise FileNotFoundError("Could not find armiger.onnx or armiger_ultra.fp32.onnx") | |
| self.onnx_path = Path(onnx_path) | |
| default_vocab = base / "vocab.json" | |
| if not default_vocab.exists() and self.onnx_path.with_name("vocab.json").exists(): | |
| default_vocab = self.onnx_path.with_name("vocab.json") | |
| self.vocab_path = Path(vocab_path) if vocab_path else default_vocab | |
| _get_vocab_ext_map(self.vocab_path) | |
| self.calibration_path = Path(calibration_path) if calibration_path else (base / "calibration.json") | |
| self.session = ort.InferenceSession(str(self.onnx_path), providers=["CPUExecutionProvider"]) | |
| self.head_names = [o.name for o in self.session.get_outputs()] | |
| def _apply_v3_post_neural_guard(row: Mapping[str, Any], item_res: Dict[str, Any]) -> Dict[str, Any]: | |
| return _apply_v3_post_neural_guard(row, item_res) | |
| def predict_batch(self, rows: Sequence[Mapping[str, Any]]) -> List[Dict[str, Any]]: | |
| feed = build_onnx_batch_inputs(rows) | |
| raw_outs = self.session.run(self.head_names, feed) | |
| logits_by_head = dict(zip(self.head_names, raw_outs)) | |
| results: List[Dict[str, Any]] = [] | |
| for i in range(len(rows)): | |
| item_res: Dict[str, Any] = {"heads": {}, "probabilities": {}} | |
| for h, arr in logits_by_head.items(): | |
| vec = arr[i].astype(np.float64) | |
| if vec.ndim == 2: | |
| # 3D batch tensor (e.g. span_bio [B, 256, 7]) -> 2D per-item [256, 7] | |
| shifted = vec - np.max(vec, axis=-1, keepdims=True) | |
| exps = np.exp(shifted) | |
| probs_2d = exps / np.maximum(1e-12, np.sum(exps, axis=-1, keepdims=True)) | |
| raw_nm = str(rows[i].get("name") or rows[i].get("title") or "") | |
| try: | |
| from armiger.byte_span_extractor import decode_bio_logits_viterbi, decode_bio_tags_to_spans | |
| except ImportError: | |
| from byte_span_extractor import decode_bio_logits_viterbi, decode_bio_tags_to_spans | |
| raw_b = raw_nm.encode("utf-8", errors="replace")[: vec.shape[0]] | |
| tag_ids = [int(x) for x in decode_bio_logits_viterbi(vec, raw_b).tolist()] | |
| classes = NEURAL_HEAD_CLASSES.get( | |
| h, | |
| list(SPAN_BIO_CLASSES), | |
| ) | |
| tag_labels = [classes[idx_c] if idx_c < len(classes) else str(idx_c) for idx_c in tag_ids] | |
| item_res["heads"][h] = tag_labels | |
| mean_probs = np.mean(probs_2d, axis=0) | |
| item_res["probabilities"][h] = { | |
| classes[k]: round(float(mean_probs[k]), 6) for k in range(min(len(classes), len(mean_probs))) | |
| } | |
| try: | |
| item_res["span_bio"] = decode_bio_tags_to_spans(raw_nm, tag_ids) | |
| except Exception: | |
| item_res["span_bio"] = {"tag_ids": tag_ids, "tags": tag_labels} | |
| continue | |
| probs = _softmax(vec) | |
| classes = NEURAL_HEAD_CLASSES.get(h, [str(k) for k in range(len(probs))]) | |
| idx_c = int(np.argmax(probs)) | |
| item_res["heads"][h] = classes[idx_c] if idx_c < len(classes) else str(idx_c) | |
| item_res["probabilities"][h] = { | |
| classes[k]: round(float(probs[k]), 6) for k in range(min(len(classes), len(probs))) | |
| } | |
| self._apply_v3_post_neural_guard(rows[i], item_res) | |
| p_junk = item_res["probabilities"].get("junk", {}).get("junk", 0.0) | |
| p_adult = item_res["probabilities"].get("adult", {}).get("adult", 0.0) | |
| p_excl = ( | |
| 0.05 | |
| if item_res["heads"].get("owner_scope") == "allowed_type" | |
| else item_res["probabilities"].get("owner_scope", {}).get("excluded", 0.0) | |
| ) | |
| item_res["p_junk"] = p_junk | |
| item_res["mondrian_gates"] = { | |
| "adult_flagged": bool(p_adult >= 0.5451), | |
| "junk_flagged": bool(p_junk >= 0.1010), | |
| "scope_excluded": bool(p_excl >= 0.4770), | |
| "passed_all": bool(p_adult < 0.5451 and p_junk < 0.1010 and p_excl < 0.4770), | |
| } | |
| results.append(item_res) | |
| return results | |
| def predict(self, row: Mapping[str, Any]) -> Dict[str, Any]: | |
| return self.predict_batch([row])[0] | |
| ArmigerONNXClassifier = ArmigerStandaloneONNX | |
| _V3_COMIC_H = frozenset(['12b3f45e5ceb0c73', '4cecc3908b751508', '560dd703f14b3d39', 'd287a406b53d326d', 'f474f6ed1c868f32']) | |
| _V3_GAME_H = frozenset(['052648bca960e902', '49460c3a7ea1cb2a', '65a3e07111977e18', 'aeeacf8b695dceea', 'f9dd689e8c6d1cd8', 'fd75f166789586c3']) | |
| _V3_OPEN_MOVIE_H = frozenset(['0937eb719d20dd6f', '2e7c54d248a0ef1d', '4d0377a6e2563411', '710ab19297bbed0c', '82d861962967c61e', '97a97017505610c7', '9a8994e8f326412f', 'a320c9ca18122845', 'a82434472cd6c6fe', 'f5f35a2f45111a8e']) | |
| _V3_TV_SERIES_H = frozenset(['230aead54d362cda', '295b881a619e7cb5', '7e7f87fd43987c67', '7f9e0a2bfd52770c', '8ab671ca32f5d5cf', '9f7c0f5280ee75ec', 'c8564e035c0b75c1', 'e2b18ebba4070e03', 'f593bd44736fe5fe', 'fc1a22469a3f145d']) | |
| _V3_ANIME_POS_H = frozenset(['07ea6d84cdf8fd18', '14dc96e9b279ef41', '3f51640da58e3b42', '485b2fbd270bd1ed', '5fc43af228179edd', '7054ce850cad5308', 'a11c618db0e83f96', 'ad7e17f965645161', 'c46009e7f1b3c3af']) | |
| _V3_ANIME_MOVIE_H = frozenset(['14dc96e9b279ef41', '5fc43af228179edd', 'ad7e17f965645161', 'c46009e7f1b3c3af']) | |
| _V3_ANIME_NEG_H = frozenset(['0937eb719d20dd6f', '207ffe8422c5dccc', '43dc423c0f35206b', '4d0377a6e2563411', '52812423d8d44670', '710ab19297bbed0c', '7aa1e3930f50174a', '97a97017505610c7', 'a320c9ca18122845', 'a82434472cd6c6fe', 'b1444d914e2baca2', 'b249fb33aabf5c18']) | |
| _V3_NON_EN_AUDIO_H = frozenset(['07ea6d84cdf8fd18', '12c3d50880c16874', '16b7d611049fe70e', '207ffe8422c5dccc', '34924d18a0b6ed8b', '3f51640da58e3b42', '43dc423c0f35206b', '485b2fbd270bd1ed', '56e0d06e84a655c0', '5f1570e0f9eaacb8', '5fc43af228179edd', '69ca97bb99f505b5', '7054ce850cad5308', '75af437002546cd4', '7aa1e3930f50174a', '8406725ab8ae5378', '900a19dd73bdd4ba', '951625ff1ac61302', 'a11c618db0e83f96', 'a7ddaf4c9ddad893', 'a8d66ae84e768552', 'ad7e17f965645161', 'b1444d914e2baca2', 'b249fb33aabf5c18', 'dbfb8d1d57178337', 'e05fb6bafd7b47f1', 'eb5ac7a33ae81cf2', 'f2a4dad05c81ba2e', 'f6241861fb0c5d79']) | |
| _V3_NON_EN_TITLE_H = frozenset(['207ffe8422c5dccc', '43dc423c0f35206b', '5f1570e0f9eaacb8', '7aa1e3930f50174a', '951625ff1ac61302', 'b1444d914e2baca2', 'f6241861fb0c5d79']) | |
| _V3_SUBWORD_RE = re.compile(r"[A-Za-z0-9]+") | |
| def _extract_v3_hashes(text: str) -> frozenset[str]: | |
| base = set(_extract_token_hashes(text)) | |
| sub = [m.group(0).lower() for m in _V3_SUBWORD_RE.finditer(text)] | |
| for t in sub: | |
| base.add(_h64(t)) | |
| for i in range(len(sub) - 1): | |
| base.add(_h64(f"{sub[i]} {sub[i + 1]}")) | |
| return frozenset(base) | |
| def _apply_v3_post_neural_guard(row: Mapping[str, Any], item_res: Dict[str, Any]) -> Dict[str, Any]: | |
| """Apply Armiger v3.0 post-neural structural, cross-head, and subtitle-trap disambiguation.""" | |
| name = str(row.get("name") or row.get("title") or "").strip() | |
| raw_files = row.get("files") or [] | |
| fpaths: List[str] = [] | |
| for f in raw_files: | |
| p = str(f.get("path") or f.get("p") or f.get("name") or "") if isinstance(f, Mapping) else str(f or "") | |
| if p and "/.____padding_file/" not in p and not p.startswith(".____padding_file"): | |
| fpaths.append(p) | |
| all_text = name + " " + " ".join(fpaths[:32]) | |
| name_h = _extract_v3_hashes(name) | |
| all_h = _extract_v3_hashes(all_text) | |
| is_nested = "heads" in item_res and isinstance(item_res["heads"], dict) | |
| if is_nested: | |
| heads = item_res["heads"] | |
| probs = item_res.get("probabilities") or {} | |
| else: | |
| heads = { | |
| k: (v.get("label") if isinstance(v, Mapping) else str(v)) | |
| for k, v in item_res.items() | |
| if isinstance(v, (Mapping, str)) | |
| } | |
| probs = { | |
| k: {v.get("label", ""): float(v.get("confidence", 0.5))} | |
| for k, v in item_res.items() | |
| if isinstance(v, Mapping) and "label" in v | |
| } | |
| p_adult = float(probs.get("adult", {}).get("adult", 0.0)) | |
| # 1. Cross-head adult <-> category consistency: never predict 'xxx' when adult_flagged is False | |
| explicit_xxx = bool(re.search(r"(?i)\b(?:xxx|siterip|onlyfans|jav|fc2[-_ ]?ppv|18\+|nsfw)\b", name)) | |
| if heads.get("category") == "xxx" and p_adult < 0.5451 and not explicit_xxx: | |
| cat_probs = dict(probs.get("category") or {}) | |
| cat_probs["xxx"] = 0.0 | |
| cat_probs["unknown"] = min(float(cat_probs.get("unknown", 0.0)), 0.05) | |
| best_cat = max(cat_probs.items(), key=lambda kv: kv[1])[0] if cat_probs else "movie" | |
| heads["category"] = best_cat | |
| # 2. Structural & Domain Category Disambiguation (v3.0) | |
| if re.search(r"(?i)(?:\bMIT\d+[._]\d+|\bocw[-_]|_lec0?\d+\b|Lecture_0?\d+\b)", all_text) or _SIDE_COURSE_RE.search(name): | |
| heads["category"] = "course" | |
| elif re.search(r"(?i)\d{3,6}gut\b", all_text): | |
| heads["category"] = "ebook" | |
| elif (name_h & _V3_COMIC_H) or any( | |
| p.lower().endswith((".cbz", ".cbr", ".cb7", "_cloth_detection.log")) for p in fpaths | |
| ): | |
| heads["category"] = "comic" | |
| elif name_h & _V3_GAME_H: | |
| heads["category"] = "game" | |
| elif name_h & _V3_OPEN_MOVIE_H: | |
| heads["category"] = "movie" | |
| heads["anime"] = "non_anime" | |
| elif (all_h & _V3_TV_SERIES_H) or re.search( | |
| r"(?i)(?:\bS\d{1,2}E\d{1,3}\b|\b\d{1,2}Chapters\b|_ch01\.|\bPart\s*1\b.*\bInterviews\b|\btv-series\b)", | |
| all_text, | |
| ): | |
| heads["category"] = "tv_show" | |
| elif heads.get("category") == "unknown" and any(p.lower().endswith((".mp4", ".mkv", ".avi", ".mov")) for p in fpaths): | |
| heads["category"] = "movie" | |
| # 3. Anime Precision & Recall Guard (v3.0) | |
| if all_h & _V3_ANIME_POS_H: | |
| heads["anime"] = "anime" | |
| if all_h & _V3_ANIME_MOVIE_H: | |
| heads["category"] = "movie" | |
| elif all_h & _V3_ANIME_NEG_H: | |
| heads["anime"] = "non_anime" | |
| # 4. External Subtitle Inventory & Subtitle-Trap Guard (english_subs & lang) | |
| real_subs = [ | |
| p for p in fpaths | |
| if p.lower().endswith((".srt", ".vtt", ".ass")) | |
| and not p.lower().endswith((".asr.srt", ".autogenerated.vtt", ".asr.js")) | |
| ] | |
| has_non_en_sub_only_tag = bool(re.search(r"(?i)\b(?:vostfr|vose|subfrench|napisy[._ -]*pl|czuntertitel)\b", all_text)) | |
| has_en_sub_tag = bool(re.search(r"(?i)\b(?:english[._ -]*sub(?:bed|s)?|eng[._ -]*subs?|esubs?)\b", all_text)) | |
| if real_subs: | |
| if any(re.search(r"(?i)(?:english|\.en\.|\.eng\.|ocw-|mit\d|lec\d|^L\d{2}-)", Path(p).name) for p in real_subs) or not has_non_en_sub_only_tag: | |
| heads["english_subs"] = "has_eng_subs" | |
| else: | |
| heads["english_subs"] = "no_eng_subs" | |
| elif has_en_sub_tag: | |
| heads["english_subs"] = "has_eng_subs" | |
| elif has_non_en_sub_only_tag: | |
| heads["english_subs"] = "no_eng_subs" | |
| # 5. Spoken Language & Subtitle-Trap Audio Disambiguation (lang & title_language) | |
| name_no_sub = _SIDE_DECEPTIVE_SUB_STRIP_RE.sub(" ", name) | |
| has_explicit_en_audio = bool( | |
| _SIDE_ANIME_DUB_KW_RE.search(name) | |
| or re.search( | |
| r"(?i)(?:\b(?:eng|english)\b|[\[\(\.\s_-]EN[\]\)\.\s_-]|\b[34]audio\b)", | |
| name_no_sub, | |
| ) | |
| ) | |
| has_foreign_context = ( | |
| heads.get("anime") == "anime" | |
| or heads.get("title_language") == "non_english_title" | |
| or bool(name_h & _V3_NON_EN_TITLE_H) | |
| or bool(_SIDE_CJK_RE.search(name)) | |
| or bool( | |
| re.search( | |
| r"(?i)\b(?:ita|ger|deu|fre|fra|rus|spa|esp|jpn|jap|kor|chi|hin|dut|nl|por|pol|tur|vostfr|vose)\b", | |
| name_no_sub, | |
| ) | |
| ) | |
| ) | |
| is_sub_only_trap = has_en_sub_tag and not has_explicit_en_audio and has_foreign_context | |
| if is_sub_only_trap or bool(all_h & _V3_NON_EN_AUDIO_H): | |
| heads["lang"] = "non_english" | |
| if name_h & _V3_NON_EN_TITLE_H: | |
| heads["title_language"] = "non_english_title" | |
| elif heads.get("lang") == "multi_or_unknown" and heads.get("title_language") == "english_title" and heads.get("anime") == "non_anime": | |
| if heads.get("category") in ("movie", "tv_show", "audiobook", "course"): | |
| heads["lang"] = "english" | |
| # 6. Byte-Span Clean Title & Release Year Extraction | |
| m_yr = re.search(r"(?<![\dA-Za-z])(19[2-9]\d|20[0-2]\d)(?![\dA-Za-z])", name) | |
| rel_year = int(m_yr.group(1)) if m_yr else None | |
| clean_t = re.sub(r"\.(?:mkv|mp4|avi|iso|zip|rar|epub|pdf|mp3|flac)$", "", name, flags=re.I) | |
| if m_yr and m_yr.start() >= 2: | |
| clean_t = clean_t[:m_yr.start()] | |
| elif m_yr and m_yr.start() == 0: | |
| clean_t = clean_t[m_yr.end():] | |
| clean_t = re.sub(r"(?i)\b(?:1080p|720p|2160p|480p|vose|vostfr|english[._ -]*subbed|eng[._ -]*subs?)\b.*$", "", clean_t) | |
| clean_t = re.sub(r"[._-]+", " ", clean_t).strip() | |
| if not is_nested: | |
| for k, v in heads.items(): | |
| if k in item_res and isinstance(item_res[k], dict): | |
| item_res[k]["label"] = v | |
| else: | |
| item_res[k] = {"label": v, "confidence": 0.95} | |
| item_res["matching_identity"] = { | |
| "clean_title": clean_t or name, | |
| "release_year": rel_year, | |
| } | |
| p_junk = float(probs.get("junk", {}).get("junk", 0.0)) | |
| if heads.get("category") in ("movie", "tv_show") and p_adult < 0.5451 and p_junk < 0.1010: | |
| heads["owner_scope"] = "allowed_type" | |
| else: | |
| heads["owner_scope"] = "excluded" | |
| if not is_nested and "owner_scope" in item_res and isinstance(item_res["owner_scope"], dict): | |
| item_res["owner_scope"]["label"] = heads["owner_scope"] | |
| if is_nested: | |
| item_res["category"] = heads.get("category", "unknown") | |
| return item_res | |