mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/jxxghp/MoviePilot.git
synced 2026-09-20 08:03:34 +08:00
feat(transfer): control mounted directory cleanup
This commit is contained in:
@@ -928,6 +928,36 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton):
|
||||
or "/@eaDir" in normalized_path
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def __should_delete_empty_source_directories(
|
||||
task: TransferTask,
|
||||
delete_mounted_local_disk_empty_dirs: bool,
|
||||
mounted_filesystem_cache: Dict[Path, bool],
|
||||
) -> bool:
|
||||
"""
|
||||
判断移动整理后是否应删除源空目录。
|
||||
|
||||
仅在关闭挂载盘空目录清理且源存储为本地时检测文件系统,
|
||||
避免默认流程产生额外系统调用。
|
||||
"""
|
||||
if delete_mounted_local_disk_empty_dirs:
|
||||
return True
|
||||
if task.fileitem.storage != "local":
|
||||
return True
|
||||
|
||||
source_directory = (
|
||||
Path(task.target_directory.download_path)
|
||||
if task.target_directory and task.target_directory.download_path
|
||||
else Path(task.fileitem.path).parent
|
||||
)
|
||||
if source_directory not in mounted_filesystem_cache:
|
||||
mounted_filesystem_cache[source_directory] = (
|
||||
SystemUtils.is_network_filesystem(
|
||||
source_directory, include_local_fuse=True
|
||||
)
|
||||
)
|
||||
return not mounted_filesystem_cache[source_directory]
|
||||
|
||||
def __default_callback(
|
||||
self, task: TransferTask, transferinfo: TransferInfo, /
|
||||
) -> Tuple[bool, str]:
|
||||
@@ -1189,10 +1219,16 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton):
|
||||
tasks = self.jobview.success_tasks(
|
||||
task.mediainfo, task.meta.begin_season
|
||||
)
|
||||
system_config_oper = SystemConfigOper()
|
||||
# 获取整理屏蔽词
|
||||
transfer_exclude_words = SystemConfigOper().get(
|
||||
transfer_exclude_words = system_config_oper.get(
|
||||
SystemConfigKey.TransferExcludeWords
|
||||
)
|
||||
# 挂载盘空目录清理默认开启
|
||||
delete_mounted_local_disk_empty_dirs = system_config_oper.get(
|
||||
SystemConfigKey.MountedLocalDiskDeleteEmptyDirs
|
||||
) is not False
|
||||
mounted_filesystem_cache: Dict[Path, bool] = {}
|
||||
processed_hashes = set()
|
||||
for t in tasks:
|
||||
if t.download_hash and t.download_hash not in processed_hashes:
|
||||
@@ -1209,7 +1245,15 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton):
|
||||
logger.info(
|
||||
f"移动模式删除种子成功:{t.download_hash}"
|
||||
)
|
||||
if not t.download_hash and t.fileitem:
|
||||
if (
|
||||
not t.download_hash
|
||||
and t.fileitem
|
||||
and self.__should_delete_empty_source_directories(
|
||||
t,
|
||||
delete_mounted_local_disk_empty_dirs,
|
||||
mounted_filesystem_cache,
|
||||
)
|
||||
):
|
||||
# 删除剩余空目录
|
||||
StorageChain().delete_media_file(t.fileitem, delete_self=False)
|
||||
|
||||
|
||||
@@ -215,6 +215,8 @@ class SystemConfigKey(Enum):
|
||||
NotificationSwitchs = "NotificationSwitchs"
|
||||
# 目录配置
|
||||
Directories = "Directories"
|
||||
# 挂载型本地盘是否删除空目录
|
||||
MountedLocalDiskDeleteEmptyDirs = "MountedLocalDiskDeleteEmptyDirs"
|
||||
# 存储配置
|
||||
Storages = "Storages"
|
||||
# 搜索站点范围
|
||||
|
||||
@@ -828,10 +828,13 @@ class SystemUtils:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def is_network_filesystem(directory: Path) -> bool:
|
||||
def is_network_filesystem(
|
||||
directory: Path, include_local_fuse: bool = False
|
||||
) -> bool:
|
||||
"""
|
||||
检测是否为网络文件系统
|
||||
:param directory: 目录路径
|
||||
:param include_local_fuse: 是否将本地 FUSE 挂载视为挂载文件系统
|
||||
:return: 是否为网络文件系统
|
||||
"""
|
||||
try:
|
||||
@@ -849,7 +852,10 @@ class SystemUtils:
|
||||
"fuseblk",
|
||||
# TBD
|
||||
]
|
||||
if any(fs in output for fs in local_fs):
|
||||
if (
|
||||
not include_local_fuse
|
||||
and any(fs in output for fs in local_fs)
|
||||
):
|
||||
return False
|
||||
network_fs = ['nfs', 'cifs', 'smbfs', 'fuse', 'sshfs', 'ftpfs']
|
||||
return any(fs in output for fs in network_fs)
|
||||
@@ -859,7 +865,11 @@ class SystemUtils:
|
||||
capture_output=True, text=True, timeout=5)
|
||||
if result.returncode == 0:
|
||||
output = result.stdout.lower()
|
||||
return 'nfs' in output or 'smbfs' in output
|
||||
return (
|
||||
'nfs' in output
|
||||
or 'smbfs' in output
|
||||
or (include_local_fuse and 'fuse' in output)
|
||||
)
|
||||
elif system == 'Windows':
|
||||
# Windows 检查网络驱动器
|
||||
return str(directory).startswith('\\\\')
|
||||
|
||||
Reference in New Issue
Block a user