fix(meta): 副标题识别 01-26Fin 等数字范围完结标记集数 (#6105)

This commit is contained in:
freeman
2026-07-13 16:50:00 +08:00
committed by GitHub
parent 96ef431efc
commit 1855ba81ec
2 changed files with 95 additions and 0 deletions

View File

@@ -24,6 +24,13 @@ SUBTITLE_EPISODE_ALL_RE = re.compile(
r"([0-9一二三四五六七八九十百零]+)\s*集\s*全|[全共]\s*([0-9一二三四五六七八九十百零]+)\s*[集话話期幕]",
re.IGNORECASE,
)
# 01-26Fin / [01-38 END] / 01-24完结 等"数字范围+完结标记"格式,完结标记必须
# 存在以避免年份范围(如 2019-2020误识别为集数Fin/End 后不能紧跟字母数字,
# 避免 Final/Ending 等单词前缀误匹配
SUBTITLE_EPISODE_RANGE_FIN_RE = re.compile(
r"(?<!\d)\[?\s*(\d{1,4})\s*-\s*(\d{1,4})\s*(?:(?:Fin|End)(?![a-z0-9])|完结(?![\u4e00-\u9fff]))\s*\]?(?!\d)",
re.IGNORECASE,
)
VIDEO_BIT_RE = re.compile(
r"(?<![A-Za-z0-9])(?P<bit>8|10|12|16)[\s._-]*bits?(?![A-Za-z0-9])",
re.IGNORECASE,
@@ -292,6 +299,36 @@ class MetaBase(object):
self.type = MediaType.TV
self._subtitle_flag = True
return
# 01-26Fin 等数字范围+完结标记
self.__init_episode_range_fin(title_text)
else:
# 副标题无中文季集标记时,仍识别 01-26Fin 等数字范围+完结标记
self.__init_episode_range_fin(title_text)
def __init_episode_range_fin(self, title_text: str):
"""
识别 01-26Fin / [01-38 END] 等"数字范围+完结标记"格式的集数信息
"""
episode_range_str = SUBTITLE_EPISODE_RANGE_FIN_RE.search(title_text)
if not episode_range_str:
return
try:
begin_episode = int(episode_range_str.group(1))
end_episode = int(episode_range_str.group(2))
except Exception as err:
logger.debug(f'识别集失败:{str(err)} - {traceback.format_exc()}')
return
if begin_episode < 1 or begin_episode > end_episode or end_episode >= 10000:
return
# 两个数字都落在常见年份区间时视为年份范围而非集数(如 2019-2020完结
if begin_episode >= 1900 and end_episode <= 2155:
return
if self.begin_episode is None:
self.begin_episode = begin_episode
self.end_episode = end_episode
self.total_episode = end_episode
self.type = MediaType.TV
self._subtitle_flag = True
@property
def season(self) -> str:

View File

@@ -169,6 +169,64 @@ def test_python_metainfo_fallback_preserves_xxx_movie_title():
assert meta.audio_encode == "DDP 5.1"
def test_python_subtitle_episode_range_fin_with_chinese_season():
"""Python 兜底解析应识别副标题中 [01-26Fin] 格式的集数范围(#6103"""
with patch("app.core.metainfo.rust_accel.parse_metainfo", return_value=None):
meta = MetaInfo(
title="JoJos Bizarre Adventure S01 2012 1080i BluRay x264 FLAC 2.0-AnimeF@ADE",
subtitle="JOJO的奇妙冒险 第一季 / JoJo's Bizarre Adventure [01-26Fin] [简繁字幕]",
)
assert meta.type == MediaType.TV
assert meta.begin_season == 1
assert meta.begin_episode == 1
assert meta.end_episode == 26
assert meta.total_episode == 26
def test_python_subtitle_episode_range_fin_without_chinese_marker():
"""副标题无中文季集标记时也应识别 [01-38Fin] 集数范围。"""
with patch("app.core.metainfo.rust_accel.parse_metainfo", return_value=None):
meta = MetaInfo(
title="Some Show S01 2022 1080p WEB-DL H264-GRP",
subtitle="Some Show [01-38Fin]",
)
assert meta.begin_episode == 1
assert meta.end_episode == 38
assert meta.total_episode == 38
def test_python_subtitle_episode_range_end_variant():
"""END/完结 等完结标记变体同样应识别为集数范围。"""
with patch("app.core.metainfo.rust_accel.parse_metainfo", return_value=None):
meta_end = MetaInfo(
title="Some Show S01 2022 1080p WEB-DL H264-GRP",
subtitle="Some Show 01-24 END",
)
meta_cn = MetaInfo(
title="Some Show S01 2022 1080p WEB-DL H264-GRP",
subtitle="某剧 01-12完结",
)
assert meta_end.begin_episode == 1
assert meta_end.end_episode == 24
assert meta_cn.begin_episode == 1
assert meta_cn.end_episode == 12
def test_python_subtitle_year_range_not_treated_as_episodes():
"""年份范围(如 2019-2020不得误识别为集数。"""
with patch("app.core.metainfo.rust_accel.parse_metainfo", return_value=None):
meta = MetaInfo(
title="Some Collection 2020 1080p WEB-DL H264-GRP",
subtitle="A Collection [2019-2020Fin]",
)
assert meta.begin_episode is None
assert meta.total_episode == 0
def test_custom_words_replace_then_episode_offset():
"""测试复杂识别词仍按先替换、后集数偏移的顺序处理。"""
custom_words = ["旧名 => 新名 && 第 <> 集 >> EP+1"]