修复极影视媒体库同步不全:展开 BoxSet 合集子项 (#5954)

This commit is contained in:
ch3njun
2026-06-16 06:35:58 +08:00
committed by GitHub
parent 8ad8b5eaad
commit 1c60d8ccd7
2 changed files with 110 additions and 5 deletions

View File

@@ -848,7 +848,14 @@ class ZSpace:
result = res.json() or {}
items = result.get("Items") or []
for item in items:
if not item or item.get("Type") not in ["Movie", "Series"]:
if not item:
continue
if item.get("Type") == "BoxSet" and item.get("Id"):
for sub_item in self.get_items(parent=item.get("Id")):
if sub_item:
yield sub_item
continue
if item.get("Type") not in ["Movie", "Series"]:
continue
provider_ids = item.get("ProviderIds") or {}
needs_detail = (

View File

@@ -25,7 +25,7 @@ def _build_client() -> ZSpace:
def test_get_items_fetches_all_recursive_pages() -> None:
"""全量同步应递归查询并持续翻页,且忽略合集外壳"""
"""全量同步应递归查询并持续翻页,且忽略非媒体条目"""
client = _build_client()
responses = [
_FakeResponse({
@@ -39,9 +39,9 @@ def test_get_items_fetches_all_recursive_pages() -> None:
"Path": "/media/movie-1.mkv",
},
{
"Id": "collection-1",
"Type": "BoxSet",
"Name": "电影合集",
"Id": "audio-1",
"Type": "Audio",
"Name": "音频一",
},
],
"TotalRecordCount": 3,
@@ -76,6 +76,104 @@ def test_get_items_fetches_all_recursive_pages() -> None:
assert calls[1].kwargs["params"]["Limit"] == 2
def test_get_items_expands_boxset_movies() -> None:
"""电影合集应向下查询并返回全部子电影。"""
client = _build_client()
responses = [
_FakeResponse({
"Items": [{
"Id": "collection-1",
"Type": "BoxSet",
"Name": "疯狂动物城(系列)",
}],
"TotalRecordCount": 1,
}),
_FakeResponse({
"Items": [
{
"Id": "movie-1",
"Type": "Movie",
"Name": "疯狂动物城",
"ProductionYear": None,
"ProviderIds": {},
"Path": "",
},
{
"Id": "movie-2",
"Type": "Movie",
"Name": "疯狂动物城2",
"ProductionYear": 2025,
"ProviderIds": {"Tmdb": "1084242"},
"Path": "/media/疯狂动物城2.mkv",
},
],
"TotalRecordCount": 2,
}),
_FakeResponse({
"Id": "movie-1",
"ParentId": "collection-1",
"Type": "Movie",
"Name": "疯狂动物城",
"ProductionYear": 2016,
"ProviderIds": {"Tmdb": "269149"},
"Path": "/media/疯狂动物城.mkv",
}),
]
with patch("app.modules.zspace.zspace.RequestUtils") as request_utils_cls:
request_utils_cls.return_value.get_res.side_effect = responses
items = list(client.get_items(parent="library-id"))
assert [item.item_id for item in items] == ["movie-1", "movie-2"]
assert [item.tmdbid for item in items] == [269149, 1084242]
calls = request_utils_cls.return_value.get_res.call_args_list
assert calls[0].kwargs["params"]["Recursive"] == "true"
assert calls[1].kwargs["params"]["ParentId"] == "collection-1"
def test_get_items_expands_boxset_series() -> None:
"""电视剧合集应向下展开并返回全部子 Series。"""
client = _build_client()
responses = [
_FakeResponse({
"Items": [{
"Id": "collection-1",
"Type": "BoxSet",
"Name": "绝命毒师",
}],
"TotalRecordCount": 1,
}),
_FakeResponse({
"Items": [
{
"Id": "series-1",
"Type": "Series",
"Name": "绝命毒师 第 1 季",
"ProductionYear": 2008,
"ProviderIds": {"Tmdb": "1396"},
"Path": "/media/绝命毒师/Season 1",
},
{
"Id": "series-2",
"Type": "Series",
"Name": "绝命毒师 第 2 季",
"ProductionYear": 2009,
"ProviderIds": {"Tmdb": "1396"},
"Path": "/media/绝命毒师/Season 2",
},
],
"TotalRecordCount": 2,
}),
]
with patch("app.modules.zspace.zspace.RequestUtils") as request_utils_cls:
request_utils_cls.return_value.get_res.side_effect = responses
items = list(client.get_items(parent="library-id"))
assert [item.item_id for item in items] == ["series-1", "series-2"]
assert [item.tmdbid for item in items] == [1396, 1396]
def test_get_items_loads_detail_when_list_metadata_is_incomplete() -> None:
"""列表项缺少关键元数据时应使用详情接口补全。"""
client = _build_client()