fix(metainfo): preserve subtitle-like title tokens

This commit is contained in:
jxxghp
2026-09-24 09:37:08 +08:00
parent a225465cd6
commit e619bed625
3 changed files with 58 additions and 4 deletions

View File

@@ -259,10 +259,10 @@ class MetaVideo(MetaBase):
media_exts: list,
state: _VideoParseState,
) -> None:
"""按固定优先级处理单个词元,首个命中的阶段终止后续识别。"""
"""按固定优先级处理词元,并标记当前词元是否为输入末尾。"""
if self.__init_part(token, tokens, state):
return
if self.__init_name(token, media_exts, state):
if self.__init_name(token, media_exts, state, tokens.cur() is None):
return
if self.__init_year(token, state):
return
@@ -336,9 +336,10 @@ class MetaVideo(MetaBase):
token: Optional[str],
media_exts: list,
state: _VideoParseState,
is_last_token: bool,
) -> bool:
"""
识别名称
识别名称,并只忽略原始文件名末尾的媒体扩展名。
"""
if not token:
return False
@@ -422,7 +423,12 @@ class MetaVideo(MetaBase):
return False
else:
# 后缀名不要
if ".%s".lower() % token in media_exts:
suffix = f".{token.lower()}"
if (
is_last_token
and suffix in media_exts
and (self.org_string or "").lower().endswith(suffix)
):
return False
# 英文或者英文+数字,拼装起来
if self.en_name:

View File

@@ -5,6 +5,7 @@ from unittest.mock import patch
import pytest
from app.domain import metainfo as metainfo_module
from app.domain.context import MediaInfo
from app.domain.metainfo import MetaInfo, MetaInfoPath, find_metainfo
from app.domain.meta.metabase import MetaBase, MetaInfoSnapshot
@@ -275,6 +276,34 @@ def test_python_metainfo_fallback_preserves_xxx_movie_title():
assert meta.audio_encode == "DDP 5.1"
@pytest.mark.parametrize("use_path", [False, True])
def test_python_metainfo_fallback_keeps_title_token_matching_subtitle_extension(
use_path, monkeypatch
):
"""Python 回退解析在标题和路径入口都应保留与字幕扩展名同名的词元。"""
title = (
"Kick-Ass.2010.PROPER.2160p.BluRay.REMUX.HEVC.DTS-HD.MA."
"TrueHD.7.1.Atmos-FGT.mkv"
)
monkeypatch.setattr(
metainfo_module,
"get_media_extensions",
lambda: (".mkv", ".ass"),
)
with (
patch("app.adapters.system.rust.parse_metainfo", return_value=None),
patch("app.adapters.system.rust.parse_metainfo_path", return_value=None),
):
meta = (
MetaInfoPath(Path("/movies") / title)
if use_path
else MetaInfo(title)
)
assert meta.en_name == "Kick Ass"
assert meta.year == "2010"
def test_python_metainfo_fallback_recognizes_eac3_audio_codec():
"""Python 兜底解析应识别 EAC3 及其声道信息。"""
with patch("app.adapters.system.rust.parse_metainfo", return_value=None):

View File

@@ -238,6 +238,25 @@ def test_rust_metainfo_parser_handles_video_from_entry():
assert result["fps"] == 120
def test_rust_metainfo_keeps_title_token_matching_subtitle_extension():
"""Rust 标题和路径入口都应保留与字幕扩展名同名的片名词元。"""
title = (
"Kick-Ass.2010.PROPER.2160p.BluRay.REMUX.HEVC.DTS-HD.MA."
"TrueHD.7.1.Atmos-FGT.mkv"
)
options = _metainfo_options()
parsed_title = rust_accel.parse_metainfo(title, options=options)
parsed_path = rust_accel.parse_metainfo_path(
f"/movies/{title}",
options=options,
)
assert parsed_title["en_name"] == "Kick Ass"
assert parsed_title["year"] == "2010"
assert parsed_path["en_name"] == "Kick Ass"
assert parsed_path["year"] == "2010"
def test_rust_metainfo_parser_handles_anime_from_entry():
"""
Rust MetaInfo 入口应完整识别 Anime 标题。