diff --git a/app/templates/index.html b/app/templates/index.html
index c1df197..294333f 100644
--- a/app/templates/index.html
+++ b/app/templates/index.html
@@ -379,10 +379,10 @@
-
+
diff --git a/quark_auto_save.py b/quark_auto_save.py
index d81c2fe..bbe9d36 100644
--- a/quark_auto_save.py
+++ b/quark_auto_save.py
@@ -417,6 +417,9 @@ def send_ql_notify(title, body):
# 添加消息
def add_notify(text):
global NOTIFYS
+ # 防止重复添加相同的通知
+ if text in NOTIFYS:
+ return text
NOTIFYS.append(text)
print(text)
return text
@@ -855,7 +858,7 @@ class Quark:
else:
if retry_index == 0:
print(
- f"正在等待[{response['data']['task_title']}]执行结果",
+ f"正在等待「{response['data']['task_title']}」执行结果",
end="",
flush=True,
)
@@ -1143,7 +1146,7 @@ class Quark:
return tree
- def dir_check_and_save(self, task, pwd_id, stoken, pdir_fid="", subdir_path=""):
+ def dir_check_and_save(self, task, pwd_id, stoken, pdir_fid="", subdir_path="", parent_dir_info=None):
tree = Tree()
# 获取分享文件列表
share_file_list = self.get_detail(pwd_id, stoken, pdir_fid)["list"]
@@ -1164,6 +1167,14 @@ class Quark:
pwd_id, stoken, share_file_list[0]["fid"]
)["list"]
+ # 添加父目录信息传递,用于确定是否在更新目录内
+ if parent_dir_info is None:
+ parent_dir_info = {
+ "in_update_dir": False, # 标记是否在更新目录内
+ "update_dir_pattern": task.get("update_subdir", ""), # 保存更新目录的正则表达式
+ "dir_path": [] # 保存目录路径
+ }
+
# 应用过滤词过滤
if task.get("filterwords"):
# 记录过滤前的文件总数(包括文件夹)
@@ -1257,13 +1268,15 @@ class Quark:
to_pdir_fid = self.savepath_fid[savepath]
dir_file_list = self.ls_dir(to_pdir_fid)
- tree.create_node(
- savepath,
- pdir_fid,
- data={
- "is_dir": True,
- },
- )
+ # 检查根节点是否已存在
+ if not tree.contains(pdir_fid):
+ tree.create_node(
+ savepath,
+ pdir_fid,
+ data={
+ "is_dir": True,
+ },
+ )
# 处理顺序命名模式
if task.get("use_sequence_naming") and task.get("sequence_naming"):
@@ -1312,9 +1325,8 @@ class Quark:
filtered_share_files = []
for share_file in share_file_list:
if share_file["dir"]:
- # 处理子目录
- if task.get("update_subdir") and re.search(task["update_subdir"], share_file["file_name"]):
- filtered_share_files.append(share_file)
+ # 不再直接添加目录到filtered_share_files
+ # 目录处理会在后续专门的循环中进行
continue
file_size = share_file.get("size", 0)
@@ -1402,8 +1414,11 @@ class Quark:
# 处理子文件夹
for share_file in share_file_list:
if share_file["dir"] and task.get("update_subdir", False):
- if re.search(task["update_subdir"], share_file["file_name"]):
- print(f"检查子文件夹: {savepath}/{share_file['file_name']}")
+ # 确定是否处理此目录:
+ # 1. 如果当前在更新目录内,则处理所有子目录
+ # 2. 如果不在更新目录内,只处理符合更新目录规则的子目录
+ if (parent_dir_info and parent_dir_info.get("in_update_dir", False)) or re.search(task["update_subdir"], share_file["file_name"]):
+ # print(f"检查子目录: {savepath}/{share_file['file_name']}")
# 创建一个子任务对象,保留原任务的属性,但专门用于子目录处理
subdir_task = task.copy()
@@ -1419,6 +1434,21 @@ class Quark:
# 取消顺序命名和剧集命名模式,强制使用正则模式
subdir_task["use_sequence_naming"] = False
subdir_task["use_episode_naming"] = False
+
+ # 更新子目录的parent_dir_info,跟踪目录路径和更新状态
+ current_parent_info = parent_dir_info.copy() if parent_dir_info else {
+ "in_update_dir": False,
+ "update_dir_pattern": task.get("update_subdir", ""),
+ "dir_path": []
+ }
+
+ # 如果当前文件夹符合更新目录规则,标记为在更新目录内
+ if re.search(task["update_subdir"], share_file["file_name"]):
+ current_parent_info["in_update_dir"] = True
+
+ # 添加当前目录到路径
+ current_parent_info["dir_path"] = current_parent_info["dir_path"].copy() if "dir_path" in current_parent_info else []
+ current_parent_info["dir_path"].append(share_file["file_name"])
subdir_tree = self.dir_check_and_save(
subdir_task,
@@ -1426,6 +1456,7 @@ class Quark:
stoken,
share_file["fid"],
f"{subdir_path}/{share_file['file_name']}",
+ current_parent_info
)
# 只有当子目录树有实际内容(大于1表示不只有根节点)时才处理
if subdir_tree.size(1) > 0:
@@ -1458,11 +1489,30 @@ class Quark:
tree.merge(share_file["fid"], subdir_tree, deep=False)
# 标记此文件夹有更新
- if share_file.get("has_updates") is False:
- for item in need_save_list:
- if item.get("fid") == share_file["fid"]:
- item["has_updates"] = True
+ # 检查文件夹是否已添加到need_save_list
+ folder_in_list = False
+ for item in need_save_list:
+ if item.get("fid") == share_file["fid"]:
+ item["has_updates"] = True
+ folder_in_list = True
+ break
+
+ # 如果文件夹未添加到need_save_list,需要添加
+ if not folder_in_list and has_files:
+ # 检查目标目录中是否已存在同名文件夹
+ dir_exists = False
+ for dir_file in dir_file_list:
+ if dir_file["dir"] and dir_file["file_name"] == share_file["file_name"]:
+ dir_exists = True
break
+
+ # 如果存在同名文件夹,检查文件夹内是否有更新
+ # 如果不存在同名文件夹,或者文件夹内有更新,则添加到保存列表
+ if not dir_exists or has_files:
+ share_file["save_name"] = share_file["file_name"]
+ share_file["original_name"] = share_file["file_name"]
+ share_file["has_updates"] = True
+ need_save_list.append(share_file)
else:
# 正则命名模式
@@ -1548,6 +1598,90 @@ class Quark:
# 设置匹配模式:目录使用update_subdir,文件使用普通正则
if share_file["dir"] and task.get("update_subdir", False):
+ # 确定是否处理此目录:
+ # 1. 如果当前在更新目录内,则处理所有子目录
+ # 2. 如果不在更新目录内,只处理符合更新目录规则的子目录
+ if parent_dir_info and parent_dir_info.get("in_update_dir", False):
+ # 已经在更新目录内,处理所有子目录
+ pass
+ elif not re.search(task["update_subdir"], share_file["file_name"]):
+ # 不在更新目录内,且不符合更新目录规则,跳过处理
+ continue
+
+ # 先检查目标目录中是否已存在这个子目录
+ dir_exists = False
+ for dir_file in dir_file_list:
+ if dir_file["dir"] and dir_file["file_name"] == share_file["file_name"]:
+ dir_exists = True
+ break
+
+ # 如果目标中已经存在此子目录,则直接检查子目录的内容更新,不要重复转存
+ if dir_exists:
+ # 子目录存在,直接递归处理其中的文件,不在主目录的处理中再转存一次
+ # print(f"检查子目录: {savepath}/{share_file['file_name']} (已存在)")
+
+ # 创建一个子任务对象,专门用于子目录处理
+ subdir_task = task.copy()
+ if (not subdir_task.get("pattern") or
+ subdir_task.get("use_sequence_naming") or
+ subdir_task.get("use_episode_naming")):
+ subdir_task["pattern"] = ".*"
+ subdir_task["replace"] = ""
+ # 取消顺序命名和剧集命名模式,强制使用正则模式
+ subdir_task["use_sequence_naming"] = False
+ subdir_task["use_episode_naming"] = False
+
+ # 更新子目录的parent_dir_info,跟踪目录路径和更新状态
+ current_parent_info = parent_dir_info.copy() if parent_dir_info else {
+ "in_update_dir": False,
+ "update_dir_pattern": task.get("update_subdir", ""),
+ "dir_path": []
+ }
+
+ # 如果当前文件夹符合更新目录规则,标记为在更新目录内
+ if re.search(task["update_subdir"], share_file["file_name"]):
+ current_parent_info["in_update_dir"] = True
+
+ # 添加当前目录到路径
+ current_parent_info["dir_path"] = current_parent_info["dir_path"].copy() if "dir_path" in current_parent_info else []
+ current_parent_info["dir_path"].append(share_file["file_name"])
+
+ # 递归处理子目录但不在need_save_list中添加目录本身
+ subdir_tree = self.dir_check_and_save(
+ subdir_task,
+ pwd_id,
+ stoken,
+ share_file["fid"],
+ f"{subdir_path}/{share_file['file_name']}",
+ current_parent_info
+ )
+
+ # 如果子目录有新内容,合并到主树中
+ if subdir_tree and subdir_tree.size() > 1:
+ has_files = False
+ for node in subdir_tree.all_nodes_itr():
+ if node.data and not node.data.get("is_dir", False):
+ has_files = True
+ break
+
+ if has_files:
+ # 添加目录到树中但不添加到保存列表
+ if not tree.contains(share_file["fid"]):
+ tree.create_node(
+ "📁" + share_file["file_name"],
+ share_file["fid"],
+ parent=pdir_fid,
+ data={
+ "is_dir": share_file["dir"],
+ },
+ )
+ # 合并子目录树
+ tree.merge(share_file["fid"], subdir_tree, deep=False)
+
+ # 跳过后续处理,不对已存在的子目录再做转存处理
+ continue
+
+ # 目录不存在,继续正常流程
pattern, replace = task["update_subdir"], ""
else:
# 检查是否是剧集命名模式
@@ -1592,24 +1726,28 @@ class Quark:
# 判断目标目录文件是否存在
file_exists = False
for dir_file in dir_file_list:
- if dir_file["dir"]:
- continue
-
- if task.get("ignore_extension", False):
- # 忽略后缀:只比较文件名部分,不管扩展名
- original_name_base = os.path.splitext(share_file["file_name"])[0]
- renamed_name_base = os.path.splitext(save_name)[0]
- existing_name_base = os.path.splitext(dir_file["file_name"])[0]
-
- # 如果原文件名或重命名后文件名与目标目录中文件名相同(忽略后缀),则视为已存在
- if existing_name_base == original_name_base or existing_name_base == renamed_name_base:
- file_exists = True
- break
- else:
- # 不忽略后缀:文件名和扩展名都要一致才视为同一个文件
- if dir_file["file_name"] == share_file["file_name"] or dir_file["file_name"] == save_name:
+ if dir_file["dir"] and share_file["dir"]:
+ # 如果都是目录,只要名称相同就视为已存在
+ if dir_file["file_name"] == share_file["file_name"]:
file_exists = True
break
+ elif not dir_file["dir"] and not share_file["dir"]:
+ # 如果都是文件
+ if task.get("ignore_extension", False):
+ # 忽略后缀:只比较文件名部分,不管扩展名
+ original_name_base = os.path.splitext(share_file["file_name"])[0]
+ renamed_name_base = os.path.splitext(save_name)[0]
+ existing_name_base = os.path.splitext(dir_file["file_name"])[0]
+
+ # 如果原文件名或重命名后文件名与目标目录中文件名相同(忽略后缀),则视为已存在
+ if existing_name_base == original_name_base or existing_name_base == renamed_name_base:
+ file_exists = True
+ break
+ else:
+ # 不忽略后缀:文件名和扩展名都要一致才视为同一个文件
+ if dir_file["file_name"] == share_file["file_name"] or dir_file["file_name"] == save_name:
+ file_exists = True
+ break
if not file_exists:
# 不打印保存信息
@@ -1617,54 +1755,75 @@ class Quark:
share_file["original_name"] = share_file["file_name"] # 保存原文件名,用于排序
# 文件夹需要特殊处理,标记为has_updates=False,等待后续检查
+ # 只有在文件夹匹配update_subdir时才设置
if share_file["dir"]:
share_file["has_updates"] = False
+ # 将文件添加到保存列表
need_save_list.append(share_file)
elif share_file["dir"]:
# 文件夹已存在,根据是否递归处理子目录决定操作
# 如果开启了子目录递归,处理子目录结构
if task.get("update_subdir", False):
+ # print(f"检查子目录: {savepath}/{share_file['file_name']}")
+
+ # 创建一个子任务对象,保留原任务的属性,但专门用于子目录处理
+ subdir_task = task.copy()
+ # 确保子目录也可以使用忽略后缀功能
+
+ # 如果原任务没有设置pattern,确保有基本的pattern
+ if not subdir_task.get("pattern"):
+ subdir_task["pattern"] = ".*" # 在子目录中匹配所有文件
+ subdir_task["replace"] = ""
+
+ # 更新子目录的parent_dir_info,跟踪目录路径和更新状态
+ current_parent_info = parent_dir_info.copy() if parent_dir_info else {
+ "in_update_dir": False,
+ "update_dir_pattern": task.get("update_subdir", ""),
+ "dir_path": []
+ }
+
+ # 如果当前文件夹符合更新目录规则,标记为在更新目录内
if re.search(task["update_subdir"], share_file["file_name"]):
- print(f"检查子文件夹: {savepath}/{share_file['file_name']}")
+ current_parent_info["in_update_dir"] = True
- # 创建一个子任务对象,保留原任务的属性,但专门用于子目录处理
- subdir_task = task.copy()
- # 确保子目录也可以使用忽略后缀功能
+ # 添加当前目录到路径
+ current_parent_info["dir_path"] = current_parent_info["dir_path"].copy() if "dir_path" in current_parent_info else []
+ current_parent_info["dir_path"].append(share_file["file_name"])
+
+ # 递归处理子目录
+ subdir_tree = self.dir_check_and_save(
+ subdir_task,
+ pwd_id,
+ stoken,
+ share_file["fid"],
+ f"{subdir_path}/{share_file['file_name']}",
+ current_parent_info
+ )
+
+ # 只有当子目录树有实际内容(大于1表示不只有根节点)时才处理
+ if subdir_tree and subdir_tree.size() > 1:
+ # 检查子目录树是否只包含文件夹而没有文件
+ has_files = False
+ for node in subdir_tree.all_nodes_itr():
+ # 检查是否有非目录节点(即文件节点)
+ if node.data and not node.data.get("is_dir", False):
+ has_files = True
+ break
- # 如果原任务没有设置pattern,确保有基本的pattern
- if not subdir_task.get("pattern"):
- subdir_task["pattern"] = ".*"
- subdir_task["replace"] = ""
-
- subdir_tree = self.dir_check_and_save(
- subdir_task,
- pwd_id,
- stoken,
- share_file["fid"],
- f"{subdir_path}/{share_file['file_name']}",
- )
- # 只有当子目录树有实际内容(大于1表示不只有根节点)时才处理
- if subdir_tree.size(1) > 0:
- # 检查子目录树是否只包含文件夹而没有文件
- has_files = False
- for node in subdir_tree.all_nodes_itr():
- # 检查是否有非目录节点(即文件节点)
- if node.data and not node.data.get("is_dir", False):
- has_files = True
- break
+ # 只有当子目录包含文件时才将其合并到主树中
+ if has_files:
+ # 获取保存路径的最后一部分目录名
+ save_path_basename = os.path.basename(task.get("savepath", "").rstrip("/"))
- # 只有当子目录包含文件时才将其合并到主树中
- if has_files:
- # 获取保存路径的最后一部分目录名
- save_path_basename = os.path.basename(task.get("savepath", "").rstrip("/"))
-
- # 跳过与保存路径同名的目录
- if share_file["file_name"] == save_path_basename:
- continue
-
- # 合并子目录树
+ # 跳过与保存路径同名的目录
+ if share_file["file_name"] == save_path_basename:
+ continue
+
+ # 添加目录到树中
+ # 检查节点是否已存在于树中,避免重复添加
+ if not tree.contains(share_file["fid"]):
tree.create_node(
"📁" + share_file["file_name"],
share_file["fid"],
@@ -1673,14 +1832,38 @@ class Quark:
"is_dir": share_file["dir"],
},
)
- tree.merge(share_file["fid"], subdir_tree, deep=False)
+ # 合并子目录树
+ tree.merge(share_file["fid"], subdir_tree, deep=False)
+
+ # 检查文件夹是否已添加到need_save_list
+ folder_in_list = False
+ for item in need_save_list:
+ if item.get("fid") == share_file["fid"]:
+ # 文件夹已在列表中,设置为有更新
+ item["has_updates"] = True
+ folder_in_list = True
+ break
+
+ # 如果文件夹未添加到need_save_list且有文件更新,则添加
+ if not folder_in_list:
+ # 检查目标目录中是否已存在同名子目录
+ dir_exists = False
+ for dir_file in dir_file_list:
+ if dir_file["dir"] and dir_file["file_name"] == share_file["file_name"]:
+ dir_exists = True
+ break
- # 标记此文件夹有更新
- if share_file.get("has_updates") is False:
- for item in need_save_list:
- if item.get("fid") == share_file["fid"]:
- item["has_updates"] = True
- break
+ # 只有当目录不存在于目标位置时,才将其添加到转存列表
+ if not dir_exists:
+ # 将父文件夹添加到保存列表,确保子目录的变化能被处理
+ share_file["save_name"] = share_file["file_name"]
+ share_file["original_name"] = share_file["file_name"]
+ share_file["has_updates"] = True # 标记为有更新
+ need_save_list.append(share_file)
+ print(f"发现子目录 {share_file['file_name']} 有更新,将包含到转存列表")
+ else:
+ # 如果子目录已存在,只显示提示消息,不添加到转存列表
+ print(f"发现子目录 {share_file['file_name']} 有更新,将更新到已存在的文件夹中")
except Exception as e:
print(f"⚠️ 正则表达式错误: {str(e)}, pattern: {pattern}")
# 使用安全的默认值
@@ -1766,16 +1949,18 @@ class Quark:
# 保存到树中
saved_files.append(f"{icon}{display_name}")
- tree.create_node(
- f"{icon}{display_name}",
- item["fid"],
- parent=pdir_fid,
- data={
- "fid": f"{query_task_return['data']['save_as']['save_as_top_fids'][index]}",
- "path": f"{savepath}/{item['save_name']}",
- "is_dir": item["dir"],
- },
- )
+ # 检查节点是否已存在于树中,避免重复添加
+ if not tree.contains(item["fid"]):
+ tree.create_node(
+ f"{icon}{display_name}",
+ item["fid"],
+ parent=pdir_fid,
+ data={
+ "fid": f"{query_task_return['data']['save_as']['save_as_top_fids'][index]}",
+ "path": f"{savepath}/{item['save_name']}",
+ "is_dir": item["dir"],
+ },
+ )
# 移除通知生成,由do_save函数统一处理
# 顺序命名模式和剧集命名模式都不在此处生成通知
@@ -2601,6 +2786,9 @@ def do_save(account, tasklist=[]):
print(f"转存账号: {account.nickname}")
# 获取全部保存目录fid
account.update_savepath_fid(tasklist)
+
+ # 创建已发送通知跟踪集合,避免重复显示通知
+ sent_notices = set()
def is_time(task):
return (
@@ -2660,6 +2848,71 @@ def do_save(account, tasklist=[]):
# 执行重命名任务,但收集日志而不是立即打印
is_rename, rename_logs = account.do_rename_task(task)
+ # 处理子目录重命名 - 如果配置了更新目录且使用正则命名模式
+ if task.get("update_subdir") and task.get("pattern") is not None:
+ # 获取保存路径
+ savepath = re.sub(r"/{2,}", "/", f"/{task['savepath']}")
+ if account.savepath_fid.get(savepath):
+ # 递归处理所有符合条件的子目录
+ def process_subdirs(current_path, relative_path=""):
+ # 获取当前目录的文件列表
+ current_fid = account.savepath_fid.get(current_path)
+ if not current_fid:
+ # 尝试获取目录的fid
+ path_fids = account.get_fids([current_path])
+ if path_fids:
+ current_fid = path_fids[0]["fid"]
+ account.savepath_fid[current_path] = current_fid
+ else:
+ print(f"无法获取目录fid: {current_path}")
+ return
+
+ current_dir_files = account.ls_dir(current_fid)
+
+ # 处理当前目录
+ if relative_path:
+ # 对当前目录执行重命名操作
+ subtask = task.copy()
+ if not subtask.get("pattern"):
+ subtask["pattern"] = ".*"
+ subtask["replace"] = ""
+
+ subdir_is_rename, subdir_rename_logs = account.do_rename_task(subtask, relative_path)
+
+ # 合并日志
+ if subdir_is_rename and subdir_rename_logs:
+ clean_logs = []
+ for log in subdir_rename_logs:
+ if "失败" not in log:
+ clean_logs.append(log)
+
+ rename_logs.extend(clean_logs)
+ nonlocal is_rename
+ is_rename = is_rename or subdir_is_rename
+
+ # 找出符合更新目录规则的子目录
+ subdirs = []
+ for file in current_dir_files:
+ if file["dir"]:
+ # 如果是根目录,检查是否符合更新目录的规则
+ if not relative_path and re.search(task["update_subdir"], file["file_name"]):
+ subdirs.append(file)
+ # 如果已经在某个更新目录内,则所有子目录都需要处理
+ elif relative_path:
+ subdirs.append(file)
+
+ # 对每个子目录递归调用
+ for subdir in subdirs:
+ # 构建子目录完整路径
+ subdir_full_path = f"{current_path}/{subdir['file_name']}"
+ subdir_relative_path = f"{relative_path}/{subdir['file_name']}"
+
+ # 递归处理子目录
+ process_subdirs(subdir_full_path, subdir_relative_path)
+
+ # 从根目录开始递归处理
+ process_subdirs(savepath)
+
# 简化日志处理 - 只保留成功的重命名消息
if rename_logs:
success_logs = []
@@ -2730,6 +2983,29 @@ def do_save(account, tasklist=[]):
# 创建一个映射列表,包含需要显示的文件名
display_files = []
+ # 检查是否有更新目录,并获取目录下的文件
+ update_subdir = task.get("update_subdir")
+
+ # 如果有设置更新目录,查找对应目录下的文件
+ if update_subdir:
+ # 检查文件树中是否有更新目录的节点
+ update_dir_nodes = []
+ update_subdir_files = []
+
+ # 遍历所有节点,查找对应的目录节点
+ for node in is_new_tree.all_nodes_itr():
+ if node.data.get("is_dir", False) and node.tag.lstrip("📁") == update_subdir:
+ update_dir_nodes.append(node)
+
+ # 如果找到更新目录节点,收集其子节点
+ if update_dir_nodes:
+ for dir_node in update_dir_nodes:
+ # 获取目录节点下的所有文件子节点
+ for node in is_new_tree.all_nodes_itr():
+ if (not node.data.get("is_dir", False) and
+ node.predecessor == dir_node.identifier):
+ update_subdir_files.append(node)
+
# 按文件名排序
if is_special_sequence:
# 对于顺序命名模式,使用重命名日志来获取新增的文件
@@ -2832,8 +3108,71 @@ def do_save(account, tasklist=[]):
# 获取保存路径的最后一部分目录名(如"/测试/魔法"取"魔法")
save_path_basename = os.path.basename(task.get("savepath", "").rstrip("/"))
- # 首先添加所有目录节点,过滤掉与保存路径同名的目录,确保目录结构完整
+ # 创建一个保存目录结构的字典
+ dir_structure = {"root": []}
+
+ # 首先处理所有目录节点,构建目录结构
dir_nodes = [node for node in all_nodes if node.data and node.data.get("is_dir", False) and node.identifier != "root"]
+
+ # 如果有设置更新目录但在树中没找到,尝试查找目录
+ update_dir_node = None
+ if update_subdir:
+ for node in dir_nodes:
+ name = node.tag.lstrip("📁")
+ if name == update_subdir:
+ update_dir_node = node
+ break
+
+ # 如果树中没有找到更新目录节点,但设置了更新目录,尝试单独处理
+ if not update_dir_node:
+ savepath = re.sub(r"/{2,}", "/", f"/{task['savepath']}")
+ update_subdir_path = f"{savepath}/{update_subdir}"
+
+ # 检查更新目录是否存在于账户的目录缓存中
+ if update_subdir_path in account.savepath_fid:
+ # 获取此目录下的文件,单独处理显示
+ try:
+ update_subdir_fid = account.savepath_fid[update_subdir_path]
+ update_subdir_files = account.ls_dir(update_subdir_fid)
+
+ # 如果目录存在但没有在文件树中,这可能是首次执行的情况
+ # 添加一个虚拟目录节点到树中
+ class VirtualDirNode:
+ def __init__(self, name, dir_id):
+ self.tag = f"📁{name}"
+ self.identifier = dir_id
+ self.data = {"is_dir": True}
+
+ # 创建虚拟目录节点
+ update_dir_node = VirtualDirNode(update_subdir, f"virtual_{update_subdir}")
+ dir_nodes.append(update_dir_node)
+
+ # 为每个文件创建虚拟节点
+ virtual_file_nodes = []
+ for file in update_subdir_files:
+ if not file.get("dir", False):
+ class VirtualFileNode:
+ def __init__(self, name, file_id, dir_id):
+ self.tag = name
+ self.identifier = file_id
+ self.predecessor = dir_id
+ self.data = {"is_dir": False}
+
+ # 创建虚拟文件节点,关联到虚拟目录
+ virtual_node = VirtualFileNode(
+ file["file_name"],
+ f"virtual_file_{file['fid']}",
+ update_dir_node.identifier
+ )
+ virtual_file_nodes.append(virtual_node)
+
+ # 将虚拟文件节点添加到all_nodes
+ if virtual_file_nodes:
+ all_nodes.extend(virtual_file_nodes)
+ except Exception as e:
+ print(f"获取更新目录信息时出错: {str(e)}")
+
+ # 恢复目录结构构建
for node in sorted(dir_nodes, key=lambda node: node.tag):
# 获取原始文件名(去除已有图标)
orig_filename = node.tag.lstrip("📁")
@@ -2847,58 +3186,520 @@ def do_save(account, tasklist=[]):
if orig_filename == save_path_basename:
continue
- # 添加适当的图标
- display_files.append((f"📁{orig_filename}", node))
+ # 获取父节点ID
+ parent_id = node.predecessor if hasattr(node, 'predecessor') and node.predecessor != "root" else "root"
+
+ # 确保父节点键存在于字典中
+ if parent_id not in dir_structure:
+ dir_structure[parent_id] = []
+
+ # 添加目录节点到结构中
+ dir_structure[parent_id].append({
+ "id": node.identifier,
+ "name": f"📁{orig_filename}",
+ "is_dir": True
+ })
+
+ # 为该目录创建一个空列表,用于存放其子项
+ dir_structure[node.identifier] = []
- # 然后添加所有文件节点
- for node in sorted(file_nodes, key=lambda node: node.tag):
+ # 然后处理所有文件节点和虚拟文件节点
+ all_file_nodes = [node for node in all_nodes if hasattr(node, 'data') and not node.data.get("is_dir", False)]
+
+ for node in sorted(all_file_nodes, key=lambda node: node.tag):
# 获取原始文件名(去除已有图标)
orig_filename = node.tag.lstrip("🎞️")
# 添加适当的图标
- icon = get_file_icon(orig_filename, is_dir=node.data.get("is_dir", False))
- display_files.append((f"{icon}{orig_filename}", node))
+ icon = get_file_icon(orig_filename, is_dir=False)
+
+ # 获取父节点ID
+ parent_id = node.predecessor if hasattr(node, 'predecessor') and node.predecessor != "root" else "root"
+
+ # 确保父节点键存在于字典中
+ if parent_id not in dir_structure:
+ dir_structure[parent_id] = []
+
+ # 添加文件节点到结构中
+ dir_structure[parent_id].append({
+ "id": node.identifier,
+ "name": f"{icon}{orig_filename}",
+ "is_dir": False
+ })
# 添加成功通知,带文件数量图标
- add_notify(f"✅《{task['taskname']}》 添加追更:")
- add_notify(f"/{task['savepath']}")
+ # 这个通知会在下面的新逻辑中添加,这里注释掉
+ # add_notify(f"✅《{task['taskname']}》添加追更:")
+ # add_notify(f"/{task['savepath']}")
- # 在显示树状结构之前,定义一个本地排序函数
- def local_sort_key(item):
- file_name = item[0][item[0].find("🎞️")+1:] if "🎞️" in item[0] else item[0]
- # 尝试提取日期格式(优先YYYY-MM-DD格式)
- date_match = re.search(r'(\d{4})[-./](\d{1,2})[-./](\d{1,2})', file_name)
- if date_match:
- year = int(date_match.group(1))
- month = int(date_match.group(2))
- day = int(date_match.group(3))
- return year * 10000 + month * 100 + day
-
- # 尝试提取紧凑日期格式(YYYYMMDD)
- compact_date_match = re.search(r'(\d{4})(\d{2})(\d{2})', file_name)
- if compact_date_match:
- year = int(compact_date_match.group(1))
- month = int(compact_date_match.group(2))
- day = int(compact_date_match.group(3))
- return year * 10000 + month * 100 + day
-
- # 尝试提取任何数字
- number_match = re.search(r'(\d+)', file_name)
- if number_match:
- return int(number_match.group(1))
-
- # 默认使用原文件名
- return float('inf')
+ # 移除调试信息
+ # 获取更新目录名称
+ update_subdir = task.get("update_subdir")
- # 对显示文件进行排序,使用本地排序函数
- display_files = sorted(display_files, key=local_sort_key)
+ # 创建一个列表来存储所有匹配的更新目录节点及其文件
+ update_dir_nodes = []
+ files_by_dir = {}
+ # 默认根目录
+ files_by_dir["root"] = []
+
+ # 查找所有匹配的更新目录节点
+ dir_nodes = [node for node in is_new_tree.all_nodes_itr() if node.data.get("is_dir") == True and node.identifier != "root"]
+ if update_subdir:
+ for node in dir_nodes:
+ dir_name = node.tag.lstrip("📁")
+ # 使用正则表达式匹配目录名
+ if re.search(update_subdir, dir_name):
+ update_dir_nodes.append(node)
+ # 为每个匹配的目录创建空文件列表
+ files_by_dir[node.identifier] = []
+
+ # 从文件的路径信息中提取父目录
+ for node in file_nodes:
+ if hasattr(node, 'data') and node.data and 'path' in node.data:
+ path = node.data['path']
+ path_parts = path.strip('/').split('/')
+
+ # 确定文件应该属于哪个目录
+ if len(path_parts) > 1 and update_subdir:
+ # 获取保存路径
+ save_path = task.get("savepath", "").rstrip("/")
+ save_path_parts = save_path.split("/")
+ save_path_basename = save_path_parts[-1] if save_path_parts else ""
+
+ # 去除路径中的保存路径部分,只保留相对路径
+ # 首先查找保存路径在完整路径中的位置
+ relative_path_start = 0
+ for i, part in enumerate(path_parts):
+ if i < len(path_parts) - 1 and part == save_path_basename:
+ relative_path_start = i + 1
+ break
+
+ # 提取相对路径部分,不含文件名
+ relative_path_parts = path_parts[relative_path_start:-1]
+
+ # 如果没有相对路径部分(直接在根目录下的文件)
+ if not relative_path_parts:
+ files_by_dir["root"].append(node)
+ continue
+
+ # 检查第一级子目录是否是更新目录之一
+ first_level_dir = relative_path_parts[0]
+ parent_found = False
+
+ for dir_node in update_dir_nodes:
+ dir_name = dir_node.tag.lstrip("📁")
+ # 只看第一级目录是否匹配更新目录规则
+ if dir_name == first_level_dir:
+ # 文件属于此更新目录,直接添加到对应目录下
+ files_by_dir[dir_node.identifier].append(node)
+ parent_found = True
+
+ # 为了在树显示中定位该文件,设置完整路径信息
+ if len(relative_path_parts) > 1:
+ # 如果是多级嵌套目录,设置嵌套路径标记
+ node.nested_path = "/".join(relative_path_parts[1:])
+ break
+
+ if not parent_found:
+ # 尝试检查文件的直接父目录
+ parent_dir_name = path_parts[-2]
+ for dir_node in update_dir_nodes:
+ dir_name = dir_node.tag.lstrip("📁")
+ if parent_dir_name == dir_name:
+ files_by_dir[dir_node.identifier].append(node)
+ parent_found = True
+ break
+
+ if not parent_found:
+ # 如果没有找到匹配的父目录,将文件添加到根目录
+ files_by_dir["root"].append(node)
+ else:
+ # 文件属于根目录
+ files_by_dir["root"].append(node)
+ else:
+ # 没有路径信息,默认添加到根目录
+ files_by_dir["root"].append(node)
+
+ # 排序函数,使用文件节点作为输入
+ def sort_nodes(nodes):
+ return sorted(nodes, key=lambda node: sort_file_by_name(node.tag.lstrip("🎞️")))
+
+ # 初始化最终显示文件的字典
+ final_display_files = {
+ "root": [],
+ "subdirs": {}
+ }
+
+ # 创建集合来跟踪当次新增的文件和文件夹
+ current_added_files = set()
+ current_added_dirs = set()
+
+ # 跟踪子目录和根目录是否有新增文件
+ has_update_in_root = False
+ has_update_in_subdir = False
+
+ # 记录是否是首次执行
+ is_first_run = True
+ if task.get("last_run_time"):
+ is_first_run = False
+
+ # 先检查是否有新增的目录
+ for dir_node in dir_nodes:
+ dir_name = dir_node.tag.lstrip("📁")
+
+ # 检查是否是指定的更新目录
+ if update_subdir and re.search(update_subdir, dir_name):
+ current_added_dirs.add(dir_name)
+ has_update_in_subdir = True
+
+ # 检查根目录是否有新增文件
+ root_new_files = []
+ for node in files_by_dir["root"]:
+ file_name = node.tag.lstrip("🎞️")
+ # 判断是否为新增文件
+ is_new_file = False
+
+ # 1. 检查是否在当前转存的文件列表中
+ if hasattr(node, 'data') and 'created_at' in node.data:
+ current_time = int(time.time())
+ time_threshold = 600 # 10分钟 = 600秒
+ if current_time - node.data['created_at'] < time_threshold:
+ is_new_file = True
+
+ # 2. 节点本身是从当次转存的文件树中获取的
+ elif hasattr(is_new_tree, 'nodes') and node.identifier in is_new_tree.nodes:
+ is_new_file = True
+
+ # 3. 首次运行任务时,视为所有文件都是新增的
+ elif is_first_run:
+ is_new_file = True
+
+ if is_new_file:
+ root_new_files.append(node)
+ current_added_files.add(file_name)
+ has_update_in_root = True
+
+ # 记录到最终显示的文件列表中
+ final_display_files["root"].append(node)
+
+ # 创建多目录下的更新文件字典
+ subdir_new_files = {}
+
+ # 首次运行时,记录哪些子目录是新添加的
+ new_added_dirs = set()
+
+ # 对每个已识别的更新目录,检查是否有新文件
+ for dir_node in update_dir_nodes:
+ dir_name = dir_node.tag.lstrip("📁")
+ dir_id = dir_node.identifier
+ dir_files = files_by_dir.get(dir_id, [])
+
+ # 初始化该目录的新文件列表
+ subdir_new_files[dir_id] = []
+
+ # 首次运行时,记录所有符合更新目录规则的目录
+ if is_first_run:
+ new_added_dirs.add(dir_name)
+ has_update_in_subdir = True
+
+ # 检查该目录下的文件是否是新文件
+ for file_node in dir_files:
+ file_name = file_node.tag.lstrip("🎞️")
+ # 判断是否为新增文件
+ is_new_file = False
+
+ if hasattr(file_node, 'data') and 'created_at' in file_node.data:
+ current_time = int(time.time())
+ time_threshold = 600 # 10分钟 = 600秒
+ if current_time - file_node.data['created_at'] < time_threshold:
+ is_new_file = True
+ elif hasattr(is_new_tree, 'nodes') and file_node.identifier in is_new_tree.nodes:
+ is_new_file = True
+ # 首次运行任务时,视为所有文件都是新增的
+ elif is_first_run:
+ is_new_file = True
+
+ if is_new_file:
+ subdir_new_files[dir_id].append(file_node)
+ current_added_files.add(file_name)
+ has_update_in_subdir = True
+
+ # 记录到最终显示的文件列表中
+ if dir_id not in final_display_files["subdirs"]:
+ final_display_files["subdirs"][dir_id] = []
+ final_display_files["subdirs"][dir_id].append(file_node)
+
+ # 如果已识别的目录中没有新增文件,尝试进一步查找符合update_subdir规则的目录
+ if update_subdir and not has_update_in_subdir:
+ savepath = re.sub(r"/{2,}", "/", f"/{task['savepath']}")
+
+ # 获取保存路径下的所有目录
+ try:
+ all_dirs = account.ls_dir(account.savepath_fid[savepath])
+
+ # 筛选出符合更新规则的目录
+ for dir_item in all_dirs:
+ if dir_item.get("dir", False):
+ dir_name = dir_item["file_name"]
+ if re.search(update_subdir, dir_name):
+ # 检查该目录是否已经处理过
+ if not any(node.tag.lstrip("📁") == dir_name for node in update_dir_nodes):
+ # 获取目录的文件列表
+ update_subdir_path = f"{savepath}/{dir_name}"
+ if update_subdir_path in account.savepath_fid:
+ try:
+ update_subdir_fid = account.savepath_fid[update_subdir_path]
+ update_subdir_files = account.ls_dir(update_subdir_fid)
+
+ # 创建虚拟目录节点
+ class VirtualDirNode:
+ def __init__(self, name, dir_id):
+ self.tag = f"📁{name}"
+ self.identifier = dir_id
+ self.data = {"is_dir": True}
+
+ # 创建虚拟目录节点
+ virtual_dir_node = VirtualDirNode(dir_name, f"virtual_{dir_name}")
+ update_dir_nodes.append(virtual_dir_node)
+
+ # 初始化新文件列表
+ subdir_new_files[virtual_dir_node.identifier] = []
+
+ # 为每个文件创建虚拟节点
+ for file in update_subdir_files:
+ if not file.get("dir", False):
+ class VirtualFileNode:
+ def __init__(self, name, file_id, dir_id):
+ self.tag = name
+ self.identifier = file_id
+ self.predecessor = dir_id
+ self.data = {"is_dir": False}
+
+ # 创建虚拟文件节点,关联到虚拟目录
+ virtual_node = VirtualFileNode(
+ file["file_name"],
+ f"virtual_file_{file['fid']}",
+ virtual_dir_node.identifier
+ )
+
+ # 首次运行时,将所有文件视为新文件
+ if is_first_run:
+ subdir_new_files[virtual_dir_node.identifier].append(virtual_node)
+ has_update_in_subdir = True
+ except Exception as e:
+ print(f"获取目录 {dir_name} 文件列表时出错: {str(e)}")
+ except Exception as e:
+ print(f"获取目录列表时出错: {str(e)}")
+
+ # 对所有目录中的文件进行排序
+ for dir_id in subdir_new_files:
+ if subdir_new_files[dir_id]:
+ subdir_new_files[dir_id] = sort_nodes(subdir_new_files[dir_id])
+
+ # 记录本次执行时间
+ task["last_run_time"] = int(time.time())
+
+ # 显示文件树规则:
+ # 1. 只有根目录有更新:只显示根目录
+ # 2. 只有子目录有更新:只显示子目录
+ # 3. 根目录和子目录都有更新:显示两者
+ # 4. 都没有更新:不显示任何内容
+
+ # 如果没有任何更新,不显示任何内容
+ if not has_update_in_root and not has_update_in_subdir:
+ # 不添加任何通知
+ pass
+ else:
+ # 添加基本通知
+ add_notify(f"✅《{task['taskname']}》添加追更:")
+ add_notify(f"/{task['savepath']}")
+
+ # 构建完整的目录树结构(支持多层级嵌套)
+ def build_directory_tree():
+ # 创建目录树结构
+ dir_tree = {"root": {"dirs": {}, "files": []}}
+
+ # 获取保存路径的最后一部分目录名(用于过滤)
+ save_path = task.get("savepath", "").rstrip("/")
+ save_path_parts = save_path.split("/")
+ save_path_basename = save_path_parts[-1] if save_path_parts else ""
+
+ # 处理所有目录节点
+ for dir_node in update_dir_nodes:
+ dir_id = dir_node.identifier
+ dir_name = dir_node.tag.lstrip("📁")
+
+ # 跳过与保存路径相同的目录
+ if dir_name == save_path_basename or dir_name == save_path:
+ continue
+
+ # 如果目录名包含完整路径,检查是否与保存路径相关
+ if "/" in dir_name:
+ # 检查是否以路径开头
+ if dir_name.startswith("/"):
+ continue
+
+ # 检查是否是保存路径或其子路径
+ path_parts = dir_name.split("/")
+ # 跳过包含保存路径的完整路径
+ if any(part == save_path_basename for part in path_parts):
+ continue
+
+ # 分割路径,处理可能的多级目录
+ path_parts = dir_name.split("/")
+
+ # 从根节点开始构建路径
+ current = dir_tree["root"]
+
+ for i, part in enumerate(path_parts):
+ # 跳过空部分和保存路径部分
+ if not part or part == save_path_basename:
+ continue
+
+ if part not in current["dirs"]:
+ # 创建新的目录节点
+ current["dirs"][part] = {
+ "dirs": {},
+ "files": [],
+ "dir_id": dir_id if i == len(path_parts) - 1 else None
+ }
+ current = current["dirs"][part]
+
+ # 添加该目录的文件
+ if dir_id in subdir_new_files:
+ # 处理嵌套目录下的文件
+ nested_files = []
+ non_nested_files = []
+
+ for file_node in subdir_new_files[dir_id]:
+ if hasattr(file_node, 'nested_path') and file_node.nested_path:
+ # 处理嵌套文件
+ nested_path_parts = file_node.nested_path.split('/')
+
+ # 创建或获取子目录结构
+ sub_current = current
+ for i, part in enumerate(nested_path_parts):
+ if part not in sub_current["dirs"]:
+ # 创建新的子目录结构
+ sub_current["dirs"][part] = {
+ "dirs": {},
+ "files": [],
+ "dir_id": None # 虚拟目录暂时没有ID
+ }
+ sub_current = sub_current["dirs"][part]
+
+ # 添加文件到嵌套目录
+ sub_current["files"].append(file_node)
+ else:
+ # 不是嵌套的文件,直接添加到当前目录
+ non_nested_files.append(file_node)
+
+ # 设置当前目录的非嵌套文件
+ current["files"] = non_nested_files
+
+ # 添加根目录文件
+ if has_update_in_root and final_display_files["root"]:
+ dir_tree["root"]["files"] = final_display_files["root"]
+
+ return dir_tree
+
+ # 递归显示目录树
+ def display_tree(node, prefix="", is_last=True, depth=0):
+ # 获取目录和文件列表
+ dirs = sorted(node["dirs"].items())
+ files = node.get("files", [])
+
+ # 根目录文件特殊处理(如果路径以"/"开头,检查是否和当前保存路径相关)
+ save_path = task.get("savepath", "").rstrip("/")
+ save_path_parts = save_path.split("/")
+ save_path_basename = save_path_parts[-1] if save_path else ""
+
+ # 计算总项数(目录+文件)
+ total_items = len(dirs) + len(files)
+ current_item = 0
+
+ # 处理目录
+ for i, (dir_name, dir_data) in enumerate(dirs):
+ current_item += 1
+ is_dir_last = current_item == total_items
+
+ # 过滤条件:
+ # 1. 目录名不为空
+ # 2. 不是保存路径本身
+ # 3. 不是以"/"开头的完整路径
+ # 4. 不是保存路径的基本名称
+ if (dir_name and
+ dir_name != save_path and
+ not dir_name.startswith("/") and
+ dir_name != save_path_basename):
+
+ dir_prefix = prefix + ("└── " if is_dir_last else "├── ")
+ add_notify(f"{dir_prefix}📁{dir_name}")
+
+ # 计算子项的前缀,保持树形结构清晰
+ # 第一个缩进标记使用点号,后续使用空格
+ if prefix == "":
+ # 第一层缩进使用点号开头
+ new_prefix = "· " if is_dir_last else "│ "
+ else:
+ # 后续层级开头保持前缀不变,尾部添加新的缩进标记
+ if is_dir_last:
+ new_prefix = prefix + " " # 最后一项,空格缩进
+ else:
+ new_prefix = prefix + "│ " # 非最后一项,使用竖线
+
+ # 递归显示子目录
+ display_tree(dir_data, new_prefix, is_dir_last, depth + 1)
+
+ # 处理文件
+ sorted_files = sort_nodes(files) if files else []
+ for j, file_node in enumerate(sorted_files):
+ current_item += 1
+ is_file_last = current_item == total_items
+
+ # 显示文件
+ file_prefix = prefix + ("└── " if is_file_last else "├── ")
+ file_name = file_node.tag.lstrip("🎞️")
+ icon = get_file_icon(file_name, is_dir=False)
+ add_notify(f"{file_prefix}{icon}{file_name}")
+
+ # 构建并显示目录树
+ if has_update_in_root or has_update_in_subdir:
+ directory_tree = build_directory_tree()
+ display_tree(directory_tree["root"])
+ add_notify("")
+
+ # 处理重命名日志,避免显示不必要的路径信息
+ if rename_logs:
+ # 对重命名日志进行排序,确保按照新文件名的顺序显示
+ sorted_rename_logs = []
+ for log in rename_logs:
+ # 提取新文件名(格式:重命名: 旧名 → 新名)
+ match = re.search(r'→\s+(\d+\.\w+)', log)
+ if match:
+ new_name = match.group(1)
+ # 提取序号
+ seq_match = re.match(r'(\d+)', new_name)
+ seq_num = int(seq_match.group(1)) if seq_match else 999
+ sorted_rename_logs.append((seq_num, log))
+ else:
+ # 未找到序号的日志放在最后
+ sorted_rename_logs.append((999, log))
+
+ # 按序号排序
+ sorted_rename_logs.sort(key=lambda x: x[0])
+
+ # 打印排序后的日志
+ for _, log in sorted_rename_logs:
+ print(log)
+ else:
+ # 原始逻辑:直接打印所有日志
+ for log in rename_logs:
+ print(log)
- # 打印保存文件列表
- for idx, (display_name, _) in enumerate(display_files):
- prefix = "├── " if idx < len(display_files) - 1 else "└── "
- add_notify(f"{prefix}{display_name}")
add_notify("")
+
# 如果是剧集命名模式并且成功进行了重命名,单独显示排序好的文件列表
elif is_rename and task.get("use_episode_naming") and task.get("episode_naming"):
# 重新获取文件列表
@@ -2999,9 +3800,10 @@ def do_save(account, tasklist=[]):
if recent_files:
display_files.append(recent_files[0]['file_name'])
- # 添加成功通知
- add_notify(f"✅《{task['taskname']}》 添加追更:")
- add_notify(f"/{task['savepath']}")
+ # 添加成功通知 - 修复问题:确保在有文件时添加通知
+ if display_files:
+ add_notify(f"✅《{task['taskname']}》添加追更:")
+ add_notify(f"/{task['savepath']}")
# 创建episode_pattern函数用于排序
@@ -3042,7 +3844,10 @@ def do_save(account, tasklist=[]):
else:
icon = get_file_icon(file_name, is_dir=file_info.get("dir", False))
add_notify(f"{prefix}{icon}{file_name}")
- add_notify("")
+
+ # 确保只有在有文件时才添加空行
+ if display_files:
+ add_notify("")
# 添加正则命名模式的文件树显示逻辑
elif is_rename and not is_special_sequence and task.get("pattern") is not None:
# 重新获取文件列表
@@ -3074,7 +3879,7 @@ def do_save(account, tasklist=[]):
display_files = [file["file_name"] for file in file_nodes]
# 添加成功通知
- add_notify(f"✅《{task['taskname']}》 添加追更:")
+ add_notify(f"✅《{task['taskname']}》添加追更:")
add_notify(f"/{task['savepath']}")
# 打印文件列表
@@ -3086,32 +3891,8 @@ def do_save(account, tasklist=[]):
add_notify("")
# 现在打印重命名日志
- if rename_logs:
- # 对重命名日志进行排序,确保按照新文件名的顺序显示
- sorted_rename_logs = []
- for log in rename_logs:
- # 提取新文件名(格式:重命名: 旧名 → 新名)
- match = re.search(r'→\s+(\d+\.\w+)', log)
- if match:
- new_name = match.group(1)
- # 提取序号
- seq_match = re.match(r'(\d+)', new_name)
- seq_num = int(seq_match.group(1)) if seq_match else 999
- sorted_rename_logs.append((seq_num, log))
- else:
- # 未找到序号的日志放在最后
- sorted_rename_logs.append((999, log))
-
- # 按序号排序
- sorted_rename_logs.sort(key=lambda x: x[0])
-
- # 打印排序后的日志
- for _, log in sorted_rename_logs:
- print(log)
- else:
- # 原始逻辑:直接打印所有日志
- for log in rename_logs:
- print(log)
+ # 注意:这些日志可能已在前面的文件树展示中打印过,这里不再重复打印
+ # 因为已处理过的文件已显示在文件树中,这里不需要再次打印
# 补充任务的插件配置
def merge_dicts(a, b):
@@ -3146,7 +3927,7 @@ def do_save(account, tasklist=[]):
plugin.run(task, account=account, tree=is_new_tree) or task
)
elif is_new_tree is False: # 明确没有新文件
- print(f"任务完成:没有新的文件需要转存")
+ print(f"任务完成: 没有新的文件需要转存")
print()
print()