Revert "feat:在子进程中操作文件"

This reverts commit 4f304a70b7.
This commit is contained in:
jxxghp
2025-09-08 17:23:25 +08:00
parent d30b9282fd
commit b201e9ab8c
+107 -103
View File
@@ -1,8 +1,4 @@
import multiprocessing
import os
import re import re
import shutil
import sys
from pathlib import Path from pathlib import Path
from threading import Lock from threading import Lock
from typing import Optional, List, Tuple from typing import Optional, List, Tuple
@@ -19,9 +15,9 @@ from app.helper.message import TemplateHelper
from app.log import logger from app.log import logger
from app.modules.filemanager.storages import StorageBase from app.modules.filemanager.storages import StorageBase
from app.schemas import TransferInfo, TmdbEpisode, TransferDirectoryConf, FileItem, TransferInterceptEventData from app.schemas import TransferInfo, TmdbEpisode, TransferDirectoryConf, FileItem, TransferInterceptEventData
from app.schemas import TransferRenameEventData
from app.schemas.types import MediaType, ChainEventType from app.schemas.types import MediaType, ChainEventType
from app.utils.system import SystemUtils from app.utils.system import SystemUtils
from app.schemas import TransferRenameEventData
lock = Lock() lock = Lock()
@@ -243,8 +239,7 @@ class TransHandler:
overflag = True overflag = True
if not overflag: if not overflag:
# 目标文件已存在 # 目标文件已存在
logger.info( logger.info(f"目的文件系统中已经存在同名文件 {target_file},当前整理覆盖模式设置为 {overwrite_mode}")
f"目的文件系统中已经存在同名文件 {target_file},当前整理覆盖模式设置为 {overwrite_mode}")
if overwrite_mode == 'always': if overwrite_mode == 'always':
# 总是覆盖同名文件 # 总是覆盖同名文件
overflag = True overflag = True
@@ -328,118 +323,127 @@ class TransHandler:
:param target_file: 目标文件路径 :param target_file: 目标文件路径
:param transfer_type: 整理方式 :param transfer_type: 整理方式
""" """
def __get_targetitem(_path: Path) -> FileItem:
"""
获取文件信息
"""
return FileItem(
storage=target_storage,
path=_path.as_posix(),
name=_path.name,
basename=_path.stem,
type="file",
size=_path.stat().st_size,
extension=_path.suffix.lstrip('.'),
modify_time=_path.stat().st_mtime
)
if (fileitem.storage != target_storage if (fileitem.storage != target_storage
and fileitem.storage != "local" and target_storage != "local"): and fileitem.storage != "local" and target_storage != "local"):
return None, f"不支持 {fileitem.storage}{target_storage} 的文件整理" return None, f"不支持 {fileitem.storage}{target_storage} 的文件整理"
def _do_transfer() -> Tuple[bool, str]: # 加锁
""" with lock:
执行文件整理 if fileitem.storage == "local" and target_storage == "local":
""" # 创建目录
try: if not target_file.parent.exists():
if fileitem.storage == "local" and target_storage == "local": target_file.parent.mkdir(parents=True)
if not target_file.parent.exists(): # 本地到本地
target_file.parent.mkdir(parents=True) if transfer_type == "copy":
if transfer_type == "copy": state = source_oper.copy(fileitem, target_file.parent, target_file.name)
shutil.copy2(fileitem.path, target_file.as_posix()) elif transfer_type == "move":
elif transfer_type == "move": state = source_oper.move(fileitem, target_file.parent, target_file.name)
SystemUtils.move(Path(fileitem.path), target_file) elif transfer_type == "link":
elif transfer_type == "link": state = source_oper.link(fileitem, target_file)
os.link(fileitem.path, target_file) elif transfer_type == "softlink":
elif transfer_type == "softlink": state = source_oper.softlink(fileitem, target_file)
os.symlink(fileitem.path, target_file) else:
else: return None, f"不支持的整理方式:{transfer_type}"
return False, f"不支持的整理方式:{transfer_type}" if state:
return True, "" return __get_targetitem(target_file), ""
elif fileitem.storage == "local" and target_storage != "local": else:
filepath = Path(fileitem.path) return None, f"{fileitem.path} {transfer_type} 失败"
if not filepath.exists(): elif fileitem.storage == "local" and target_storage != "local":
return False, f"文件 {filepath} 不存在" # 本地到网盘
if transfer_type in ["copy", "move"]: filepath = Path(fileitem.path)
target_fileitem = target_oper.get_folder(target_file.parent) if not filepath.exists():
if not target_fileitem: return None, f"文件 {filepath} 不存在"
return False, f"{target_storage}{target_file.parent} 目录获取失败" if transfer_type == "copy":
# 复制
# 根据目的路径创建文件夹
target_fileitem = target_oper.get_folder(target_file.parent)
if target_fileitem:
# 上传文件
new_item = target_oper.upload(target_fileitem, filepath, target_file.name) new_item = target_oper.upload(target_fileitem, filepath, target_file.name)
if not new_item: if new_item:
return False, f"{fileitem.path} 上传 {target_storage} 失败" return new_item, ""
if transfer_type == "move": else:
source_oper.delete(fileitem) return None, f"{fileitem.path} 上传 {target_storage} 失败"
return True, ""
else: else:
return False, f"不支持的整理方式:{transfer_type}" return None, f"{target_storage}{target_file.parent} 目录获取失败"
elif fileitem.storage != "local" and target_storage == "local": elif transfer_type == "move":
if target_file.exists(): # 移动
logger.warn(f"文件已存在:{target_file}") # 根据目的路径获取文件夹
return True, "" target_fileitem = target_oper.get_folder(target_file.parent)
if transfer_type in ["copy", "move"]: if target_fileitem:
tmp_file = source_oper.download(fileitem=fileitem, path=target_file.parent) # 上传文件
if not tmp_file: new_item = target_oper.upload(target_fileitem, filepath, target_file.name)
return False, f"{fileitem.path} {fileitem.storage} 下载失败" if new_item:
# 删除源文件
source_oper.delete(fileitem)
return new_item, ""
else:
return None, f"{fileitem.path} 上传 {target_storage} 失败"
else:
return None, f"{target_storage}{target_file.parent} 目录获取失败"
elif fileitem.storage != "local" and target_storage == "local":
# 网盘到本地
if target_file.exists():
logger.warn(f"文件已存在:{target_file}")
return __get_targetitem(target_file), ""
# 网盘到本地
if transfer_type in ["copy", "move"]:
# 下载
tmp_file = source_oper.download(fileitem=fileitem, path=target_file.parent)
if tmp_file:
# 创建目录
if not target_file.parent.exists(): if not target_file.parent.exists():
target_file.parent.mkdir(parents=True) target_file.parent.mkdir(parents=True)
# 将tmp_file移动后target_file
SystemUtils.move(tmp_file, target_file) SystemUtils.move(tmp_file, target_file)
if transfer_type == "move": if transfer_type == "move":
# 删除源文件
source_oper.delete(fileitem) source_oper.delete(fileitem)
return True, "" return __get_targetitem(target_file), ""
else: else:
return False, f"不支持的整理方式:{transfer_type}" return None, f"{fileitem.path} {fileitem.storage} 下载失败"
elif fileitem.storage == target_storage: elif fileitem.storage == target_storage:
# 同一网盘
if transfer_type == "copy":
# 复制文件到新目录
target_fileitem = target_oper.get_folder(target_file.parent) target_fileitem = target_oper.get_folder(target_file.parent)
if not target_fileitem: if target_fileitem:
return False, f"{target_storage}{target_file.parent} 目录获取失败" if source_oper.move(fileitem, Path(target_fileitem.path), target_file.name):
if transfer_type in ["copy", "move"]: return target_oper.get_item(target_file), ""
if not source_oper.move(fileitem, Path(target_fileitem.path), target_file.name): else:
return False, f"{target_storage}{fileitem.path} {'复制' if transfer_type == 'copy' else '移动'}文件失败" return None, f"{target_storage}{fileitem.path} 复制文件失败"
return True, ""
else: else:
return False, f"不支持的整理方式:{transfer_type}" return None, f"{target_storage}{target_file.parent} 目录获取失败"
elif transfer_type == "move":
# 移动文件到新目录
target_fileitem = target_oper.get_folder(target_file.parent)
if target_fileitem:
if source_oper.move(fileitem, Path(target_fileitem.path), target_file.name):
return target_oper.get_item(target_file), ""
else:
return None, f"{target_storage}{fileitem.path} 移动文件失败"
else:
return None, f"{target_storage}{target_file.parent} 目录获取失败"
else: else:
return False, "未知错误" return None, f"不支持的整理方式:{transfer_type}"
except Exception as _e:
return False, str(_e)
def _worker_action(): return None, "未知错误"
"""
子进程执行函数
"""
_success, _msg = _do_transfer()
if _success:
sys.exit(0)
logger.error(f"子进程执行失败:{_msg}")
sys.exit(10)
# 在新进程中执行以降低内存占用
try:
ctx = multiprocessing.get_context("fork")
except ValueError:
ctx = None
if ctx is not None:
# 新进程执行
logger.info(f"在新进程中整理文件 {fileitem.path}")
proc = ctx.Process(target=_worker_action)
# 加锁以避免与当前进程内其他并发调用发生竞争
with lock:
proc.start()
proc.join()
if proc.exitcode == 0:
# 成功
item = target_oper.get_item(target_file)
if item:
return item, ""
return None, f"{target_storage}{target_file} 获取失败"
else:
return None, f"{fileitem.path} {transfer_type} 失败"
else:
# 当前进程执行
success, errmsg = _do_transfer()
if success:
item = target_oper.get_item(target_file)
if item:
return item, ""
return None, f"{target_storage}{target_file} 获取失败"
return None, errmsg
def __transfer_other_files(self, fileitem: FileItem, target_storage: str, def __transfer_other_files(self, fileitem: FileItem, target_storage: str,
source_oper: StorageBase, target_oper: StorageBase, source_oper: StorageBase, target_oper: StorageBase,