fix 统一文件识别处理逻辑
This commit is contained in:
@ -269,15 +269,19 @@ class ChainBase(metaclass=ABCMeta):
|
||||
"""
|
||||
return self.run_module("list_torrents", status=status, hashs=hashs)
|
||||
|
||||
def transfer(self, path: Path, mediainfo: MediaInfo, transfer_type: str) -> Optional[TransferInfo]:
|
||||
def transfer(self, path: Path, mediainfo: MediaInfo,
|
||||
transfer_type: str,
|
||||
meta: MetaBase = None) -> Optional[TransferInfo]:
|
||||
"""
|
||||
文件转移
|
||||
:param path: 文件路径
|
||||
:param mediainfo: 识别的媒体信息
|
||||
:param transfer_type: 转移模式
|
||||
:param meta: 预识别的元数据,仅单文件转移时传递
|
||||
:return: {path, target_path, message}
|
||||
"""
|
||||
return self.run_module("transfer", path=path, mediainfo=mediainfo, transfer_type=transfer_type)
|
||||
return self.run_module("transfer", path=path, mediainfo=mediainfo,
|
||||
transfer_type=transfer_type, meta=meta)
|
||||
|
||||
def transfer_completed(self, hashs: Union[str, list], transinfo: TransferInfo) -> None:
|
||||
"""
|
||||
|
@ -36,7 +36,8 @@ class TransferChain(ChainBase):
|
||||
self.transferhis = TransferHistoryOper(self._db)
|
||||
self.progress = ProgressHelper()
|
||||
|
||||
def process(self, arg_str: str = None, channel: MessageChannel = None, userid: Union[str, int] = None) -> bool:
|
||||
def process(self, arg_str: str = None,
|
||||
channel: MessageChannel = None, userid: Union[str, int] = None) -> bool:
|
||||
"""
|
||||
获取下载器中的种子列表,并执行转移
|
||||
:param arg_str: 传入的参数 (种子hash和TMDBID|类型)
|
||||
@ -154,13 +155,16 @@ class TransferChain(ChainBase):
|
||||
transferinfo: TransferInfo = self.transfer(mediainfo=mediainfo,
|
||||
path=torrent.path,
|
||||
transfer_type=settings.TRANSFER_TYPE)
|
||||
if not transferinfo or not transferinfo.target_path:
|
||||
if not transferinfo:
|
||||
logger.error("文件转移模块运行失败")
|
||||
continue
|
||||
if not transferinfo.target_path:
|
||||
# 转移失败
|
||||
logger.warn(f"{torrent.title} 入库失败")
|
||||
logger.warn(f"{torrent.title} 入库失败:{transferinfo.message}")
|
||||
self.post_message(Notification(
|
||||
channel=channel,
|
||||
title=f"{mediainfo.title_year}{meta.season_episode} 入库失败!",
|
||||
text=f"原因:{transferinfo.message if transferinfo else '未知'}",
|
||||
text=f"原因:{transferinfo.message or '未知'}",
|
||||
image=mediainfo.get_message_image(),
|
||||
userid=userid
|
||||
))
|
||||
@ -189,7 +193,7 @@ class TransferChain(ChainBase):
|
||||
# 新增转移成功历史记录
|
||||
self.transferhis.add(
|
||||
src=str(torrent.path),
|
||||
dest=str(transferinfo.target_path) if transferinfo else None,
|
||||
dest=str(transferinfo.target_path),
|
||||
mode=settings.TRANSFER_TYPE,
|
||||
type=mediainfo.type.value,
|
||||
category=mediainfo.category,
|
||||
|
@ -1,5 +1,5 @@
|
||||
from dataclasses import dataclass, asdict
|
||||
from typing import Union, Optional, List
|
||||
from typing import Union, Optional, List, Self
|
||||
|
||||
import cn2an
|
||||
import regex as re
|
||||
@ -443,6 +443,61 @@ class MetaBase(object):
|
||||
elif str(ep).isdigit():
|
||||
self.begin_episode = int(ep)
|
||||
self.end_episode = None
|
||||
|
||||
def merge(self, meta: Self):
|
||||
"""
|
||||
全并Meta信息
|
||||
"""
|
||||
# 类型
|
||||
if self.type == MediaType.UNKNOWN \
|
||||
and meta.type != MediaType.UNKNOWN:
|
||||
self.type = meta.type
|
||||
# 名称
|
||||
if not self.name:
|
||||
self.cn_name = meta.cn_name
|
||||
self.en_name = meta.en_name
|
||||
# 年份
|
||||
if not self.year:
|
||||
self.year = meta.year
|
||||
# 开始季
|
||||
if not self.begin_season:
|
||||
self.begin_season = meta.begin_season
|
||||
# 结束季
|
||||
if not self.end_season:
|
||||
self.end_season = meta.end_season
|
||||
# 总季数
|
||||
if self.begin_season:
|
||||
self.total_seasons = meta.total_seasons
|
||||
# 开始集
|
||||
if not self.begin_episode:
|
||||
self.begin_episode = meta.begin_episode
|
||||
# 结束集
|
||||
if not self.end_episode:
|
||||
self.end_episode = meta.end_episode
|
||||
# 总集数
|
||||
if not self.total_episode:
|
||||
self.total_episode = meta.total_episode
|
||||
# 版本
|
||||
if not self.resource_type:
|
||||
self.resource_type = meta.resource_type
|
||||
# 分辨率
|
||||
if not self.resource_pix:
|
||||
self.resource_pix = meta.resource_pix
|
||||
# 制作组/字幕组
|
||||
if not self.resource_team:
|
||||
self.resource_team = meta.resource_team
|
||||
# 特效
|
||||
if not self.resource_effect:
|
||||
self.resource_effect = meta.resource_effect
|
||||
# 视频编码
|
||||
if not self.video_encode:
|
||||
self.video_encode = meta.video_encode
|
||||
# 音频编码
|
||||
if not self.audio_encode:
|
||||
self.audio_encode = meta.audio_encode
|
||||
# Part
|
||||
if not self.part:
|
||||
self.part = meta.part
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
|
@ -29,12 +29,14 @@ class FileTransferModule(_ModuleBase):
|
||||
def init_setting(self) -> Tuple[str, Union[str, bool]]:
|
||||
pass
|
||||
|
||||
def transfer(self, path: Path, mediainfo: MediaInfo, transfer_type: str) -> Optional[TransferInfo]:
|
||||
def transfer(self, path: Path, mediainfo: MediaInfo,
|
||||
transfer_type: str, meta: MetaBase = None) -> TransferInfo:
|
||||
"""
|
||||
文件转移
|
||||
:param path: 文件路径
|
||||
:param mediainfo: 识别的媒体信息
|
||||
:param transfer_type: 转移方式
|
||||
:param meta: 预识别的元数据,仅单文件转移时传递
|
||||
:return: {path, target_path, message}
|
||||
"""
|
||||
# 获取目标路径
|
||||
@ -43,26 +45,11 @@ class FileTransferModule(_ModuleBase):
|
||||
logger.error("未找到媒体库目录,无法转移文件")
|
||||
return TransferInfo(message="未找到媒体库目录,无法转移文件")
|
||||
# 转移
|
||||
result = self.transfer_media(in_path=path,
|
||||
mediainfo=mediainfo,
|
||||
transfer_type=transfer_type,
|
||||
target_dir=target_path)
|
||||
if not result:
|
||||
return TransferInfo()
|
||||
if isinstance(result, str):
|
||||
return TransferInfo(message=result)
|
||||
# 解包结果
|
||||
is_bluray, target_path, file_list, file_list_new, file_size, fail_list, msg = result
|
||||
# 返回
|
||||
return TransferInfo(path=path,
|
||||
target_path=target_path,
|
||||
message=msg,
|
||||
file_count=len(file_list),
|
||||
total_size=file_size,
|
||||
fail_list=fail_list,
|
||||
is_bluray=is_bluray,
|
||||
file_list=file_list,
|
||||
file_list_new=file_list_new)
|
||||
return self.transfer_media(in_path=path,
|
||||
mediainfo=mediainfo,
|
||||
transfer_type=transfer_type,
|
||||
target_dir=target_path,
|
||||
file_meta=meta)
|
||||
|
||||
@staticmethod
|
||||
def __transfer_command(file_item: Path, target_file: Path, transfer_type: str) -> int:
|
||||
@ -338,22 +325,24 @@ class FileTransferModule(_ModuleBase):
|
||||
in_path: Path,
|
||||
mediainfo: MediaInfo,
|
||||
transfer_type: str,
|
||||
target_dir: Path = None
|
||||
) -> Union[str, Tuple[bool, Path, list, list, int, List[Path], str]]:
|
||||
target_dir: Path = None,
|
||||
file_meta: MetaBase = None
|
||||
) -> TransferInfo:
|
||||
"""
|
||||
识别并转移一个文件、多个文件或者目录
|
||||
:param in_path: 转移的路径,可能是一个文件也可以是一个目录
|
||||
:param mediainfo: 媒体信息
|
||||
:param target_dir: 目的文件夹,非空的转移到该文件夹,为空时则按类型转移到配置文件中的媒体库文件夹
|
||||
:param transfer_type: 文件转移方式
|
||||
:param mediainfo: 媒体信息
|
||||
:return: 是否蓝光原盘、目的路径、处理文件清单、总大小、失败文件列表、错误信息
|
||||
:param file_meta:预识别元数,为空则重新识别
|
||||
:return: TransferInfo、错误信息
|
||||
"""
|
||||
# 检查目录路径
|
||||
if not in_path.exists():
|
||||
return f"{in_path} 路径不存在"
|
||||
return TransferInfo(message=f"{in_path} 路径不存在")
|
||||
|
||||
if not target_dir.exists():
|
||||
return f"{target_dir} 目标路径不存在"
|
||||
return TransferInfo(message=f"{target_dir} 目标路径不存在")
|
||||
|
||||
if mediainfo.type == MediaType.MOVIE:
|
||||
if settings.LIBRARY_MOVIE_NAME:
|
||||
@ -405,17 +394,22 @@ class FileTransferModule(_ModuleBase):
|
||||
new_path=new_path,
|
||||
transfer_type=transfer_type)
|
||||
if retcode != 0:
|
||||
return f"{retcode},蓝光原盘转移失败"
|
||||
return TransferInfo(message=f"{retcode},蓝光原盘转移失败")
|
||||
else:
|
||||
# 计算大小
|
||||
total_filesize += in_path.stat().st_size
|
||||
# 返回转移后的路径
|
||||
return bluray_flag, new_path, [], [], total_filesize, [], ""
|
||||
return TransferInfo(path=in_path,
|
||||
target_path=new_path,
|
||||
total_size=total_filesize,
|
||||
is_bluray=bluray_flag,
|
||||
file_list=[],
|
||||
file_list_new=[])
|
||||
else:
|
||||
# 获取文件清单
|
||||
transfer_files: List[Path] = SystemUtils.list_files_with_extensions(in_path, settings.RMT_MEDIAEXT)
|
||||
if len(transfer_files) == 0:
|
||||
return f"{in_path} 目录下没有找到可转移的文件"
|
||||
return TransferInfo(message=f"{in_path} 目录下没有找到可转移的文件")
|
||||
# 识别目录名称,不包括后缀
|
||||
meta = MetaInfo(in_path.stem)
|
||||
# 目的路径
|
||||
@ -427,46 +421,16 @@ class FileTransferModule(_ModuleBase):
|
||||
# 转移所有文件
|
||||
for transfer_file in transfer_files:
|
||||
try:
|
||||
# 识别文件元数据,不包含后缀
|
||||
file_meta = MetaInfo(transfer_file.stem)
|
||||
# 开始季
|
||||
if not file_meta.begin_season:
|
||||
file_meta.begin_season = meta.begin_season
|
||||
# 结束季为空
|
||||
file_meta.end_season = None
|
||||
# 总季数
|
||||
if file_meta.begin_season:
|
||||
file_meta.total_seasons = 1
|
||||
# 开始集
|
||||
if not file_meta.begin_episode:
|
||||
file_meta.begin_episode = meta.begin_episode
|
||||
# 结束集
|
||||
if not file_meta.end_episode:
|
||||
file_meta.end_episode = meta.end_episode
|
||||
# 总集数
|
||||
if not file_meta.total_episode:
|
||||
file_meta.total_episode = meta.total_episode
|
||||
# 版本
|
||||
if not file_meta.resource_type:
|
||||
file_meta.resource_type = meta.resource_type
|
||||
# 分辨率
|
||||
if not file_meta.resource_pix:
|
||||
file_meta.resource_pix = meta.resource_pix
|
||||
# 制作组/字幕组
|
||||
if not file_meta.resource_team:
|
||||
file_meta.resource_team = meta.resource_team
|
||||
# 特效
|
||||
if not file_meta.resource_effect:
|
||||
file_meta.resource_effect = meta.resource_effect
|
||||
# 视频编码
|
||||
if not file_meta.video_encode:
|
||||
file_meta.video_encode = meta.video_encode
|
||||
# 音频编码
|
||||
if not file_meta.audio_encode:
|
||||
file_meta.audio_encode = meta.audio_encode
|
||||
# Part
|
||||
if not file_meta.part:
|
||||
file_meta.part = meta.part
|
||||
if not file_meta:
|
||||
# 识别文件元数据,不包含后缀
|
||||
file_meta = MetaInfo(transfer_file.stem)
|
||||
# 合并元数据
|
||||
file_meta.merge(meta)
|
||||
# 结束季为空
|
||||
file_meta.end_season = None
|
||||
# 总季数为1
|
||||
if file_meta.begin_season:
|
||||
file_meta.total_seasons = 1
|
||||
# 目的文件名
|
||||
new_file = self.get_rename_path(
|
||||
path=target_dir,
|
||||
@ -475,6 +439,8 @@ class FileTransferModule(_ModuleBase):
|
||||
mediainfo=mediainfo,
|
||||
file_ext=transfer_file.suffix)
|
||||
)
|
||||
# 重新修正目的路径
|
||||
new_path = new_path.parents[-2].name
|
||||
# 判断是否要覆盖
|
||||
overflag = False
|
||||
if new_file.exists():
|
||||
@ -491,10 +457,11 @@ class FileTransferModule(_ModuleBase):
|
||||
err_msgs.append(f"{transfer_file.name}:错误码 {retcode}")
|
||||
fail_list.append(transfer_file)
|
||||
continue
|
||||
# 计算文件数
|
||||
# 源文件清单
|
||||
file_list.append(str(transfer_file))
|
||||
# 目的文件清单
|
||||
file_list_new.append(str(new_file))
|
||||
# 计算大小
|
||||
# 计算总大小
|
||||
total_filesize += transfer_file.stat().st_size
|
||||
except Exception as err:
|
||||
err_msgs.append(f"{transfer_file.name}:{err}")
|
||||
@ -503,10 +470,17 @@ class FileTransferModule(_ModuleBase):
|
||||
|
||||
if not file_list:
|
||||
# 没有成功的
|
||||
return "\n".join(err_msgs)
|
||||
return TransferInfo(message="\n".join(err_msgs))
|
||||
|
||||
# 蓝光原盘、新路径、处理文件清单、总大小、失败文件列表、错误信息
|
||||
return bluray_flag, new_path, file_list, file_list_new, total_filesize, fail_list, "\n".join(err_msgs)
|
||||
return TransferInfo(path=in_path,
|
||||
target_path=new_path,
|
||||
message="\n".join(err_msgs),
|
||||
file_count=len(file_list),
|
||||
total_size=total_filesize,
|
||||
fail_list=fail_list,
|
||||
is_bluray=bluray_flag,
|
||||
file_list=file_list,
|
||||
file_list_new=file_list_new)
|
||||
|
||||
@staticmethod
|
||||
def __get_naming_dict(meta: MetaBase, mediainfo: MediaInfo, file_ext: str = None) -> dict:
|
||||
|
@ -15,7 +15,7 @@ from app.core.metainfo import MetaInfo
|
||||
from app.db.transferhistory_oper import TransferHistoryOper
|
||||
from app.log import logger
|
||||
from app.plugins import _PluginBase
|
||||
from app.schemas import MediaType, Notification, NotificationType, TransferInfo
|
||||
from app.schemas import Notification, NotificationType, TransferInfo
|
||||
from app.schemas.types import EventType
|
||||
|
||||
lock = threading.Lock()
|
||||
@ -180,24 +180,17 @@ class DirMonitor(_PluginBase):
|
||||
logger.info(f"{event_path} 已整理过")
|
||||
return
|
||||
|
||||
# 文件元数据
|
||||
file_meta = MetaInfo(title=file_path.name)
|
||||
# 上级目录元数据
|
||||
dir_meta = MetaInfo(title=file_path.parent.name)
|
||||
# 整合元数据
|
||||
if not file_meta.cn_name and dir_meta.cn_name:
|
||||
file_meta.cn_name = dir_meta.cn_name
|
||||
if not file_meta.en_name and dir_meta.en_name:
|
||||
file_meta.en_name = dir_meta.en_name
|
||||
if file_meta.type != MediaType.TV and dir_meta.type == MediaType.TV:
|
||||
file_meta.type = MediaType.TV
|
||||
if not file_meta.year and dir_meta.year:
|
||||
file_meta.year = dir_meta.year
|
||||
if not file_meta.begin_season and dir_meta.begin_season:
|
||||
file_meta.begin_season = dir_meta.begin_season
|
||||
if not file_meta.episode_list and dir_meta.episode_list:
|
||||
file_meta.begin_episode = dir_meta.begin_episode
|
||||
file_meta.end_episode = dir_meta.end_episode
|
||||
meta = MetaInfo(title=file_path.parent.name)
|
||||
# 文件元数据,不包含后缀
|
||||
file_meta = MetaInfo(title=file_path.stem)
|
||||
# 合并元数据
|
||||
file_meta.merge(meta)
|
||||
# 结束季为空
|
||||
file_meta.end_season = None
|
||||
# 总季数为1
|
||||
if file_meta.begin_season:
|
||||
file_meta.total_seasons = 1
|
||||
|
||||
if not file_meta.name:
|
||||
logger.warn(f"{file_path.name} 无法识别有效信息")
|
||||
@ -221,15 +214,19 @@ class DirMonitor(_PluginBase):
|
||||
# 转移
|
||||
transferinfo: TransferInfo = self.chain.transfer(mediainfo=mediainfo,
|
||||
path=file_path,
|
||||
transfer_type=self._transfer_type)
|
||||
transfer_type=self._transfer_type,
|
||||
meta=file_meta)
|
||||
|
||||
if not transferinfo or not transferinfo.target_path:
|
||||
if not transferinfo:
|
||||
logger.error("文件转移模块运行失败")
|
||||
return
|
||||
if not transferinfo.target_path:
|
||||
# 转移失败
|
||||
logger.warn(f"{file_path.name} 入库失败")
|
||||
logger.warn(f"{file_path.name} 入库失败:{transferinfo.message}")
|
||||
if self._notify:
|
||||
self.chain.post_message(Notification(
|
||||
title=f"{mediainfo.title_year}{file_meta.season_episode} 入库失败!",
|
||||
text=f"原因:{transferinfo.message if transferinfo else '未知'}",
|
||||
text=f"原因:{transferinfo.message or '未知'}",
|
||||
image=mediainfo.get_message_image()
|
||||
))
|
||||
return
|
||||
@ -237,7 +234,7 @@ class DirMonitor(_PluginBase):
|
||||
# 新增转移成功历史记录
|
||||
self.transferhis.add(
|
||||
src=event_path,
|
||||
dest=str(transferinfo.target_path) if transferinfo else None,
|
||||
dest=str(transferinfo.target_path),
|
||||
mode=settings.TRANSFER_TYPE,
|
||||
type=mediainfo.type.value,
|
||||
category=mediainfo.category,
|
||||
|
Reference in New Issue
Block a user