"""命名模板差分:用 MP 上游(MetaInfo + TemplateContextBuilder + jinja2.Template)生成 naming-mp.json。 用法(MP 仓库根目录,用其 .venv): cd /opt/moviepilot-plus/upstream/MoviePilot && PYTHONPATH=. \ .venv/bin/python /opt/uhd_media_tool/packages/domain/test/differential/gen-naming-mp.py 只记录行为输出,不复制 MP 源码。默认模板取 settings.RENAME_FORMAT(与 MP 规范化一致); MP 没有综艺类型,综艺样例用剧集类型渲染我们的模板(预期 MP 报错,属我们特有)。 """ import json import pathlib import subprocess from pathlib import PurePosixPath from jinja2 import Template from app.application.messaging.message import TemplateHelper from app.core.config import settings from app.core.context import MediaInfo from app.core.metainfo import MetaInfo from app.schemas.types import MediaType HERE = pathlib.Path(__file__).parent cases = json.loads((HERE / "naming-cases.json").read_text(encoding="utf-8"))["cases"] def normalize_template(s: str) -> str: # 同 settings.RENAME_FORMAT:\ → /,合并 /,去首尾 / import re s = s.replace("\\", "/") s = re.sub(r"/+", "/", s) return s.strip("/") def run(case: dict) -> dict: kind = case["kind"] mtype = MediaType.MOVIE if kind == "movie" else MediaType.TV meta = MetaInfo(case["fileName"]) if mtype == MediaType.TV and meta.begin_episode is not None: # transhandler.plan_transfer:单文件 3 集及以上截成首集 meta.end_season = None if meta.total_season: meta.total_season = 1 if meta.total_episode > 2: meta.total_episode = 1 meta.end_episode = None e = case["entity"] mi = MediaInfo() mi.type = mtype mi.title = e["title"] mi.year = str(e["year"]) if e.get("year") else None mi.en_title = e.get("enTitle") mi.original_title = e.get("originalTitle") mi.category = e.get("category", "") if e.get("tmdbId") is not None: mi.tmdb_id = e["tmdbId"] ext = "." + case["fileName"].rsplit(".", 1)[1] ctx = TemplateHelper().builder.build(meta=meta, mediainfo=mi, file_extension=ext, include_raw_objects=False) ctx.pop("media_source", None) ctx.pop("media_id", None) ctx.update(case.get("vars") or {}) tpl = case.get("template") or settings.RENAME_FORMAT(mtype) try: out = Template(normalize_template(tpl)).render(ctx) except Exception as ex: # noqa: BLE001 - 记录 MP 的报错 return {"error": f"{type(ex).__name__}: {ex}"} return {"path": str(PurePosixPath(out))} def main() -> None: commit = subprocess.run(["git", "rev-parse", "--short", "HEAD"], capture_output=True, text=True).stdout.strip() result = {"generatedFrom": {"repo": "MoviePilot", "commit": commit}, "mp": {c["id"]: run(c) for c in cases}} (HERE / "naming-mp.json").write_text(json.dumps(result, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") print(f"wrote {len(cases)} cases") if __name__ == "__main__": main()