fix 删种失败删除源文件
This commit is contained in:
parent
7d4ec4d8a0
commit
270c11bb8b
@ -2,6 +2,7 @@ import datetime
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import shutil
|
||||||
import time
|
import time
|
||||||
from typing import List, Tuple, Dict, Any, Optional
|
from typing import List, Tuple, Dict, Any, Optional
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ from app.modules.jellyfin import Jellyfin
|
|||||||
from app.modules.themoviedb.tmdbv3api import Episode
|
from app.modules.themoviedb.tmdbv3api import Episode
|
||||||
from app.plugins import _PluginBase
|
from app.plugins import _PluginBase
|
||||||
from app.schemas.types import NotificationType, EventType
|
from app.schemas.types import NotificationType, EventType
|
||||||
|
from app.utils.path_utils import PathUtils
|
||||||
|
|
||||||
|
|
||||||
class MediaSyncDel(_PluginBase):
|
class MediaSyncDel(_PluginBase):
|
||||||
@ -496,8 +498,21 @@ class MediaSyncDel(_PluginBase):
|
|||||||
self._transferhis.delete(transferhis.id)
|
self._transferhis.delete(transferhis.id)
|
||||||
del_cnt += 1
|
del_cnt += 1
|
||||||
# 删除种子任务
|
# 删除种子任务
|
||||||
if self._del_source and transferhis.download_hash:
|
if self._del_source:
|
||||||
|
del_source = False
|
||||||
|
if transferhis.download_hash:
|
||||||
|
try:
|
||||||
self.chain.remove_torrents(transferhis.download_hash)
|
self.chain.remove_torrents(transferhis.download_hash)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("删除种子失败,尝试删除源文件:%s" % str(e))
|
||||||
|
del_source = True
|
||||||
|
|
||||||
|
# 直接删除源文件
|
||||||
|
if del_source:
|
||||||
|
source_name = os.path.basename(transferhis.src)
|
||||||
|
source_path = str(transferhis.src).replace(source_name, "")
|
||||||
|
self.delete_media_file(filedir=source_path,
|
||||||
|
filename=source_name)
|
||||||
|
|
||||||
logger.info(f"同步删除 {msg} 完成!")
|
logger.info(f"同步删除 {msg} 完成!")
|
||||||
|
|
||||||
@ -632,8 +647,21 @@ class MediaSyncDel(_PluginBase):
|
|||||||
image = transferhis.image
|
image = transferhis.image
|
||||||
self._transferhis.delete(transferhis.id)
|
self._transferhis.delete(transferhis.id)
|
||||||
# 删除种子任务
|
# 删除种子任务
|
||||||
if self._del_source and transferhis.download_hash:
|
if self._del_source:
|
||||||
|
del_source = False
|
||||||
|
if transferhis.download_hash:
|
||||||
|
try:
|
||||||
self.chain.remove_torrents(transferhis.download_hash)
|
self.chain.remove_torrents(transferhis.download_hash)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("删除种子失败,尝试删除源文件:%s" % str(e))
|
||||||
|
del_source = True
|
||||||
|
|
||||||
|
# 直接删除源文件
|
||||||
|
if del_source:
|
||||||
|
source_name = os.path.basename(transferhis.src)
|
||||||
|
source_path = str(transferhis.src).replace(source_name, "")
|
||||||
|
self.delete_media_file(filedir=source_path,
|
||||||
|
filename=source_name)
|
||||||
|
|
||||||
logger.info(f"同步删除 {msg} 完成!")
|
logger.info(f"同步删除 {msg} 完成!")
|
||||||
|
|
||||||
@ -807,6 +835,42 @@ class MediaSyncDel(_PluginBase):
|
|||||||
|
|
||||||
return del_medias
|
return del_medias
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def delete_media_file(filedir, filename):
|
||||||
|
"""
|
||||||
|
删除媒体文件,空目录也会被删除
|
||||||
|
"""
|
||||||
|
filedir = os.path.normpath(filedir).replace("\\", "/")
|
||||||
|
file = os.path.join(filedir, filename)
|
||||||
|
try:
|
||||||
|
if not os.path.exists(file):
|
||||||
|
return False, f"{file} 不存在"
|
||||||
|
os.remove(file)
|
||||||
|
nfoname = f"{os.path.splitext(filename)[0]}.nfo"
|
||||||
|
nfofile = os.path.join(filedir, nfoname)
|
||||||
|
if os.path.exists(nfofile):
|
||||||
|
os.remove(nfofile)
|
||||||
|
# 检查空目录并删除
|
||||||
|
if re.findall(r"^S\d{2}|^Season", os.path.basename(filedir), re.I):
|
||||||
|
# 当前是季文件夹,判断并删除
|
||||||
|
seaon_dir = filedir
|
||||||
|
if seaon_dir.count('/') > 1 and not PathUtils.get_dir_files(seaon_dir, exts=settings.RMT_MEDIAEXT):
|
||||||
|
shutil.rmtree(seaon_dir)
|
||||||
|
# 媒体文件夹
|
||||||
|
media_dir = os.path.dirname(seaon_dir)
|
||||||
|
else:
|
||||||
|
media_dir = filedir
|
||||||
|
# 检查并删除媒体文件夹,非根目录且目录大于二级,且没有媒体文件时才会删除
|
||||||
|
if media_dir != '/' \
|
||||||
|
and media_dir.count('/') > 1 \
|
||||||
|
and not re.search(r'[a-zA-Z]:/$', media_dir) \
|
||||||
|
and not PathUtils.get_dir_files(media_dir, exts=settings.RMT_MEDIAEXT):
|
||||||
|
shutil.rmtree(media_dir)
|
||||||
|
return True, f"{file} 删除成功"
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("删除源文件失败:%s" % str(e))
|
||||||
|
return True, f"{file} 删除失败"
|
||||||
|
|
||||||
def get_state(self):
|
def get_state(self):
|
||||||
return self._enabled
|
return self._enabled
|
||||||
|
|
||||||
@ -833,7 +897,7 @@ class MediaSyncDel(_PluginBase):
|
|||||||
self.post_message(channel=event.event_data.get("channel"),
|
self.post_message(channel=event.event_data.get("channel"),
|
||||||
title="开始媒体库同步删除 ...",
|
title="开始媒体库同步删除 ...",
|
||||||
userid=event.event_data.get("user"))
|
userid=event.event_data.get("user"))
|
||||||
self.sync_del()
|
self.sync_del_by_log()
|
||||||
|
|
||||||
if event:
|
if event:
|
||||||
self.post_message(channel=event.event_data.get("channel"),
|
self.post_message(channel=event.event_data.get("channel"),
|
||||||
|
155
app/utils/path_utils.py
Normal file
155
app/utils/path_utils.py
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class PathUtils:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_dir_files(in_path, exts="", filesize=0, episode_format=None):
|
||||||
|
"""
|
||||||
|
获得目录下的媒体文件列表List ,按后缀、大小、格式过滤
|
||||||
|
"""
|
||||||
|
if not in_path:
|
||||||
|
return []
|
||||||
|
if not os.path.exists(in_path):
|
||||||
|
return []
|
||||||
|
ret_list = []
|
||||||
|
if os.path.isdir(in_path):
|
||||||
|
for root, dirs, files in os.walk(in_path):
|
||||||
|
for file in files:
|
||||||
|
cur_path = os.path.join(root, file)
|
||||||
|
# 检查路径是否合法
|
||||||
|
if PathUtils.is_invalid_path(cur_path):
|
||||||
|
continue
|
||||||
|
# 检查格式匹配
|
||||||
|
if episode_format and not episode_format.match(file):
|
||||||
|
continue
|
||||||
|
# 检查后缀
|
||||||
|
if exts and os.path.splitext(file)[-1].lower() not in exts:
|
||||||
|
continue
|
||||||
|
# 检查文件大小
|
||||||
|
if filesize and os.path.getsize(cur_path) < filesize:
|
||||||
|
continue
|
||||||
|
# 命中
|
||||||
|
if cur_path not in ret_list:
|
||||||
|
ret_list.append(cur_path)
|
||||||
|
else:
|
||||||
|
# 检查路径是否合法
|
||||||
|
if PathUtils.is_invalid_path(in_path):
|
||||||
|
return []
|
||||||
|
# 检查后缀
|
||||||
|
if exts and os.path.splitext(in_path)[-1].lower() not in exts:
|
||||||
|
return []
|
||||||
|
# 检查格式
|
||||||
|
if episode_format and not episode_format.match(os.path.basename(in_path)):
|
||||||
|
return []
|
||||||
|
# 检查文件大小
|
||||||
|
if filesize and os.path.getsize(in_path) < filesize:
|
||||||
|
return []
|
||||||
|
ret_list.append(in_path)
|
||||||
|
return ret_list
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_dir_level1_files(in_path, exts=""):
|
||||||
|
"""
|
||||||
|
查询目录下的文件(只查询一级)
|
||||||
|
"""
|
||||||
|
ret_list = []
|
||||||
|
if not os.path.exists(in_path):
|
||||||
|
return []
|
||||||
|
for file in os.listdir(in_path):
|
||||||
|
path = os.path.join(in_path, file)
|
||||||
|
if os.path.isfile(path):
|
||||||
|
if not exts or os.path.splitext(file)[-1].lower() in exts:
|
||||||
|
ret_list.append(path)
|
||||||
|
return ret_list
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_dir_level1_medias(in_path, exts=""):
|
||||||
|
"""
|
||||||
|
根据后缀,返回目录下所有的文件及文件夹列表(只查询一级)
|
||||||
|
"""
|
||||||
|
ret_list = []
|
||||||
|
if not os.path.exists(in_path):
|
||||||
|
return []
|
||||||
|
if os.path.isdir(in_path):
|
||||||
|
for file in os.listdir(in_path):
|
||||||
|
path = os.path.join(in_path, file)
|
||||||
|
if os.path.isfile(path):
|
||||||
|
if not exts or os.path.splitext(file)[-1].lower() in exts:
|
||||||
|
ret_list.append(path)
|
||||||
|
else:
|
||||||
|
ret_list.append(path)
|
||||||
|
else:
|
||||||
|
ret_list.append(in_path)
|
||||||
|
return ret_list
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_invalid_path(path):
|
||||||
|
"""
|
||||||
|
判断是否不能处理的路径
|
||||||
|
"""
|
||||||
|
if not path:
|
||||||
|
return True
|
||||||
|
if path.find('/@Recycle/') != -1 or path.find('/#recycle/') != -1 or path.find('/.') != -1 or path.find(
|
||||||
|
'/@eaDir') != -1:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_path_in_path(path1, path2):
|
||||||
|
"""
|
||||||
|
判断两个路径是否包含关系 path1 in path2
|
||||||
|
"""
|
||||||
|
if not path1 or not path2:
|
||||||
|
return False
|
||||||
|
path1 = os.path.normpath(path1).replace("\\", "/")
|
||||||
|
path2 = os.path.normpath(path2).replace("\\", "/")
|
||||||
|
if path1 == path2:
|
||||||
|
return True
|
||||||
|
path = os.path.dirname(path2)
|
||||||
|
while True:
|
||||||
|
if path == path1:
|
||||||
|
return True
|
||||||
|
path = os.path.dirname(path)
|
||||||
|
if path == os.path.dirname(path):
|
||||||
|
break
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_bluray_dir(path):
|
||||||
|
"""
|
||||||
|
判断是否蓝光原盘目录,是则返回原盘的根目录,否则返回空
|
||||||
|
"""
|
||||||
|
if not path or not os.path.exists(path):
|
||||||
|
return None
|
||||||
|
if os.path.isdir(path):
|
||||||
|
if os.path.exists(os.path.join(path, "BDMV", "index.bdmv")):
|
||||||
|
return path
|
||||||
|
elif os.path.normpath(path).endswith("BDMV") \
|
||||||
|
and os.path.exists(os.path.join(path, "index.bdmv")):
|
||||||
|
return os.path.dirname(path)
|
||||||
|
elif os.path.normpath(path).endswith("STREAM") \
|
||||||
|
and os.path.exists(os.path.join(os.path.dirname(path), "index.bdmv")):
|
||||||
|
return PathUtils.get_parent_paths(path, 2)
|
||||||
|
else:
|
||||||
|
# 电视剧原盘下会存在多个目录形如:Spider Man 2021/DIsc1, Spider Man 2021/Disc2
|
||||||
|
for level1 in PathUtils.get_dir_level1_medias(path):
|
||||||
|
if os.path.exists(os.path.join(level1, "BDMV", "index.bdmv")):
|
||||||
|
return path
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
if str(os.path.splitext(path)[-1]).lower() in [".m2ts", ".ts"] \
|
||||||
|
and os.path.normpath(os.path.dirname(path)).endswith("STREAM") \
|
||||||
|
and os.path.exists(os.path.join(PathUtils.get_parent_paths(path, 2), "index.bdmv")):
|
||||||
|
return PathUtils.get_parent_paths(path, 3)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_parent_paths(path, level: int = 1):
|
||||||
|
"""
|
||||||
|
获取父目录路径,level为向上查找的层数
|
||||||
|
"""
|
||||||
|
for lv in range(0, level):
|
||||||
|
path = os.path.dirname(path)
|
||||||
|
return path
|
Loading…
x
Reference in New Issue
Block a user