mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-04 23:17:20 +08:00
fix: 清理音乐刮削结果中 album_type 等字段的尾部空格 (#6327)
MusicBrainz 和 ListenBrainz 模块从 API 响应中提取 album_type、 secondary_types 时直接使用 dict.get() 取值,未做 strip() 处理, 导致部分结果带有尾部空格(如 'Album '、'Broadcast ')。 修复: - MusicBrainz 新增 _stripped() 工具方法,3 处 album_type 赋值统一清理 - ListenBrainz 新增 _stripped() 工具方法,_fresh_release_to_info 中清理 - Pydantic schema 层增加 field_validator 作为兜底安全网 - 新增 9 个回归测试覆盖所有场景
This commit is contained in:
@@ -265,10 +265,9 @@ class ListenBrainzModule(_ModuleBase):
|
||||
return None
|
||||
artist_name = str(release.get("artist_credit_name") or "").strip()
|
||||
release_date = release.get("release_date") or None
|
||||
category_parts = [
|
||||
release.get("release_group_primary_type"),
|
||||
release.get("release_group_secondary_type"),
|
||||
]
|
||||
primary_type = cls._stripped(release.get("release_group_primary_type"))
|
||||
secondary_type = cls._stripped(release.get("release_group_secondary_type"))
|
||||
category_parts = [primary_type, secondary_type]
|
||||
return MusicInfo(
|
||||
media_source=cls._source,
|
||||
media_id=str(media_id),
|
||||
@@ -279,12 +278,12 @@ class ListenBrainzModule(_ModuleBase):
|
||||
album=str(title),
|
||||
album_artist=artist_name or None,
|
||||
album_id=str(media_id),
|
||||
album_type=release.get("release_group_primary_type") or None,
|
||||
album_type=primary_type,
|
||||
year=cls._year(release_date),
|
||||
release_date=release_date,
|
||||
cover_url=cls._release_cover(release.get("caa_release_mbid"))
|
||||
or cls._release_group_cover(media_id),
|
||||
category=" / ".join(str(part) for part in category_parts if part),
|
||||
category=" / ".join(part for part in category_parts if part),
|
||||
genres=[str(tag) for tag in release.get("release_tags") or [] if tag],
|
||||
names=[str(title)],
|
||||
detail_link=f"{cls._album_detail_url}/{media_id}",
|
||||
@@ -321,6 +320,12 @@ class ListenBrainzModule(_ModuleBase):
|
||||
return []
|
||||
return [str(artist_mbids[0])] if artist_mbids and artist_mbids[0] else []
|
||||
|
||||
@staticmethod
|
||||
def _stripped(value: Any) -> Optional[str]:
|
||||
"""去除 ListenBrainz 响应字段两端的空白,空值返回 None。"""
|
||||
text = str(value).strip() if value is not None else ""
|
||||
return text or None
|
||||
|
||||
@staticmethod
|
||||
def _year(release_date: Any) -> Optional[int]:
|
||||
"""从 ListenBrainz 发行日期提取年份。"""
|
||||
|
||||
@@ -729,8 +729,8 @@ class MusicBrainzModule(_ModuleBase):
|
||||
title=str(title),
|
||||
artists=artists,
|
||||
artist_ids=artist_ids,
|
||||
album_type=release_group.get("primary-type"),
|
||||
secondary_types=[str(item) for item in release_group.get("secondary-types") or []],
|
||||
album_type=cls._stripped(release_group.get("primary-type")),
|
||||
secondary_types=[cls._stripped(item) for item in release_group.get("secondary-types") or [] if cls._stripped(item)],
|
||||
release_date=detail.get("date") or None,
|
||||
cover_url=cls._build_cover_url(group_id),
|
||||
genres=cls._names_of(detail.get("genres")),
|
||||
@@ -1387,8 +1387,8 @@ class MusicBrainzModule(_ModuleBase):
|
||||
album = (release or {}).get("title")
|
||||
artists, artist_ids = cls._artist_credits(recording.get("artist-credit"))
|
||||
album_artists, _ = cls._artist_credits((release or {}).get("artist-credit"))
|
||||
category_parts = [release_group.get("primary-type")]
|
||||
category_parts.extend(release_group.get("secondary-types") or [])
|
||||
category_parts = [cls._stripped(release_group.get("primary-type"))]
|
||||
category_parts.extend(cls._stripped(item) for item in release_group.get("secondary-types") or [])
|
||||
return MusicInfo(
|
||||
media_source=cls._source,
|
||||
media_id=str(media_id),
|
||||
@@ -1398,7 +1398,7 @@ class MusicBrainzModule(_ModuleBase):
|
||||
album=album,
|
||||
album_artist=" / ".join(album_artists) if album_artists else None,
|
||||
album_id=str(release_group["id"]) if release_group.get("id") else None,
|
||||
album_type=release_group.get("primary-type"),
|
||||
album_type=cls._stripped(release_group.get("primary-type")),
|
||||
year=cls._year(release_date),
|
||||
release_date=release_date,
|
||||
duration=cls._duration_seconds(recording.get("length")),
|
||||
@@ -1427,8 +1427,8 @@ class MusicBrainzModule(_ModuleBase):
|
||||
title=str(title),
|
||||
artists=artists,
|
||||
artist_ids=artist_ids,
|
||||
album_type=release_group.get("primary-type"),
|
||||
secondary_types=[str(item) for item in release_group.get("secondary-types") or []],
|
||||
album_type=cls._stripped(release_group.get("primary-type")),
|
||||
secondary_types=[cls._stripped(item) for item in release_group.get("secondary-types") or [] if cls._stripped(item)],
|
||||
release_date=release_group.get("first-release-date") or None,
|
||||
cover_url=cls._build_cover_url(media_id),
|
||||
genres=cls._names_of(release_group.get("genres")),
|
||||
@@ -1627,6 +1627,12 @@ class MusicBrainzModule(_ModuleBase):
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _stripped(value: Any) -> Optional[str]:
|
||||
"""去除 MusicBrainz 响应字段两端的空白,空值返回 None。"""
|
||||
text = str(value).strip() if value is not None else ""
|
||||
return text or None
|
||||
|
||||
@staticmethod
|
||||
def _optional_int(value: Any) -> Optional[int]:
|
||||
"""将 MusicBrainz 的碟号、音轨号等计数字段转换为可选整数。"""
|
||||
|
||||
Reference in New Issue
Block a user