From edc15e957549f800f998a1c340dc133626f30b14 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 6 Sep 2026 14:54:44 +0800 Subject: [PATCH] fix: recognize parenthesized tmdb ids --- app/domain/metainfo.py | 10 +++++++++- tests/test_anime_source_metainfo.py | 12 ++++++++++++ tests/test_metainfo.py | 10 ++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/domain/metainfo.py b/app/domain/metainfo.py index 989f826c3..f340c1b9f 100644 --- a/app/domain/metainfo.py +++ b/app/domain/metainfo.py @@ -51,6 +51,12 @@ _EMBY_TMDB_RE_LIST = ( re.compile(r'\[tmdb[=\-](\d+)\]'), re.compile(r'\{tmdbid[=\-](\d+)\}'), re.compile(r'\{tmdb[=\-](\d+)\}'), + re.compile(r'\(tmdbid[=\-]\s*(\d+)\s*\)', re.IGNORECASE), + re.compile(r'\(tmdb[=\-]\s*(\d+)\s*\)', re.IGNORECASE), +) +_PARENTHESIZED_TMDB_RE = re.compile( + r'\(tmdb(?:id)?[=\-]\s*\d+\s*\)', + re.IGNORECASE, ) _EXTENDED_MEDIA_ID_RE_LIST = { "bangumi": ( @@ -232,7 +238,7 @@ def _find_metainfo_python(title: str) -> Tuple[str, dict]: ): title = title.replace(f"{{[{result}]}}", '') - # 支持Emby格式的ID标签;第一个 [tmdbid] 历史上始终优先处理,用于覆盖前面 {[...]} 中的旧标签。 + # 支持 Emby 格式及常见圆括号格式的 ID 标签;第一个 [tmdbid] 历史上始终优先处理,用于覆盖前面 {[...]} 中的旧标签。 tmdb_match = _EMBY_TMDB_RE_LIST[0].search(title) if tmdb_match: if tmdb_match.group(1) != "0": @@ -482,6 +488,8 @@ def _requires_python_metainfo( candidates = [title or "", *(custom_words or [])] if any(_GENERIC_MEDIA_ID_TAG_RE.search(candidate) for candidate in candidates): return True + if any(_PARENTHESIZED_TMDB_RE.search(candidate) for candidate in candidates): + return True contains_extended_id = any( _EXTENDED_MEDIA_ID_TAG_RE.search(candidate) for candidate in candidates ) diff --git a/tests/test_anime_source_metainfo.py b/tests/test_anime_source_metainfo.py index 11f6d74b1..3ddf2efaa 100644 --- a/tests/test_anime_source_metainfo.py +++ b/tests/test_anime_source_metainfo.py @@ -56,6 +56,18 @@ def test_metainfo_path_inherits_bangumi_id_from_parent() -> None: assert meta.begin_episode == 1 +def test_parenthesized_tmdb_id_uses_python_fallback_for_old_rust() -> None: + """旧 Rust 扩展不识别圆括号 TMDB 标签时应回退到 Python 解析。""" + with patch( + "app.adapters.system.rust.parse_metainfo_path", + side_effect=AssertionError("旧 Rust 扩展不应处理圆括号 TMDB 标签"), + ): + meta = MetaInfoPath(Path("/movies/狩猎 (2022) (tmdb-727340)/狩猎.mkv")) + + assert meta.media_source == "themoviedb" + assert meta.media_id == "727340" + + def test_extended_ids_fall_back_when_installed_rust_is_old() -> None: """当前Rust扩展缺少新字段时应直接使用Python解析器。""" with patch( diff --git a/tests/test_metainfo.py b/tests/test_metainfo.py index d3ebc4029..825cade59 100644 --- a/tests/test_metainfo.py +++ b/tests/test_metainfo.py @@ -74,6 +74,7 @@ def test_emby_format_ids(): 1399, ), ("/movies/Avatar (2009) {tmdb-19995}/Avatar.2009.1080p.mkv", 19995), + ("/movies/狩猎 (2022) (tmdb-727340)/狩猎.mkv", 727340), ] for path_str, expected_media_id in test_paths: @@ -688,6 +689,15 @@ def test_emby_tmdbid_overrides_braced_metainfo_tmdbid(): assert "[tmdbid=222]" not in title +def test_parenthesized_tmdb_id_is_extracted_from_title(): + """测试圆括号 TMDB 标签可从标题中提取并移除。""" + title, metainfo = find_metainfo("狩猎 (2022) (tmdb-727340)") + + assert title.strip() == "狩猎 (2022)" + assert metainfo["media_source"] == MediaSource.TMDB + assert metainfo["media_id"] == "727340" + + def test_custom_identifier_uses_source_specific_id_and_returns_unified_identity(): """自定义识别词使用专用ID语法,解析结果仍转换为统一身份。""" title, metainfo = find_metainfo(