From 6ef8408f432dde643aee2ba7078f59d2776f84ce Mon Sep 17 00:00:00 2001 From: jxxghp Date: Mon, 12 Oct 2026 17:49:40 +0800 Subject: [PATCH] fix(bangumi): merge tmdb classification metadata for aux source (#6968) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bangumi 等主识别源缺少 original_language/origin_country 标准字段,引用这些字段的分类规则整体失效并落入未分类;TMDB 辅助补充已有 genre_ids 合并,补齐语言与国家标准字段,仅填充主来源缺失值。 --- app/chain/media/auxiliary.py | 9 +++++ tests/test_tmdb_auxiliary.py | 73 ++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/app/chain/media/auxiliary.py b/app/chain/media/auxiliary.py index 77c65b15c..c53bd50b1 100644 --- a/app/chain/media/auxiliary.py +++ b/app/chain/media/auxiliary.py @@ -42,6 +42,15 @@ class MediaAuxiliaryOwner(_MediaOwnerBase): mediainfo.tmdb_info = tmdb_media.tmdb_info or mediainfo.tmdb_info if not mediainfo.genre_ids: mediainfo.genre_ids = list(tmdb_media.genre_ids or []) + # Bangumi/AniList 等主来源没有语言与国家标准字段,引用这些字段的 + # 分类规则会整体失效并落入未分类;已关联 TMDB 详情时补齐标准事实, + # 仅填充主来源缺失的字段,不覆盖主来源自身的投影。 + if not mediainfo.original_language: + mediainfo.original_language = tmdb_media.original_language + if not mediainfo.origin_country: + mediainfo.origin_country = list(tmdb_media.origin_country or []) + if not mediainfo.production_countries: + mediainfo.production_countries = list(tmdb_media.production_countries or []) for field in ("imdb_id", "tvdb_id", "tvdb_slug", "collection_id"): if not getattr(mediainfo, field, None): setattr(mediainfo, field, getattr(tmdb_media, field, None)) diff --git a/tests/test_tmdb_auxiliary.py b/tests/test_tmdb_auxiliary.py index d43dddb77..7fca051bc 100644 --- a/tests/test_tmdb_auxiliary.py +++ b/tests/test_tmdb_auxiliary.py @@ -3,6 +3,7 @@ from types import SimpleNamespace from unittest.mock import Mock, patch from app.chain.media import MediaChain +from app.domain.classification.facts import build_classification_facts from app.domain.context import MediaInfo from app.domain.metainfo import MetaInfo from app.runtime.extensions.module.dispatcher import ModuleInvocationDispatcher @@ -135,6 +136,78 @@ def test_supplement_tmdb_does_not_override_custom_category() -> None: assert result.tmdb_id == 9876 +def test_supplement_tmdb_merges_classification_metadata_for_bangumi_primary() -> None: + """Bangumi 主识别缺少语言与国家时,必须从关联 TMDB 详情补齐分类标准字段。""" + primary = MediaInfo( + bangumi_info={ + "id": 378862, + "name": "お兄ちゃんはおしまい!", + "name_cn": "别当欧尼酱了!", + "platform": "TV", + "date": "2023-01-05", + } + ) + tmdb_media = MediaInfo( + tmdb_info={ + "id": 198152, + "media_type": MediaType.TV, + "name": "别当欧尼酱了!", + "first_air_date": "2023-01-05", + "genre_ids": [16], + "original_language": "ja", + "origin_country": ["JP"], + } + ) + + result = _make_chain(tmdb_media).supplement_tmdb_info(primary) + + assert result is primary + assert result.media_source == MediaSource.Bangumi + assert result.media_id == "378862" + assert result.tmdb_id == 198152 + assert result.genre_ids == [16] + assert result.original_language == "ja" + assert result.origin_country == ["JP"] + # 分类事实必须能读到补充后的语言与国家,规则才能命中而不是落入未分类。 + facts = build_classification_facts(result) + assert facts.media.language == "ja" + assert facts.media.countries == ["JP"] + assert facts.media.genre_keys == ["animation"] + + +def test_supplement_tmdb_keeps_primary_language_and_country_fields() -> None: + """主来源已有的语言与国家标准字段不被 TMDB 辅助结果覆盖。""" + primary = MediaInfo( + media_source=MediaSource.Douban, + media_id="35593344", + type=MediaType.MOVIE, + title="测试电影", + original_language="zh", + origin_country=["CN"], + production_countries=[{"iso_3166_1": "CN", "name": "中国大陆"}], + ) + tmdb_media = MediaInfo( + tmdb_info={ + "id": 9876, + "media_type": MediaType.MOVIE, + "title": "Test Movie", + "genre_ids": [28], + "original_language": "en", + "origin_country": ["US"], + "production_countries": [{"iso_3166_1": "US", "name": "United States"}], + } + ) + + result = _make_chain(tmdb_media).supplement_tmdb_info(primary) + + assert result is primary + assert result.original_language == "zh" + assert result.origin_country == ["CN"] + assert result.production_countries == [{"iso_3166_1": "CN", "name": "中国大陆"}] + # 主来源缺失的流派仍按原语义补齐。 + assert result.genre_ids == [28] + + def test_tmdb_supplement_uses_current_season_year_and_keeps_season_zero() -> None: """电视剧优先使用当前季年份,并且特别季季号不能退化为空。""" media = MediaInfo(