mirror of
https://github.com/d0zingcat/MoviePilot-Plugins.git
synced 2026-05-13 23:16:47 +00:00
Merge pull request #220 from DzAvril/dev
This commit is contained in:
@@ -387,11 +387,12 @@
|
||||
"RemoveLink": {
|
||||
"name": "清理硬链接",
|
||||
"description": "监控目录内文件被删除时,同步删除监控目录内所有和它硬链接的文件",
|
||||
"version": "1.7",
|
||||
"version": "1.8",
|
||||
"icon": "Ombi_A.png",
|
||||
"author": "DzAvril",
|
||||
"level": 1,
|
||||
"history": {
|
||||
"v1.8": "增加清理空目录功能(beta)",
|
||||
"v1.7": "修复因未监测重命名事件导致的清理硬链接失败的问题",
|
||||
"v1.6": "提升插件性能"
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class FileMonitorHandler(FileSystemEventHandler):
|
||||
# 新增文件记录
|
||||
with state_lock:
|
||||
self.sync.state_set[str(file_path)] = file_path.stat().st_ino
|
||||
|
||||
|
||||
def on_moved(self, event):
|
||||
if event.is_directory:
|
||||
return
|
||||
@@ -106,7 +106,7 @@ class RemoveLink(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "Ombi_A.png"
|
||||
# 插件版本
|
||||
plugin_version = "1.7"
|
||||
plugin_version = "1.8"
|
||||
# 插件作者
|
||||
plugin_author = "DzAvril"
|
||||
# 作者主页
|
||||
@@ -124,6 +124,7 @@ class RemoveLink(_PluginBase):
|
||||
exclude_keywords = ""
|
||||
_enabled = False
|
||||
_notify = False
|
||||
_delete_empty = False
|
||||
_observer = []
|
||||
# 监控目录的文件列表
|
||||
state_set: Dict[str, int] = {}
|
||||
@@ -136,6 +137,7 @@ class RemoveLink(_PluginBase):
|
||||
self.monitor_dirs = config.get("monitor_dirs")
|
||||
self.exclude_dirs = config.get("exclude_dirs") or ""
|
||||
self.exclude_keywords = config.get("exclude_keywords") or ""
|
||||
self._delete_empty = config.get("delete_empty")
|
||||
|
||||
# 停止现有任务
|
||||
self.stop_service()
|
||||
@@ -224,6 +226,19 @@ class RemoveLink(_PluginBase):
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"component": "VCol",
|
||||
"props": {"cols": 12, "md": 4},
|
||||
"content": [
|
||||
{
|
||||
"component": "VSwitch",
|
||||
"props": {
|
||||
"model": "delete_empty",
|
||||
"label": "清理空目录(beta)",
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -289,32 +304,47 @@ class RemoveLink(_PluginBase):
|
||||
],
|
||||
},
|
||||
{
|
||||
'component': 'VRow',
|
||||
'content': [
|
||||
"component": "VRow",
|
||||
"content": [
|
||||
{
|
||||
'component': 'VCol',
|
||||
'props': {
|
||||
'cols': 12,
|
||||
"component": "VCol",
|
||||
"props": {
|
||||
"cols": 12,
|
||||
},
|
||||
'content': [
|
||||
"content": [
|
||||
{
|
||||
'component': 'VAlert',
|
||||
'props': {
|
||||
'type': 'info',
|
||||
'variant': 'tonal',
|
||||
'text': '监控目录如有多个需换行,源目录和硬链接目录都需要添加到监控目录中;如需实现删除硬链接时不删除源文件,可把源文件目录配置到不删除目录中。'
|
||||
}
|
||||
"component": "VAlert",
|
||||
"props": {
|
||||
"type": "info",
|
||||
"variant": "tonal",
|
||||
"text": "监控目录如有多个需换行,源目录和硬链接目录都需要添加到监控目录中;如需实现删除硬链接时不删除源文件,可把源文件目录配置到不删除目录中。",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"component": "VCol",
|
||||
"props": {
|
||||
"cols": 12,
|
||||
},
|
||||
"content": [
|
||||
{
|
||||
"component": "VAlert",
|
||||
"props": {
|
||||
"type": "info",
|
||||
"variant": "tonal",
|
||||
"text": "清理空目录为测试功能,请谨慎开启。",
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
], {
|
||||
"enabled": False,
|
||||
"notify": False,
|
||||
"onlyonce": False,
|
||||
"monitor_dirs": "",
|
||||
"exclude_keywords": "",
|
||||
}
|
||||
@@ -344,13 +374,42 @@ class RemoveLink(_PluginBase):
|
||||
if exclude_dir and exclude_dir in str(file_path):
|
||||
return True
|
||||
return False
|
||||
|
||||
def delete_empty_folders(self, path):
|
||||
"""
|
||||
从指定路径开始,逐级向上层目录检测并删除空目录,直到遇到非空目录或到达指定监控目录为止
|
||||
"""
|
||||
if not self._delete_empty:
|
||||
return
|
||||
while True:
|
||||
parent_path = os.path.dirname(path)
|
||||
# parent_path如已被删除则退出检查
|
||||
if not os.path.exists(parent_path):
|
||||
break
|
||||
# 如果当前路径等于监控目录之一,停止向上检查
|
||||
if parent_path in self.monitor_dirs.split("\n"):
|
||||
break
|
||||
# 检查当前目录是否为空且不在排除列表内
|
||||
if not os.listdir(parent_path) and not self.__is_excluded(parent_path):
|
||||
os.rmdir(parent_path)
|
||||
logger.info(f"清理空目录:{parent_path}")
|
||||
if self._notify:
|
||||
self.post_message(
|
||||
mtype=NotificationType.SiteMessage,
|
||||
title=f"【清理硬链接】",
|
||||
text=f"清理空文件夹:[{parent_path}]\n",
|
||||
)
|
||||
else:
|
||||
break
|
||||
# 更新路径为父目录,准备下一轮检查
|
||||
path = parent_path
|
||||
def handle_deleted(self, file_path: Path):
|
||||
"""
|
||||
处理删除事件
|
||||
"""
|
||||
# 删除的文件对应的监控信息
|
||||
with state_lock:
|
||||
# 清理空目录
|
||||
self.delete_empty_folders(file_path)
|
||||
# 删除的文件inode
|
||||
deleted_inode = self.state_set.get(str(file_path))
|
||||
if not deleted_inode:
|
||||
@@ -369,12 +428,16 @@ class RemoveLink(_PluginBase):
|
||||
# 删除硬链接文件
|
||||
logger.info(f"删除硬链接文件:{path}, inode: {inode}")
|
||||
file.unlink()
|
||||
# 清理空目录
|
||||
self.delete_empty_folders(file)
|
||||
if self._notify:
|
||||
self.post_message(
|
||||
mtype=NotificationType.SiteMessage,
|
||||
title=f"【清理硬链接】",
|
||||
text=f"监控到删除源文件:[{file_path}]\n"
|
||||
f"同步删除硬链接文件:[{path}]",
|
||||
f"同步删除硬链接文件:[{path}]",
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error("删除硬链接文件发生错误:%s - %s" % (str(e), traceback.format_exc()))
|
||||
logger.error(
|
||||
"删除硬链接文件发生错误:%s - %s" % (str(e), traceback.format_exc())
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user