mirror of
https://github.com/jxxghp/MoviePilot-Plugins.git
synced 2026-06-01 07:26:51 +00:00
fix: filter watchfiles temporary files
This commit is contained in:
12
package.json
12
package.json
@@ -114,11 +114,12 @@
|
||||
"name": "目录监控",
|
||||
"description": "监控目录文件发生变化时实时整理到媒体库。",
|
||||
"labels": "文件整理",
|
||||
"version": "2.5",
|
||||
"version": "2.5.1",
|
||||
"icon": "directory.png",
|
||||
"author": "jxxghp",
|
||||
"level": 1,
|
||||
"history": {
|
||||
"v2.5.1": "过滤下载临时文件和不可整理文件,避免目录监控误触发整理",
|
||||
"v2.5": "目录监控改用watchfiles,移除旧监控依赖",
|
||||
"v2.4": "修复目录监控不使用ChatGPT辅助识别问题",
|
||||
"v2.3": "特殊场景下补充转移成功历史记录",
|
||||
@@ -372,11 +373,12 @@
|
||||
"name": "整理VCB动漫压制组作品",
|
||||
"description": "一款辅助整理&提高识别VCB-Stuido动漫压制组作品的插件",
|
||||
"labels": "文件整理,识别",
|
||||
"version": "1.8.2.3",
|
||||
"version": "1.8.2.4",
|
||||
"icon": "vcbmonitor.png",
|
||||
"author": "pixel@qingwa",
|
||||
"level": 2,
|
||||
"history": {
|
||||
"v1.8.2.4": "过滤下载临时文件和不可整理文件,避免目录监控误触发整理",
|
||||
"v1.8.2.3": "目录监控改用watchfiles,移除旧监控依赖",
|
||||
"v1.8.2.1": "修复日志输出&同步目录监控插件功能",
|
||||
"v1.8.2": "提高识别率",
|
||||
@@ -641,12 +643,13 @@
|
||||
"name": "清理硬链接",
|
||||
"description": "监控目录内文件被删除时,同步删除监控目录内所有和它硬链接的文件",
|
||||
"labels": "文件整理",
|
||||
"version": "2.3",
|
||||
"version": "2.3.1",
|
||||
"icon": "Ombi_A.png",
|
||||
"author": "DzAvril",
|
||||
"level": 1,
|
||||
"v2": true,
|
||||
"history": {
|
||||
"v2.3.1": "优化下载临时文件过滤,避免清理硬链接处理未完成文件",
|
||||
"v2.3": "目录监控改用watchfiles,移除旧监控依赖",
|
||||
"v2.2": "修复直接删除文件夹导致的插件崩溃的bug",
|
||||
"v2.1": "联动删除历史记录",
|
||||
@@ -661,12 +664,13 @@
|
||||
"name": "实时硬链接",
|
||||
"description": "监控目录文件变化,实时硬链接。",
|
||||
"labels": "文件整理",
|
||||
"version": "1.7",
|
||||
"version": "1.7.1",
|
||||
"icon": "Linkace_C.png",
|
||||
"author": "jxxghp",
|
||||
"level": 1,
|
||||
"v2": true,
|
||||
"history": {
|
||||
"v1.7.1": "过滤下载临时文件,避免实时硬链接处理未完成文件",
|
||||
"v1.7": "目录监控改用watchfiles,移除旧监控依赖",
|
||||
"v1.6": "增强API安全性"
|
||||
}
|
||||
|
||||
@@ -31,6 +31,29 @@ from app.utils.system import SystemUtils
|
||||
lock = threading.Lock()
|
||||
|
||||
|
||||
def _has_suffix_in(file_path: Path, extensions: List[str]) -> bool:
|
||||
"""
|
||||
判断文件后缀是否命中给定扩展名列表。
|
||||
"""
|
||||
if not file_path.suffix:
|
||||
return False
|
||||
return file_path.suffix.casefold() in {ext.casefold() for ext in extensions}
|
||||
|
||||
|
||||
def _is_download_tmp_file(file_path: Path) -> bool:
|
||||
"""
|
||||
判断文件是否为下载器尚未完成的临时文件。
|
||||
"""
|
||||
return _has_suffix_in(file_path, settings.DOWNLOAD_TMPEXT)
|
||||
|
||||
|
||||
def _is_monitor_media_file(file_path: Path) -> bool:
|
||||
"""
|
||||
判断文件是否为目录监控可整理的媒体文件。
|
||||
"""
|
||||
return not _is_download_tmp_file(file_path) and _has_suffix_in(file_path, settings.RMT_MEDIAEXT)
|
||||
|
||||
|
||||
class WatchfilesEvent:
|
||||
"""
|
||||
watchfiles 目录监控事件。
|
||||
@@ -173,7 +196,10 @@ class FileMonitorHandler:
|
||||
path = Path(event_path)
|
||||
if not path.exists():
|
||||
return
|
||||
event = WatchfilesEvent(src_path=event_path, is_directory=path.is_dir())
|
||||
is_directory = path.is_dir()
|
||||
if not is_directory and not _is_monitor_media_file(path):
|
||||
return
|
||||
event = WatchfilesEvent(src_path=event_path, is_directory=is_directory)
|
||||
text = "修改" if change_type == Change.modified else "创建"
|
||||
self.sync.event_handler(event=event, text=text,
|
||||
mon_path=self._watch_path, event_path=event_path)
|
||||
@@ -187,7 +213,7 @@ class DirMonitor(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "directory.png"
|
||||
# 插件版本
|
||||
plugin_version = "2.5"
|
||||
plugin_version = "2.5.1"
|
||||
# 插件作者
|
||||
plugin_author = "jxxghp"
|
||||
# 作者主页
|
||||
@@ -424,6 +450,8 @@ class DirMonitor(_PluginBase):
|
||||
try:
|
||||
if not file_path.exists():
|
||||
return
|
||||
if not _is_monitor_media_file(file_path):
|
||||
return
|
||||
# 全程加锁
|
||||
with lock:
|
||||
transfer_history = self.transferhis.get_by_src(event_path)
|
||||
@@ -457,8 +485,7 @@ class DirMonitor(_PluginBase):
|
||||
return
|
||||
|
||||
# 不是媒体文件不处理
|
||||
if file_path.suffix.casefold() not in map(str.casefold, settings.RMT_MEDIAEXT):
|
||||
logger.debug(f"{event_path} 不是媒体文件")
|
||||
if not _is_monitor_media_file(file_path):
|
||||
return
|
||||
|
||||
# 判断是不是蓝光目录
|
||||
|
||||
@@ -22,6 +22,22 @@ from app.utils.system import SystemUtils
|
||||
lock = threading.Lock()
|
||||
|
||||
|
||||
def _has_suffix_in(file_path: Path, extensions: List[str]) -> bool:
|
||||
"""
|
||||
判断文件后缀是否命中给定扩展名列表。
|
||||
"""
|
||||
if not file_path.suffix:
|
||||
return False
|
||||
return file_path.suffix.casefold() in {ext.casefold() for ext in extensions}
|
||||
|
||||
|
||||
def _is_download_tmp_file(file_path: Path) -> bool:
|
||||
"""
|
||||
判断文件是否为下载器尚未完成的临时文件。
|
||||
"""
|
||||
return _has_suffix_in(file_path, settings.DOWNLOAD_TMPEXT)
|
||||
|
||||
|
||||
class WatchfilesEvent:
|
||||
"""
|
||||
watchfiles 目录监控事件。
|
||||
@@ -164,7 +180,10 @@ class FileMonitorHandler:
|
||||
path = Path(event_path)
|
||||
if not path.exists():
|
||||
return
|
||||
event = WatchfilesEvent(src_path=event_path, is_directory=path.is_dir())
|
||||
is_directory = path.is_dir()
|
||||
if not is_directory and _is_download_tmp_file(path):
|
||||
return
|
||||
event = WatchfilesEvent(src_path=event_path, is_directory=is_directory)
|
||||
text = "修改" if change_type == Change.modified else "创建"
|
||||
self.sync.event_handler(event=event, text=text,
|
||||
mon_path=self._watch_path, event_path=event_path)
|
||||
@@ -178,7 +197,7 @@ class LinkMonitor(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "Linkace_C.png"
|
||||
# 插件版本
|
||||
plugin_version = "1.7"
|
||||
plugin_version = "1.7.1"
|
||||
# 插件作者
|
||||
plugin_author = "jxxghp"
|
||||
# 作者主页
|
||||
@@ -414,6 +433,8 @@ class LinkMonitor(_PluginBase):
|
||||
try:
|
||||
if not file_path.exists():
|
||||
return
|
||||
if _is_download_tmp_file(file_path):
|
||||
return
|
||||
# 全程加锁
|
||||
with lock:
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from pathlib import Path
|
||||
from typing import List, Tuple, Dict, Any, Optional
|
||||
|
||||
from watchfiles import Change, watch
|
||||
from app.core.config import settings
|
||||
from app.db.transferhistory_oper import TransferHistoryOper
|
||||
from app.log import logger
|
||||
from app.plugins import _PluginBase
|
||||
@@ -16,6 +17,22 @@ from app.schemas.types import EventType
|
||||
state_lock = threading.Lock()
|
||||
|
||||
|
||||
def _has_suffix_in(file_path: Path, extensions: List[str]) -> bool:
|
||||
"""
|
||||
判断文件后缀是否命中给定扩展名列表。
|
||||
"""
|
||||
if not file_path.suffix:
|
||||
return False
|
||||
return file_path.suffix.casefold() in {ext.casefold() for ext in extensions}
|
||||
|
||||
|
||||
def _is_download_tmp_file(file_path: Path) -> bool:
|
||||
"""
|
||||
判断文件是否为下载器尚未完成的临时文件。
|
||||
"""
|
||||
return _has_suffix_in(file_path, settings.DOWNLOAD_TMPEXT + [".mp"])
|
||||
|
||||
|
||||
class WatchfilesEvent:
|
||||
"""
|
||||
watchfiles 目录监控事件。
|
||||
@@ -204,7 +221,7 @@ class FileMonitorHandler:
|
||||
self.sync.dir_state_set.add(str(Path(event.src_path)))
|
||||
return
|
||||
file_path = Path(event.src_path)
|
||||
if file_path.suffix in [".!qB", ".part", ".mp"]:
|
||||
if _is_download_tmp_file(file_path):
|
||||
return
|
||||
logger.info(f"监测到新增文件:{file_path}")
|
||||
if self.sync.exclude_keywords:
|
||||
@@ -227,7 +244,7 @@ class FileMonitorHandler:
|
||||
if event.is_directory:
|
||||
return
|
||||
file_path = Path(event.dest_path)
|
||||
if file_path.suffix in [".!qB", ".part", ".mp"]:
|
||||
if _is_download_tmp_file(file_path):
|
||||
return
|
||||
logger.info(f"监测到新增文件:{file_path}")
|
||||
if self.sync.exclude_keywords:
|
||||
@@ -255,7 +272,7 @@ class FileMonitorHandler:
|
||||
EventType.DownloadFileDeleted, {"src": str(file_path)}
|
||||
)
|
||||
return
|
||||
if file_path.suffix in [".!qB", ".part", ".mp"]:
|
||||
if _is_download_tmp_file(file_path):
|
||||
return
|
||||
logger.info(f"监测到删除文件:{file_path}")
|
||||
# 命中过滤关键字不处理
|
||||
@@ -304,7 +321,7 @@ class RemoveLink(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "Ombi_A.png"
|
||||
# 插件版本
|
||||
plugin_version = "2.3"
|
||||
plugin_version = "2.3.1"
|
||||
# 插件作者
|
||||
plugin_author = "DzAvril"
|
||||
# 作者主页
|
||||
|
||||
@@ -32,6 +32,36 @@ from app.utils.system import SystemUtils
|
||||
lock = threading.Lock()
|
||||
|
||||
|
||||
def _has_suffix_in(file_path: Path, extensions: List[str]) -> bool:
|
||||
"""
|
||||
判断文件后缀是否命中给定扩展名列表。
|
||||
"""
|
||||
if not file_path.suffix:
|
||||
return False
|
||||
return file_path.suffix.casefold() in {ext.casefold() for ext in extensions}
|
||||
|
||||
|
||||
def _is_download_tmp_file(file_path: Path) -> bool:
|
||||
"""
|
||||
判断文件是否为下载器尚未完成的临时文件。
|
||||
"""
|
||||
return _has_suffix_in(file_path, settings.DOWNLOAD_TMPEXT)
|
||||
|
||||
|
||||
def _is_monitor_media_file(file_path: Path) -> bool:
|
||||
"""
|
||||
判断文件是否为目录监控可整理的媒体文件。
|
||||
"""
|
||||
return not _is_download_tmp_file(file_path) and _has_suffix_in(file_path, settings.RMT_MEDIAEXT)
|
||||
|
||||
|
||||
def _is_torrent_file(file_path: Path) -> bool:
|
||||
"""
|
||||
判断文件是否为已完成的种子文件。
|
||||
"""
|
||||
return not _is_download_tmp_file(file_path) and file_path.suffix.casefold() == ".torrent"
|
||||
|
||||
|
||||
class WatchfilesEvent:
|
||||
"""
|
||||
watchfiles 目录监控事件。
|
||||
@@ -174,7 +204,10 @@ class FileMonitorHandler:
|
||||
path = Path(event_path)
|
||||
if not path.exists():
|
||||
return
|
||||
event = WatchfilesEvent(src_path=event_path, is_directory=path.is_dir())
|
||||
is_directory = path.is_dir()
|
||||
if not is_directory and not _is_monitor_media_file(path):
|
||||
return
|
||||
event = WatchfilesEvent(src_path=event_path, is_directory=is_directory)
|
||||
text = "修改" if change_type == Change.modified else "创建"
|
||||
self.sync.event_handler(event=event, text=text,
|
||||
mon_path=self._watch_path, event_path=event_path)
|
||||
@@ -205,7 +238,10 @@ class TorrentHandler:
|
||||
path = Path(event_path)
|
||||
if not path.exists():
|
||||
return
|
||||
event = WatchfilesEvent(src_path=event_path, is_directory=path.is_dir())
|
||||
is_directory = path.is_dir()
|
||||
if is_directory or not _is_torrent_file(path):
|
||||
return
|
||||
event = WatchfilesEvent(src_path=event_path, is_directory=is_directory)
|
||||
text = "修改" if change_type == Change.modified else "创建"
|
||||
self.sync.torrent_event(event=event, text=text, mon_path=self._watch_path)
|
||||
|
||||
@@ -218,7 +254,7 @@ class VCBAnimeMonitor(_PluginBase):
|
||||
# 插件图标
|
||||
plugin_icon = "vcbmonitor.png"
|
||||
# 插件版本
|
||||
plugin_version = "1.8.2.3"
|
||||
plugin_version = "1.8.2.4"
|
||||
# 插件作者
|
||||
plugin_author = "pixel@qingwa"
|
||||
# 作者主页
|
||||
@@ -483,6 +519,8 @@ class VCBAnimeMonitor(_PluginBase):
|
||||
try:
|
||||
if not file_path.exists():
|
||||
return
|
||||
if not _is_monitor_media_file(file_path):
|
||||
return
|
||||
# 全程加锁
|
||||
with lock:
|
||||
transfer_history = self.transferhis.get_by_src(event_path)
|
||||
@@ -516,8 +554,7 @@ class VCBAnimeMonitor(_PluginBase):
|
||||
return
|
||||
|
||||
# 不是媒体文件不处理
|
||||
if file_path.suffix not in settings.RMT_MEDIAEXT:
|
||||
logger.debug(f"{event_path} 不是媒体文件")
|
||||
if not _is_monitor_media_file(file_path):
|
||||
return
|
||||
|
||||
# 判断是不是蓝光目录
|
||||
@@ -778,12 +815,10 @@ class VCBAnimeMonitor(_PluginBase):
|
||||
:param mon_path: 种子目录
|
||||
"""
|
||||
evc_path = Path(event.src_path)
|
||||
if not event.is_directory and (evc_path.suffix == ".torrent" or str(evc_path).split('.')[1] == "torrent"):
|
||||
if not event.is_directory and _is_torrent_file(evc_path):
|
||||
# 文件发生变化
|
||||
logger.debug("文件%s:%s" % (text, mon_path))
|
||||
self.__handle_torrent(torrent_path=self._torrents_path)
|
||||
else:
|
||||
logger.debug("不是种子文件:%s" % mon_path)
|
||||
|
||||
def __handle_torrent(self, torrent_path: str):
|
||||
torrent_path = Path(torrent_path)
|
||||
|
||||
Reference in New Issue
Block a user