fix(music): strip Gazelle slash-separated release specs

This commit is contained in:
jxxghp
2026-10-20 12:09:50 +08:00
parent 80a92ddb29
commit d0f70e45eb
3 changed files with 58 additions and 2 deletions

View File

@@ -239,6 +239,15 @@ _MUSIC_FORMAT_TOKEN_ALT = (
r"DSD(?:64|128|256|512)?|DSF|DFF|SACD|FLAC|ALAC|APE|CUE|WAV|WAVE|AIFF?|PCM|"
r"MP3|AAC|M4A|OGG|VORBIS|OPUS|WMA|WEB-?DL|WEBRip|WEB"
)
# Gazelle 将音质、抓轨日志、介质与年份串成斜杠尾链。只匹配完整规格尾链,
# 避免删除作品正文中的斜杠、CD 或 Log;末尾年份仍交由解析器提取。
_MUSIC_SLASH_SPEC_TAIL_RE = re.compile(
rf"\s+(?:{_MUSIC_FORMAT_TOKEN_ALT})"
rf"(?:\s*/\s*(?:{_MUSIC_FORMAT_TOKEN_ALT}|lossless|Log(?:\s*\(\d{{1,3}}%\))?|"
r"CD|Vinyl|分[轨軌]|整[轨軌]|原抓|自抓|自扫|自掃))+"
r"(?:\s*/\s*(?P<year>(?:19|20)\d{2}))?\s*$",
re.IGNORECASE,
)
_MUSIC_VIDEO_TOKEN_ALT = (
r"1080[pi]|720p|2160[pi]|480[pi]|4k|8k|uhd|"
r"bluray|blu-ray|bdrip|uhd\s*bd|hddvd|hdvd|hdtv|webrip|remux|"
@@ -1474,9 +1483,14 @@ class MetaMusic(MetaBase):
为两种解析引擎统一清理有格式证据的发行尾标与音频文件曲序。
点分发行类型只在音频规格前生效;版本括号保留语义,介质和目录编号
不进入检索。文件曲序先于艺人拆分,避免 ``01. Artist`` 成为艺人名。
不进入检索。斜杠规格尾链整段剥离并保留年份,正文中的斜杠仍保留。
文件曲序先于艺人拆分,避免 ``01. Artist`` 成为艺人名。
:param value: 原始音乐资源标题或文件名
:return: 两种引擎共用的解析文本及待恢复的编号文件曲名
"""
text, file_title = self._prepare_filename_input(value)
text = _MUSIC_SLASH_SPEC_TAIL_RE.sub(r" \g<year>", text)
text = _MUSIC_EDITION_BRACKET_RE.sub(r"(\1)", text)
text = _MUSIC_CATALOG_SPEC_RE.sub("", text)
if re.search(r"(?:19|20)\d{2}", text) and len(_SCENE_DOT_RE.findall(value)) >= 3:

View File

@@ -8263,7 +8263,7 @@
"subtitle": "朴树 - 猎户星座 [2017] [专辑] FLAC / Lossless / Log (100%) / Cue",
"id": "torrent-1126",
"expected": {
"title": "Lie Hu Xing Zuo",
"title": "猎户星座",
"artists": [
"Pu Shu"
],

View File

@@ -9,6 +9,7 @@ from app.chain.search import SearchChain
from app.domain.context import MusicInfo, TorrentInfo
from app.domain.meta import runtime
from app.domain.meta.metamusic import MetaMusic
from app.domain.metainfo import MetaInfo
from app.domain.music import match_music_resource
from app.schemas.types import MediaType
@@ -125,3 +126,44 @@ def test_release_names_without_group_or_cjk_credit(title, artists):
"""
meta = MetaMusic.parse_resource(title)
assert (meta.title, meta.artists, meta.year, meta.audio_format) == ("Album", artists, 2022, "FLAC")
@pytest.mark.usefixtures("music_engine")
@pytest.mark.parametrize("title,expected,year", [
(
"程响 (Cheng Xiang) - 江南多雨时 [2020] [单曲专辑] FLAC / Lossless / WEB / 2020",
"江南多雨时", 2020,
),
(
"群星 (Various Artists) - âge 20th Archives Song Archives [2020] [合辑] "
"FLAC / Lossless / Log (100%) / Cue / CD / 2020",
"âge 20th Archives Song Archives", 2020,
),
(
"群星 - 南泥湾 (Nanni Bay) [1990] [专辑] "
"FLAC / Lossless / Log (100%) / Cue / CD / 自抓 / 1990",
"南泥湾 (Nanni Bay)", 1990,
),
("Artist - Album FLAC / Lossless / WEB / 2020", "Album", 2020),
("Artist - Example Album [2020] FLAC / Lossless / Log (100%) / Cue / CD", "Example Album", 2020),
("Artist - Love / Hate [2020] FLAC / Lossless / WEB / 2020", "Love / Hate", 2020),
("Artist - Captain's Log (100%) [2020] FLAC / Lossless / CD / 2020", "Captain's Log (100%)", 2020),
("Artist - CD [2020] FLAC / Lossless / CD / 2020", "CD", 2020),
("Artist - Album (Live) [2020] FLAC / Lossless / WEB / 2020", "Album (Live)", 2020),
])
def test_gazelle_slash_specs_preserve_music_identity(title: str, expected: str, year: int) -> None:
"""
Gazelle 规格尾链不进入作品名,正文斜杠、抓轨同名词与版本说明仍须保留。
:param title: 含规格尾链的站点资源标题
:param expected: 应保留的真实作品名
:param year: 应提取的发行年份
"""
meta = MetaInfo(title, mtype=MediaType.MUSIC)
assert meta.title == expected
assert meta.year == year
assert meta.org_string == title
assert meta.artists == [title.partition(" - ")[0]]
assert meta.audio_format == "FLAC"
assert meta.audio_lossless is True