diff --git a/app/api/endpoints/transfer.py b/app/api/endpoints/transfer.py index eac588f9..da546390 100644 --- a/app/api/endpoints/transfer.py +++ b/app/api/endpoints/transfer.py @@ -1,8 +1,9 @@ import json from pathlib import Path -from typing import Any +from typing import Any, Optional from fastapi import APIRouter, Depends +from pydantic import BaseModel from sqlalchemy.orm import Session from app import schemas @@ -19,6 +20,25 @@ from app.schemas import MediaType, FileItem router = APIRouter() +class ManualTransferItem(BaseModel): + fileitem: FileItem = None, + logid: Optional[int] = None, + target_storage: Optional[str] = None, + target_path: Optional[str] = None, + tmdbid: Optional[int] = None, + doubanid: Optional[str] = None, + type_name: Optional[str] = None, + season: Optional[int] = None, + transfer_type: Optional[str] = None, + episode_format: Optional[str] = None, + episode_detail: Optional[str] = None, + episode_part: Optional[str] = None, + episode_offset: Optional[int] = 0, + min_filesize: Optional[int] = 0, + scrape: bool = False, + from_history: bool = False + + @router.get("/name", summary="查询整理后的名称", response_model=schemas.Response) def query_name(path: str, filetype: str, _: schemas.TokenPayload = Depends(verify_token)) -> Any: @@ -49,52 +69,22 @@ def query_name(path: str, filetype: str, @router.post("/manual", summary="手动转移", response_model=schemas.Response) -def manual_transfer(fileitem: FileItem = None, - logid: int = None, - target_storage: str = None, - target_path: str = None, - tmdbid: int = None, - doubanid: str = None, - type_name: str = None, - season: int = None, - transfer_type: str = None, - episode_format: str = None, - episode_detail: str = None, - episode_part: str = None, - episode_offset: int = 0, - min_filesize: int = 0, - scrape: bool = None, - from_history: bool = None, +def manual_transfer(transer_item: ManualTransferItem, db: Session = Depends(get_db), _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 手动转移,文件或历史记录,支持自定义剧集识别格式 - :param fileitem: 文件信息 - :param logid: 转移历史记录ID - :param target_storage: 目标存储 - :param target_path: 目标路径 - :param type_name: 媒体类型、电影/电视剧 - :param tmdbid: tmdbid - :param doubanid: 豆瓣ID - :param season: 剧集季号 - :param transfer_type: 转移类型,move/copy 等 - :param episode_format: 剧集识别格式 - :param episode_detail: 剧集识别详细信息 - :param episode_part: 剧集识别分集信息 - :param episode_offset: 剧集识别偏移量 - :param min_filesize: 最小文件大小(MB) - :param scrape: 是否刮削元数据 - :param from_history: 从历史记录中获取tmdbid、season、episode_detail等信息 + :param transer_item: 手工整理项 :param db: 数据库 :param _: Token校验 """ force = False - target_path = Path(target_path) if target_path else None - if logid: + target_path = Path(transer_item.target_path) if transer_item.target_path else None + if transer_item.logid: # 查询历史记录 - history: TransferHistory = TransferHistory.get(db, logid) + history: TransferHistory = TransferHistory.get(db, transer_item.logid) if not history: - return schemas.Response(success=False, message=f"历史记录不存在,ID:{logid}") + return schemas.Response(success=False, message=f"历史记录不存在,ID:{transer_item.logid}") # 强制转移 force = True if history.status and ("move" in history.mode): @@ -110,11 +100,11 @@ def manual_transfer(fileitem: FileItem = None, StorageChain().delete_file(dest_fileitem) # 从历史数据获取信息 - if from_history: - type_name = history.type if history.type else type_name - tmdbid = int(history.tmdbid) if history.tmdbid else tmdbid - doubanid = str(history.doubanid) if history.doubanid else doubanid - season = int(str(history.seasons).replace("S", "")) if history.seasons else season + if transer_item.from_history: + transer_item.type_name = history.type if history.type else transer_item.type_name + transer_item.tmdbid = int(history.tmdbid) if history.tmdbid else transer_item.tmdbid + transer_item.doubanid = str(history.doubanid) if history.doubanid else transer_item.doubanid + transer_item.season = int(str(history.seasons).replace("S", "")) if history.seasons else transer_item.season if history.episodes: if "-" in str(history.episodes): # E01-E03多集合并 @@ -122,40 +112,41 @@ def manual_transfer(fileitem: FileItem = None, episode_list: list[int] = [] for i in range(int(episode_start.replace("E", "")), int(episode_end.replace("E", "")) + 1): episode_list.append(i) - episode_detail = ",".join(str(e) for e in episode_list) + transer_item.episode_detail = ",".join(str(e) for e in episode_list) else: # E01单集 - episode_detail = str(history.episodes).replace("E", "") + transer_item.episode_detail = str(history.episodes).replace("E", "") - elif fileitem: - src_fileitem = fileitem + elif transer_item.fileitem: + src_fileitem = transer_item.fileitem else: return schemas.Response(success=False, message=f"缺少参数") # 类型 - mtype = MediaType(type_name) if type_name else None + mtype = MediaType(transer_item.type_name) if transer_item.type_name else None # 自定义格式 epformat = None - if episode_offset or episode_part or episode_detail or episode_format: + if transer_item.episode_offset or transer_item.episode_part \ + or transer_item.episode_detail or transer_item.episode_format: epformat = schemas.EpisodeFormat( - format=episode_format, - detail=episode_detail, - part=episode_part, - offset=episode_offset, + format=transer_item.episode_format, + detail=transer_item.episode_detail, + part=transer_item.episode_part, + offset=transer_item.episode_offset, ) # 开始转移 state, errormsg = TransferChain().manual_transfer( fileitem=src_fileitem, - target_storage=target_storage, + target_storage=transer_item.target_storage, target_path=target_path, - tmdbid=tmdbid, - doubanid=doubanid, + tmdbid=transer_item.tmdbid, + doubanid=transer_item.doubanid, mtype=mtype, - season=season, - transfer_type=transfer_type, + season=transer_item.season, + transfer_type=transer_item.transfer_type, epformat=epformat, - min_filesize=min_filesize, - scrape=scrape, + min_filesize=transer_item.min_filesize, + scrape=transer_item.scrape, force=force ) # 失败 diff --git a/app/chain/transfer.py b/app/chain/transfer.py index 1f326b28..c3ae4016 100644 --- a/app/chain/transfer.py +++ b/app/chain/transfer.py @@ -32,7 +32,7 @@ lock = threading.Lock() class TransferChain(ChainBase): """ - 文件转移处理链 + 文件整理处理链 """ def __init__(self): @@ -45,7 +45,7 @@ class TransferChain(ChainBase): self.storagechain = StorageChain() self.systemconfig = SystemConfigOper() self.directoryhelper = DirectoryHelper() - self.all_exts = settings.RMT_MEDIAEXT + settings.RMT_SUBEXT + settings.RMT_AUDIO_TRACK_EXT + self.all_exts = settings.RMT_MEDIAEXT def recommend_name(self, meta: MetaBase, mediainfo: MediaInfo) -> Optional[str]: """ @@ -58,7 +58,7 @@ class TransferChain(ChainBase): def process(self) -> bool: """ - 获取下载器中的种子列表,并执行转移 + 获取下载器中的种子列表,并执行整理 """ # 全局锁,避免重复处理 @@ -122,7 +122,7 @@ class TransferChain(ChainBase): # 非MoviePilot下载的任务,按文件识别 mediainfo = None - # 执行转移 + # 执行整理 self.__do_transfer( fileitem=FileItem( storage="local", @@ -152,23 +152,21 @@ class TransferChain(ChainBase): min_filesize: int = 0, scrape: bool = None, force: bool = False) -> Tuple[bool, str]: """ - 执行一个复杂目录的转移操作 + 执行一个复杂目录的整理操作 :param fileitem: 文件项 :param meta: 元数据 :param mediainfo: 媒体信息 :param download_hash: 下载记录hash :param target_storage: 目标存储器 :param target_path: 目标路径 - :param transfer_type: 转移类型 + :param transfer_type: 整理类型 :param season: 季 :param epformat: 剧集格式 :param min_filesize: 最小文件大小(MB) :param scrape: 是否刮削元数据 - :param force: 是否强制转移 + :param force: 是否强制整理 返回:成功标识,错误信息 """ - if not transfer_type: - transfer_type = 'link' # 自定义格式 formaterHandler = FormatParser(eformat=epformat.format, @@ -191,19 +189,19 @@ class TransferChain(ChainBase): # 跳过数量 skip_num = 0 - # 获取待转移路径清单 + # 获取待整理路径清单 trans_items = self.__get_trans_fileitems(fileitem) # 总文件数 total_num = len(trans_items) self.progress.update(value=0, - text=f"开始转移 {fileitem.path},共 {total_num} 个文件或子目录 ...", + text=f"开始 {fileitem.path},共 {total_num} 个文件或子目录 ...", key=ProgressKey.FileTransfer) if not trans_items: - logger.warn(f"{fileitem.path} 没有找到可转移的媒体文件") - return False, f"{fileitem.name} 没有找到可转移的媒体文件" + logger.warn(f"{fileitem.path} 没有找到可整理的媒体文件") + return False, f"{fileitem.name} 没有找到可整理的媒体文件" - # 处理所有待转移目录或文件,默认一个转移路径或文件只有一个媒体信息 + # 处理所有待整理目录或文件,默认一个整理路径或文件只有一个媒体信息 for trans_item in trans_items: # 汇总季集清单 season_episodes: Dict[Tuple, List[int]] = {} @@ -211,21 +209,17 @@ class TransferChain(ChainBase): metas: Dict[Tuple, MetaBase] = {} # 汇总媒体信息 medias: Dict[Tuple, MediaInfo] = {} - # 汇总转移信息 + # 汇总整理信息 transfers: Dict[Tuple, TransferInfo] = {} item_path = Path(trans_item.path) - # 如果是目录且不是⼀蓝光原盘,获取所有文件并转移 + # 如果是目录且不是⼀蓝光原盘,获取所有文件并整理 if (trans_item.type == "dir" - and not (trans_item.storage == "local" and not SystemUtils.is_bluray_dir(item_path))): + and not (trans_item.storage == "local" and SystemUtils.is_bluray_dir(item_path))): # 遍历获取下载目录所有文件(递归) file_items = self.storagechain.list_files(trans_item, recursion=True) if not file_items: continue - # 过滤后缀和大小 - file_items = [f for f in file_items - if f.extension and (f".{f.extension.lower()}" in self.all_exts - and (not min_filesize or f.size > min_filesize * 1024 * 1024))] else: # 文件或蓝光目录 file_items = [trans_item] @@ -234,7 +228,18 @@ class TransferChain(ChainBase): # 有集自定义格式,过滤文件 file_items = [f for f in file_items if formaterHandler.match(f.name)] - # 转移所有文件 + # 过滤后缀和大小 + file_items = [f for f in file_items + if f.extension and (f".{f.extension.lower()}" in self.all_exts + and (not min_filesize or f.size > min_filesize * 1024 * 1024))] + + if not file_items: + logger.warn(f"{fileitem.path} 没有找到可整理的媒体文件") + return False, f"{fileitem.name} 没有找到可整理的媒体文件" + + logger.info(f"正在整理 {len(file_items)} 个文件...") + + # 整理所有文件 for file_item in file_items: file_path = Path(file_item.path) # 回收站及隐藏的文件不处理 @@ -265,11 +270,11 @@ class TransferChain(ChainBase): skip_num += 1 continue - # 转移成功的不再处理 + # 整理成功的不再处理 if not force: transferd = self.transferhis.get_by_src(file_item.path) if transferd and transferd.status: - logger.info(f"{file_item.path} 已成功转移过,如需重新处理,请删除历史记录。") + logger.info(f"{file_item.path} 已成功整理过,如需重新处理,请删除历史记录。") # 计数 processed_num += 1 skip_num += 1 @@ -277,7 +282,7 @@ class TransferChain(ChainBase): # 更新进度 self.progress.update(value=processed_num / total_num * 100, - text=f"正在转移 ({processed_num + 1}/{total_num}){file_item.name} ...", + text=f"正在整理 ({processed_num + 1}/{total_num}){file_item.name} ...", key=ProgressKey.FileTransfer) if not meta: @@ -316,7 +321,7 @@ class TransferChain(ChainBase): if not file_mediainfo: logger.warn(f'{file_path} 未识别到媒体信息') - # 新增转移失败历史记录 + # 新增整理失败历史记录 his = self.transferhis.add_fail( fileitem=file_item, mode=transfer_type, @@ -326,7 +331,7 @@ class TransferChain(ChainBase): self.post_message(Notification( mtype=NotificationType.Manual, title=f"{file_path.name} 未识别到媒体信息,无法入库!", - text=f"回复:```\n/redo {his.id} [tmdbid]|[类型]\n``` 手动识别转移。", + text=f"回复:```\n/redo {his.id} [tmdbid]|[类型]\n``` 手动识别整理。", link=settings.MP_DOMAIN('#/history') )) # 计数 @@ -361,7 +366,7 @@ class TransferChain(ChainBase): if download_file: download_hash = download_file.download_hash - # 执行转移 + # 执行整理 transferinfo: TransferInfo = self.transfer(fileitem=file_item, meta=file_meta, mediainfo=file_mediainfo, @@ -371,13 +376,13 @@ class TransferChain(ChainBase): episodes_info=episodes_info, scrape=scrape) if not transferinfo: - logger.error("文件转移模块运行失败") - return False, "文件转移模块运行失败" + logger.error("文件整理模块运行失败") + return False, "文件整理模块运行失败" if not transferinfo.success: - # 转移失败 + # 整理失败 logger.warn(f"{file_path.name} 入库失败:{transferinfo.message}") err_msgs.append(f"{file_path.name} {transferinfo.message}") - # 新增转移失败历史记录 + # 新增整理失败历史记录 self.transferhis.add_fail( fileitem=file_item, mode=transfer_type, @@ -410,17 +415,17 @@ class TransferChain(ChainBase): else: # 合并季集清单 season_episodes[mkey] = list(set(season_episodes[mkey] + file_meta.episode_list)) - # 合并转移数据 + # 合并整理数据 transfers[mkey].file_count += transferinfo.file_count transfers[mkey].total_size += transferinfo.total_size transfers[mkey].file_list.extend(transferinfo.file_list) transfers[mkey].file_list_new.extend(transferinfo.file_list_new) transfers[mkey].fail_list.extend(transferinfo.fail_list) - # 新增转移成功历史记录 + # 新增整理成功历史记录 self.transferhis.add_success( fileitem=file_item, - mode=transfer_type, + mode=transfer_type or transferinfo.transfer_type, download_hash=download_hash, meta=file_meta, mediainfo=file_mediainfo, @@ -438,11 +443,11 @@ class TransferChain(ChainBase): # 更新进度 processed_num += 1 self.progress.update(value=processed_num / total_num * 100, - text=f"{file_path.name} 转移完成", + text=f"{file_path.name} 整理完成", key=ProgressKey.FileTransfer) - # 目录或文件转移完成 - self.progress.update(text=f"{trans_item.path} 转移完成,正在执行后续处理 ...", + # 目录或文件整理完成 + self.progress.update(text=f"{trans_item.path} 整理完成,正在执行后续处理 ...", key=ProgressKey.FileTransfer) # 执行后续处理 @@ -464,11 +469,11 @@ class TransferChain(ChainBase): 'transferinfo': transfer_info }) # 结束进度 - logger.info(f"{fileitem.path} 转移完成,共 {total_num} 个文件," + logger.info(f"{fileitem.path} 整理完成,共 {total_num} 个文件," f"失败 {fail_num} 个,跳过 {skip_num} 个") self.progress.update(value=100, - text=f"{fileitem.path} 转移完成,共 {total_num} 个文件," + text=f"{fileitem.path} 整理完成,共 {total_num} 个文件," f"失败 {fail_num} 个,跳过 {skip_num} 个", key=ProgressKey.FileTransfer) # 结速进度 @@ -478,7 +483,7 @@ class TransferChain(ChainBase): def __get_trans_fileitems(self, fileitem: FileItem): """ - 获取转移目录列表 + 获取整理目录或文件列表 """ file_path = Path(fileitem.path) @@ -495,7 +500,7 @@ class TransferChain(ChainBase): if fileitem.storage == "local" and SystemUtils.is_bluray_dir(file_path): return [fileitem] - # 需要转移的文件项列表 + # 需要整理的文件项列表 trans_items = [] # 先检查当前目录的下级目录,以支持合集的情况 @@ -511,13 +516,13 @@ class TransferChain(ChainBase): trans_items.append(sub_dir) if not trans_items: - # 没有有效子目录,直接转移当前目录 + # 没有有效子目录,直接整理当前目录 trans_items.append(fileitem) else: - # 有子目录时,把当前目录的文件添加到转移任务中 + # 有子目录时,把当前目录的文件添加到整理任务中 sub_items = self.storagechain.list_files(fileitem) if sub_items: - sub_files = [f for f in sub_items if f.type == "file" and f".{f.extension.lower()}" in self.all_exts] + sub_files = [f for f in sub_items if f.type == "file"] if sub_files: trans_items.extend(sub_files) @@ -525,7 +530,7 @@ class TransferChain(ChainBase): def remote_transfer(self, arg_str: str, channel: MessageChannel, userid: Union[str, int] = None): """ - 远程重新转移,参数 历史记录ID TMDBID|类型 + 远程重新整理,参数 历史记录ID TMDBID|类型 """ def args_error(): @@ -567,7 +572,7 @@ class TransferChain(ChainBase): def __re_transfer(self, logid: int, mtype: MediaType = None, mediaid: str = None) -> Tuple[bool, str]: """ - 根据历史记录,重新识别转移,只支持简单条件 + 根据历史记录,重新识别整理,只支持简单条件 :param logid: 历史记录ID :param mtype: 媒体类型 :param mediaid: TMDB ID/豆瓣ID @@ -577,7 +582,7 @@ class TransferChain(ChainBase): if not history: logger.error(f"历史记录不存在,ID:{logid}") return False, "历史记录不存在" - # 按源目录路径重新转移 + # 按源目录路径重新整理 src_path = Path(history.src) if not src_path.exists(): return False, f"源目录不存在:{src_path}" @@ -592,7 +597,7 @@ class TransferChain(ChainBase): mediainfo = self.mediachain.recognize_by_path(str(src_path)) if not mediainfo: return False, f"未识别到媒体信息,类型:{mtype.value},id:{mediaid}" - # 重新执行转移 + # 重新执行整理 logger.info(f"{src_path.name} 识别为:{mediainfo.title_year}") # 删除旧的已整理文件 @@ -601,7 +606,7 @@ class TransferChain(ChainBase): dest_fileitem = FileItem(**json.loads(history.dest_fileitem)) self.storagechain.delete_file(dest_fileitem) - # 强制转移 + # 强制整理 if history.src_fileitem: # 解析源文件对象 fileitem = FileItem(**json.loads(history.src_fileitem)) @@ -628,7 +633,7 @@ class TransferChain(ChainBase): scrape: bool = None, force: bool = False) -> Tuple[bool, Union[str, list]]: """ - 手动转移,支持复杂条件,带进度显示 + 手动整理,支持复杂条件,带进度显示 :param fileitem: 文件项 :param target_storage: 目标存储 :param target_path: 目标路径 @@ -636,13 +641,13 @@ class TransferChain(ChainBase): :param doubanid: 豆瓣ID :param mtype: 媒体类型 :param season: 季度 - :param transfer_type: 转移类型 + :param transfer_type: 整理类型 :param epformat: 剧集格式 :param min_filesize: 最小文件大小(MB) :param scrape: 是否刮削元数据 - :param force: 是否强制转移 + :param force: 是否强制整理 """ - logger.info(f"手动转移:{fileitem.path} ...") + logger.info(f"手动整理:{fileitem.path} ...") if tmdbid or doubanid: # 有输入TMDBID时单个识别 @@ -656,9 +661,9 @@ class TransferChain(ChainBase): # 开始进度 self.progress.start(ProgressKey.FileTransfer) self.progress.update(value=0, - text=f"开始转移 {fileitem.path} ...", + text=f"开始整理 {fileitem.path} ...", key=ProgressKey.FileTransfer) - # 开始转移 + # 开始整理 state, errmsg = self.__do_transfer( fileitem=fileitem, target_storage=target_storage, @@ -675,7 +680,7 @@ class TransferChain(ChainBase): return False, errmsg self.progress.end(ProgressKey.FileTransfer) - logger.info(f"{fileitem.path} 转移完成") + logger.info(f"{fileitem.path} 整理完成") return True, "" else: # 没有输入TMDBID时,按文件识别 diff --git a/app/db/transferhistory_oper.py b/app/db/transferhistory_oper.py index 7699a8fc..c31cb4e9 100644 --- a/app/db/transferhistory_oper.py +++ b/app/db/transferhistory_oper.py @@ -160,7 +160,7 @@ class TransferHistoryOper(DbOper): src_fileitem=json.dumps(fileitem.dict()), dest=transferinfo.target_item.path if transferinfo.target_item else None, dest_storage=transferinfo.target_item.storage if transferinfo.target_item else None, - dest_fileitem=json.dumps(transferinfo.target_item.dict()), + dest_fileitem=json.dumps(transferinfo.target_item.dict()) if transferinfo.target_item else None, mode=mode, type=mediainfo.type.value, category=mediainfo.category, diff --git a/app/modules/filemanager/__init__.py b/app/modules/filemanager/__init__.py index 14a3b3d5..dbb76984 100644 --- a/app/modules/filemanager/__init__.py +++ b/app/modules/filemanager/__init__.py @@ -166,6 +166,7 @@ class FileManagerModule(_ModuleBase): result.append(t) else: result.extend(_items) + # 返回结果 result = [] __get_files(fileitem, recursion) @@ -292,6 +293,9 @@ class FileManagerModule(_ModuleBase): # 目标存储类型 if not target_storage: target_storage = dir_info.library_storage + # 整理方式 + if not transfer_type: + transfer_type = dir_info.transfer_type # 是否需要刮削 if scrape is None: need_scrape = dir_info.scraping @@ -692,10 +696,11 @@ class FileManagerModule(_ModuleBase): transfer_type=transfer_type) if new_item: logger.info(f"文件 {fileitem.path} {transfer_type}完成") + return new_item, errmsg else: logger.error(f"文件{fileitem.path} {transfer_type}失败:{errmsg}") - return target_item, errmsg + return None, errmsg def __transfer_dir_files(self, fileitem: FileItem, transfer_type: str, target_storage: str, target_path: Path) -> Tuple[Optional[FileItem], str]: @@ -733,7 +738,7 @@ class FileManagerModule(_ModuleBase): if not new_item: return None, errmsg # 返回成功 - return FileItem(), "" + return storage_oper.get_item(target_path), "" def __transfer_file(self, fileitem: FileItem, target_storage: str, target_file: Path, transfer_type: str, over_flag: bool = False) -> Tuple[Optional[FileItem], str]: @@ -857,15 +862,17 @@ class FileManagerModule(_ModuleBase): return TransferInfo(success=False, message=errmsg, fileitem=fileitem, - target_path=new_path) + target_path=new_path, + transfer_type=transfer_type) logger.info(f"文件夹 {fileitem.path} 整理成功") # 返回整理后的路径 return TransferInfo(success=True, fileitem=fileitem, - target_fileitem=new_item, + target_item=new_item, total_size=fileitem.size, - need_scrape=need_scrape) + need_scrape=need_scrape, + transfer_type=transfer_type) else: # 整理单个文件 if mediainfo.type == MediaType.TV: @@ -875,7 +882,8 @@ class FileManagerModule(_ModuleBase): return TransferInfo(success=False, message=f"未识别到文件集数", fileitem=fileitem, - fail_list=[fileitem.path]) + fail_list=[fileitem.path], + transfer_type=transfer_type) # 文件结束季为空 in_meta.end_season = None @@ -930,15 +938,17 @@ class FileManagerModule(_ModuleBase): return TransferInfo(success=False, message=f"媒体库存在同名文件,且质量更好", fileitem=fileitem, - target_fileitem=__get_targetitem(target_file), - fail_list=[fileitem.path]) + target_item=__get_targetitem(target_file), + fail_list=[fileitem.path], + transfer_type=transfer_type) case 'never': # 存在不覆盖 return TransferInfo(success=False, message=f"媒体库存在同名文件,当前覆盖模式为不覆盖", fileitem=fileitem, - target_fileitem=__get_targetitem(target_file), - fail_list=[fileitem.path]) + target_item=__get_targetitem(target_file), + fail_list=[fileitem.path], + transfer_type=transfer_type) case 'latest': # 仅保留最新版本 logger.info(f"当前整理覆盖模式设置为仅保留最新版本,将覆盖:{new_file}") @@ -959,7 +969,8 @@ class FileManagerModule(_ModuleBase): return TransferInfo(success=False, message=err_msg, fileitem=fileitem, - fail_list=[fileitem.path]) + fail_list=[fileitem.path], + transfer_type=transfer_type) logger.info(f"文件 {fileitem.path} 整理成功") return TransferInfo(success=True, @@ -969,7 +980,8 @@ class FileManagerModule(_ModuleBase): total_size=fileitem.size, file_list=[fileitem.path], file_list_new=[new_item.path], - need_scrape=need_scrape) + need_scrape=need_scrape, + transfer_type=transfer_type) @staticmethod def __get_naming_dict(meta: MetaBase, mediainfo: MediaInfo, file_ext: str = None, diff --git a/app/monitor.py b/app/monitor.py index 7bf54064..c7bf4872 100644 --- a/app/monitor.py +++ b/app/monitor.py @@ -97,6 +97,8 @@ class Monitor(metaclass=Singleton): self.systemmessage = MessageHelper() self.systemconfig = SystemConfigOper() + self.all_exts = settings.RMT_MEDIAEXT + # 启动目录监控和文件整理 self.init() @@ -269,7 +271,7 @@ class Monitor(metaclass=Singleton): return # 不是媒体文件不处理 - if event_path.suffix not in settings.RMT_MEDIAEXT: + if event_path.suffix.lower() not in self.all_exts: logger.debug(f"{event_path} 不是媒体文件") return diff --git a/app/schemas/transfer.py b/app/schemas/transfer.py index 5e55a6f1..972cbd1a 100644 --- a/app/schemas/transfer.py +++ b/app/schemas/transfer.py @@ -48,6 +48,8 @@ class TransferInfo(BaseModel): fileitem: Optional[FileItem] = None # 转移后路径 target_item: Optional[FileItem] = None + # 整理方式 + transfer_type: Optional[str] = None # 处理文件数 file_count: Optional[int] = 0 # 处理文件清单