MP MetaInfo + TheMovieDbModule name matching vs parse/recall/resolveIdentity, TMDB responses replayed offline; includes the category-alias misbinding regression from the user stack. Co-Authored-By: Claude Opus 5.5 <[email protected]>
97 lines
3.4 KiB
Python
97 lines
3.4 KiB
Python
"""身份匹配差分:用 MP 上游 MetaInfo + TheMovieDbModule 的名称识别链生成 mp.json。
|
|
|
|
用法(MP 仓库根目录,用其 .venv;TMDB 走本地缓存代理,见 docs/porting/moviepilot-identity-match.md):
|
|
cd /opt/moviepilot-plus/upstream/MoviePilot && PYTHONPATH=. TMDB_PROXY=http://127.0.0.1:18731 \
|
|
.venv/bin/python /opt/uhd_media_tool/packages/domain/test/differential/identity/gen-identity-mp.py
|
|
|
|
按 MP 实际识别顺序:MetaInfo(title, subtitle) → _prepare_search_names(cn_name, 简体 cn_name, en_name)
|
|
→ 逐个名称 _search_by_name(_build_match_plan:电视剧 [季年份+年份, 无年份];其他 [电影+年份, 电视剧+年份, multi])。
|
|
不含识别缓存、插件辅助识别与详情补全(只取匹配到的 id/类型/名称/年份)。只记录行为输出,不复制 MP 源码。
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import pathlib
|
|
import subprocess
|
|
|
|
from app.domain.metainfo import MetaInfo
|
|
from app.modules.themoviedb import TheMovieDbModule
|
|
from app.modules.themoviedb.tmdbapi import TmdbApi
|
|
from app.modules.themoviedb.tmdbv3api import tmdb as tmdb_mod
|
|
|
|
HERE = pathlib.Path(__file__).parent
|
|
PROXY = os.environ.get("TMDB_PROXY", "http://127.0.0.1:18731")
|
|
|
|
|
|
def _build_url(self, action, params=""):
|
|
return "%s/3%s?api_key=x&%s&language=%s" % (PROXY, action, params, self.language)
|
|
|
|
|
|
tmdb_mod.TMDb._build_url = _build_url
|
|
|
|
samples = json.loads((HERE / "samples.json").read_text(encoding="utf-8"))["samples"]
|
|
if os.environ.get("LIMIT"):
|
|
samples = samples[: int(os.environ["LIMIT"])]
|
|
# 只需名称匹配链:不走 init_module(识别缓存/分类配置需要启动层)
|
|
module = TheMovieDbModule.__new__(TheMovieDbModule)
|
|
module.tmdb = TmdbApi()
|
|
|
|
|
|
def val(v):
|
|
return getattr(v, "value", v)
|
|
|
|
|
|
def run(s: dict) -> dict:
|
|
meta = MetaInfo(s["title"], s.get("subtitle"))
|
|
out = {
|
|
"meta": {
|
|
"name": meta.name,
|
|
"cn_name": meta.cn_name,
|
|
"en_name": meta.en_name,
|
|
"year": meta.year,
|
|
"type": val(meta.type),
|
|
"begin_season": meta.begin_season,
|
|
"begin_episode": meta.begin_episode,
|
|
},
|
|
"names": module._prepare_search_names(meta),
|
|
"match": None,
|
|
}
|
|
if not meta.name:
|
|
return out
|
|
for name in out["names"]:
|
|
info = module._search_by_name(name, meta, [])
|
|
if info:
|
|
mtype = val(info.get("media_type"))
|
|
mtype = "movie" if mtype in ("movie", "电影") else "tv"
|
|
date = info.get("release_date") or info.get("first_air_date") or ""
|
|
out["match"] = {
|
|
"by": name,
|
|
"tmdbId": info.get("id"),
|
|
"type": mtype,
|
|
"title": info.get("title") or info.get("name"),
|
|
"year": int(date[:4]) if date[:4].isdigit() else None,
|
|
}
|
|
break
|
|
return out
|
|
|
|
|
|
result = {}
|
|
for s in samples:
|
|
try:
|
|
result[s["id"]] = run(s)
|
|
except Exception as e: # noqa: BLE001
|
|
result[s["id"]] = {"error": f"{type(e).__name__}: {e}"}
|
|
|
|
commit = subprocess.run(["git", "rev-parse", "--short", "HEAD"], capture_output=True, text=True).stdout.strip()
|
|
(HERE / "mp.json").write_text(
|
|
json.dumps(
|
|
{"generatedFrom": {"repo": "MoviePilot", "commit": commit, "entry": "MetaInfo + TheMovieDbModule._search_by_name"},
|
|
"results": result},
|
|
ensure_ascii=False,
|
|
indent=1,
|
|
)
|
|
+ "\n",
|
|
encoding="utf-8",
|
|
)
|
|
print(len(result))
|