Compare commits

...

7 Commits

Author SHA1 Message Date
Y_C_Z
53cfbbf575
Merge 50d01bb4d8 into 8e27444f0e 2025-06-26 01:00:39 +08:00
Cp0204
8e27444f0e 新增重存模式处理子目录更新 #67
Some checks are pending
Docker Publish / build-and-push (push) Waiting to run
- 重存模式下,删除整个子目录并重新转存
- 新增提示信息,帮助用户选择合适的处理模式
2025-06-26 01:00:23 +08:00
Cp0204
59e024fd40 ♻️ 插件 alist_sync 更清晰的变量命名 2025-06-25 20:25:47 +08:00
Cp0204
ba9d3c7826 🔧 插件 alist_sync 加入优先级列表 2025-06-25 20:17:11 +08:00
Cp0204
44b3920055 改进魔法变量 {II} 排序加入文件修改时间因素
- 无可排序字符时则按修改时间排序
- 和目录已有文件重名时始终在其后
- 确保稳定排序和正确赋值
2025-06-25 20:16:13 +08:00
xiaoQQya
a939c233dc
改进魔法变量 {II} 使用自然排序
* fix: 修复 II 魔法变量排序时不是自然排序的问题

* chore: del empty line

---------

Co-authored-by: Cp0204 <Cp0204@qq.com>
2025-06-25 19:46:48 +08:00
Y_C_Z
50d01bb4d8
每次转存都清空目标文件夹 2025-04-16 12:13:33 +08:00
5 changed files with 60 additions and 9 deletions

View File

@ -358,10 +358,17 @@
</div>
</div>
</div>
<div class="form-group row" title="需匹配到各级嵌套目录名才会更新,否则子目录在第一次转存后不会更新。注意:原理是逐级索引,深层嵌套目录的场景下效率非常低,慎用 .*">
<div class="form-group row" title="需匹配到各级嵌套目录名才会更新,否则子目录在第一次转存后不会更新。注意:递归模式原理是逐级索引,深层嵌套目录的场景下效率非常低,慎用 .*">
<label class="col-sm-2 col-form-label">更新目录</label>
<div class="col-sm-10">
<input type="text" name="update_subdir[]" class="form-control" v-model="task.update_subdir" placeholder="可选,匹配需更新子目录(含各级嵌套目录)的正则表达式,多项以|分割,如 4k|1080p">
<div class="input-group">
<input type="text" name="update_subdir[]" class="form-control" v-model="task.update_subdir" placeholder="可选,匹配需更新子目录(含各级嵌套目录)的正则表达式,多项以|分割,如 4k|1080p">
<div class="input-group-append" title="重存模式:删除该目录下所有文件,重新转存,大资源包时推荐使用&#x0A;不勾选为递归模式:递归检查,逐级更新嵌套目录,效率低">
<div class="input-group-text">
<input type="checkbox" v-model="task.update_subdir_resave_mode">&nbsp;重存模式
</div>
</div>
</div>
</div>
</div>
<div class="form-group row">

View File

@ -2,6 +2,7 @@
"alist",
"alist_strm",
"alist_strm_gen",
"alist_sync",
"aria2",
"emby",
"plex"

View File

@ -26,7 +26,7 @@ class Alist_sync:
"enable": False, # 当前任务开关,
"save_path": "", # 需要同步目录,默认空时路径则会与夸克的保存路径一致,不开启完整路径模式时,默认根目录为保存驱动的根目录
"verify_path": "", # 验证目录主要用于影视库避免重复文件一般配合alist的别名功能及full_path使用用于多个网盘的源合并成一个目录
"full_path": False, # 完整路径模式
"full_path_mode": False, # 完整路径模式
# 完整路径模式开启后不再限制保存目录的存储驱动将根据填入的路径进行保存需要填写完整的alist目录
}

View File

@ -18,6 +18,7 @@ import importlib
import traceback
import urllib.parse
from datetime import datetime
from natsort import natsorted
# 兼容青龙
try:
@ -264,7 +265,8 @@ class MagicRename:
def sort_file_list(self, file_list, dir_filename_dict={}):
"""文件列表统一排序,给{I+}赋值"""
filename_list = [
f["file_name_re"]
# 强制加入`文件修改时间`字段供排序效果1无可排序字符时则按修改时间排序2和目录已有文件重名时始终在其后
f"{f['file_name_re']}{f['updated_at']}"
for f in file_list
if f.get("file_name_re") and not f["dir"]
]
@ -273,7 +275,7 @@ class MagicRename:
# print(f"dir_filename_list: {dir_filename_list}")
# 合并目录文件列表
filename_list = list(set(filename_list) | set(dir_filename_dict.values()))
filename_list.sort(key=self._custom_sort_key)
filename_list = natsorted(filename_list, key=self._custom_sort_key)
filename_index = {}
for name in filename_list:
if name in dir_filename_dict.values():
@ -286,7 +288,9 @@ class MagicRename:
for file in file_list:
if file.get("file_name_re"):
if match := re.search(r"\{I+\}", file["file_name_re"]):
i = filename_index.get(file["file_name_re"], 0)
i = filename_index.get(
f"{file['file_name_re']}{file['updated_at']}", 0
)
file["file_name_re"] = re.sub(
match.group(),
str(i).zfill(match.group().count("I")),
@ -609,7 +613,7 @@ class Quark:
"__t": datetime.now().timestamp(),
}
response = self._send_request("GET", url, params=querystring).json()
if response["data"]["status"] != 0:
if response["data"]["status"] == 2:
if retry_index > 0:
print()
break
@ -849,6 +853,17 @@ class Quark:
dir_file_list = self.ls_dir(to_pdir_fid)["data"]["list"]
dir_filename_list = [dir_file["file_name"] for dir_file in dir_file_list]
# print("dir_file_list: ", dir_file_list)
# 清空目标文件夹
fid_list = [item["fid"] for item in dir_file_list]
if fid_list:
self.delete(fid_list)
recycle_list = self.recycle_list()
record_id_list = [
item["record_id"] for item in recycle_list if item["fid"] in fid_list
]
self.recycle_remove(record_id_list)
# 重新获取目标目录文件列表
dir_file_list = self.ls_dir(to_pdir_fid)
tree.create_node(
savepath,
@ -898,8 +913,35 @@ class Quark:
need_save_list.append(share_file)
elif share_file["dir"]:
# 存在并是一个目录,历遍子目录
if task.get("update_subdir", False):
if re.search(task["update_subdir"], share_file["file_name"]):
if task.get("update_subdir", False) and re.search(
task["update_subdir"], share_file["file_name"]
):
if task.get("update_subdir_resave_mode", False):
# 重存模式:删除该目录下所有文件,重新转存
print(f"重存子目录:{savepath}/{share_file['file_name']}")
# 删除子目录、回收站中彻底删除
subdir = next(
(
f
for f in dir_file_list
if f["file_name"] == share_file["file_name"]
),
None,
)
delete_return = self.delete([subdir["fid"]])
self.query_task(delete_return["data"]["task_id"])
recycle_list = self.recycle_list()
record_id_list = [
item["record_id"]
for item in recycle_list
if item["fid"] == subdir["fid"]
]
self.recycle_remove(record_id_list)
# 作为新文件添加到转存列表
share_file["file_name_re"] = share_file["file_name"]
need_save_list.append(share_file)
else:
# 递归模式
print(f"检查子目录:{savepath}/{share_file['file_name']}")
subdir_tree = self.dir_check_and_save(
task,

View File

@ -2,3 +2,4 @@ flask
apscheduler
requests
treelib
natsort