mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-02-02 18:22:39 +08:00
fix: 修复订阅自定义识别词在整理时不生效的问题
问题:订阅中添加的自定义识别词(特别是集数偏移)在下载时正常生效, 但在下载完成整理时没有生效。 根因:下载历史中未保存识别词,整理时 MetaInfoPath 未接收 custom_words 参数。 修复: - 在 DownloadHistory 模型中添加 custom_words 字段 - 下载时从 meta.apply_words 获取并保存识别词到下载历史 - MetaInfoPath 函数添加 custom_words 参数支持 - 整理时从下载历史获取 custom_words 并传递给 MetaInfoPath - 添加 Alembic 迁移脚本 (2.2.3) - 添加相关单元测试
This commit is contained in:
@@ -292,6 +292,10 @@ class DownloadChain(ChainBase):
|
||||
|
||||
# 登记下载记录
|
||||
downloadhis = DownloadHistoryOper()
|
||||
# 获取应用的识别词(如果有)
|
||||
custom_words_str = None
|
||||
if hasattr(_meta, 'apply_words') and _meta.apply_words:
|
||||
custom_words_str = '\n'.join(_meta.apply_words)
|
||||
downloadhis.add(
|
||||
path=download_path.as_posix(),
|
||||
type=_media.type.value,
|
||||
@@ -315,6 +319,7 @@ class DownloadChain(ChainBase):
|
||||
date=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
|
||||
media_category=_media.category,
|
||||
episode_group=_media.episode_group,
|
||||
custom_words=custom_words_str,
|
||||
note={"source": source}
|
||||
)
|
||||
|
||||
|
||||
@@ -1080,9 +1080,26 @@ class TransferChain(ChainBase, metaclass=Singleton):
|
||||
err_msgs.append(f"{file_item.name} 已整理过")
|
||||
continue
|
||||
|
||||
# 提前获取下载历史,以便获取自定义识别词
|
||||
download_history = None
|
||||
downloadhis = DownloadHistoryOper()
|
||||
if bluray_dir:
|
||||
# 蓝光原盘,按目录名查询
|
||||
download_history = downloadhis.get_by_path(file_path.as_posix())
|
||||
else:
|
||||
# 按文件全路径查询
|
||||
download_file = downloadhis.get_file_by_fullpath(file_path.as_posix())
|
||||
if download_file:
|
||||
download_history = downloadhis.get_by_hash(download_file.download_hash)
|
||||
|
||||
# 获取自定义识别词
|
||||
custom_words_list = None
|
||||
if download_history and download_history.custom_words:
|
||||
custom_words_list = download_history.custom_words.split('\n')
|
||||
|
||||
if not meta:
|
||||
# 文件元数据
|
||||
file_meta = MetaInfoPath(file_path)
|
||||
# 文件元数据(传入自定义识别词)
|
||||
file_meta = MetaInfoPath(file_path, custom_words=custom_words_list)
|
||||
else:
|
||||
file_meta = meta
|
||||
|
||||
@@ -1108,18 +1125,6 @@ class TransferChain(ChainBase, metaclass=Singleton):
|
||||
if end_ep is not None:
|
||||
file_meta.end_episode = end_ep
|
||||
|
||||
# 根据父路径获取下载历史
|
||||
download_history = None
|
||||
downloadhis = DownloadHistoryOper()
|
||||
if bluray_dir:
|
||||
# 蓝光原盘,按目录名查询
|
||||
download_history = downloadhis.get_by_path(file_path.as_posix())
|
||||
else:
|
||||
# 按文件全路径查询
|
||||
download_file = downloadhis.get_file_by_fullpath(file_path.as_posix())
|
||||
if download_file:
|
||||
download_history = downloadhis.get_by_hash(download_file.download_hash)
|
||||
|
||||
# 获取下载Hash
|
||||
if download_history and (not downloader or not download_hash):
|
||||
downloader = download_history.downloader
|
||||
|
||||
@@ -62,20 +62,21 @@ def MetaInfo(title: str, subtitle: Optional[str] = None, custom_words: List[str]
|
||||
return meta
|
||||
|
||||
|
||||
def MetaInfoPath(path: Path) -> MetaBase:
|
||||
def MetaInfoPath(path: Path, custom_words: List[str] = None) -> MetaBase:
|
||||
"""
|
||||
根据路径识别元数据
|
||||
:param path: 路径
|
||||
:param custom_words: 自定义识别词列表
|
||||
"""
|
||||
# 文件元数据,不包含后缀
|
||||
file_meta = MetaInfo(title=path.name)
|
||||
file_meta = MetaInfo(title=path.name, custom_words=custom_words)
|
||||
# 上级目录元数据
|
||||
dir_meta = MetaInfo(title=path.parent.name)
|
||||
dir_meta = MetaInfo(title=path.parent.name, custom_words=custom_words)
|
||||
if file_meta.type == MediaType.TV or dir_meta.type != MediaType.TV:
|
||||
# 合并元数据
|
||||
file_meta.merge(dir_meta)
|
||||
# 上上级目录元数据
|
||||
root_meta = MetaInfo(title=path.parent.parent.name)
|
||||
root_meta = MetaInfo(title=path.parent.parent.name, custom_words=custom_words)
|
||||
if file_meta.type == MediaType.TV or root_meta.type != MediaType.TV:
|
||||
# 合并元数据
|
||||
file_meta.merge(root_meta)
|
||||
|
||||
@@ -55,6 +55,8 @@ class DownloadHistory(Base):
|
||||
media_category = Column(String)
|
||||
# 剧集组
|
||||
episode_group = Column(String)
|
||||
# 自定义识别词(用于整理时应用)
|
||||
custom_words = Column(String)
|
||||
|
||||
@classmethod
|
||||
@db_query
|
||||
|
||||
30
database/versions/58edfac72c32_2_2_3.py
Normal file
30
database/versions/58edfac72c32_2_2_3.py
Normal file
@@ -0,0 +1,30 @@
|
||||
"""2.2.3
|
||||
添加 downloadhistory.custom_words 字段,用于整理时应用订阅识别词
|
||||
|
||||
Revision ID: 58edfac72c32
|
||||
Revises: 41ef1dd7467c
|
||||
Create Date: 2026-01-19
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "58edfac72c32"
|
||||
down_revision = "41ef1dd7467c"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
conn = op.get_bind()
|
||||
inspector = sa.inspect(conn)
|
||||
|
||||
# 检查并添加 downloadhistory.custom_words
|
||||
dh_columns = inspector.get_columns('downloadhistory')
|
||||
if not any(c['name'] == 'custom_words' for c in dh_columns):
|
||||
op.add_column('downloadhistory', sa.Column('custom_words', sa.String, nullable=True))
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# 降级时删除字段
|
||||
op.drop_column('downloadhistory', 'custom_words')
|
||||
@@ -13,6 +13,12 @@ if __name__ == '__main__':
|
||||
suite.addTest(MetaInfoTest('test_emby_format_ids'))
|
||||
suite.addTest(ObjectUtilsTest('test_check_method'))
|
||||
|
||||
# 测试自定义识别词功能
|
||||
suite.addTest(MetaInfoTest('test_metainfopath_with_custom_words'))
|
||||
suite.addTest(MetaInfoTest('test_metainfopath_without_custom_words'))
|
||||
suite.addTest(MetaInfoTest('test_metainfopath_with_empty_custom_words'))
|
||||
suite.addTest(MetaInfoTest('test_custom_words_apply_words_recording'))
|
||||
|
||||
# 测试蓝光目录识别
|
||||
suite.addTest(BluRayTest())
|
||||
|
||||
|
||||
@@ -61,3 +61,38 @@ class MetaInfoTest(TestCase):
|
||||
meta = MetaInfoPath(Path(path_str))
|
||||
self.assertEqual(meta.tmdbid, expected_tmdbid,
|
||||
f"路径 {path_str} 期望的tmdbid为 {expected_tmdbid},实际识别为 {meta.tmdbid}")
|
||||
|
||||
def test_metainfopath_with_custom_words(self):
|
||||
"""测试 MetaInfoPath 使用自定义识别词"""
|
||||
# 测试替换词:将"测试替换"替换为空
|
||||
custom_words = ["测试替换 => "]
|
||||
path = Path("/movies/电影测试替换名称 (2024)/movie.mkv")
|
||||
meta = MetaInfoPath(path, custom_words=custom_words)
|
||||
# 验证替换生效:cn_name 不应包含"测试替换"
|
||||
if meta.cn_name:
|
||||
self.assertNotIn("测试替换", meta.cn_name)
|
||||
|
||||
def test_metainfopath_without_custom_words(self):
|
||||
"""测试 MetaInfoPath 不传入自定义识别词"""
|
||||
path = Path("/movies/Normal Movie (2024)/movie.mkv")
|
||||
meta = MetaInfoPath(path)
|
||||
# 验证正常识别,不报错
|
||||
self.assertIsNotNone(meta)
|
||||
|
||||
def test_metainfopath_with_empty_custom_words(self):
|
||||
"""测试 MetaInfoPath 传入空的自定义识别词"""
|
||||
path = Path("/movies/Test Movie (2024)/movie.mkv")
|
||||
meta = MetaInfoPath(path, custom_words=[])
|
||||
# 验证不报错,正常识别
|
||||
self.assertIsNotNone(meta)
|
||||
|
||||
def test_custom_words_apply_words_recording(self):
|
||||
"""测试 apply_words 记录功能"""
|
||||
custom_words = ["替换词 => 新词"]
|
||||
title = "电影替换词.2024.mkv"
|
||||
meta = MetaInfo(title=title, custom_words=custom_words)
|
||||
# 验证 apply_words 属性存在
|
||||
self.assertTrue(hasattr(meta, 'apply_words'))
|
||||
# 如果替换词被应用,应该记录在 apply_words 中
|
||||
if meta.apply_words:
|
||||
self.assertIn("替换词 => 新词", meta.apply_words)
|
||||
|
||||
Reference in New Issue
Block a user