Compare commits

...

6 Commits

Author SHA1 Message Date
x1ao4
b14bfbdfd1
Merge pull request #38 from x1ao4/dev
修复剧集命名模式下忽略后缀功能失效的问题并优化侧边栏部分内容的显示效果
2025-07-10 01:17:29 +08:00
x1ao4
a50269d718 修复剧集命名模式下忽略后缀功能失效的问题并优化侧边栏部分内容的显示效果 2025-07-10 01:15:28 +08:00
x1ao4
a80378d5de
Merge pull request #37 from x1ao4/dev
修复大量文件转存时的索引越界错误和分享链接检查时的网络错误问题
2025-07-09 23:29:30 +08:00
x1ao4
19f63e4504
规范 Docker Compose 格式 2025-07-09 23:25:44 +08:00
x1ao4
4ad08bae91 忽略分享链接检查时的 request error 网络错误
- 修复网络不稳定时误报 request error 状态的问题
- 在分享链接检查中忽略网络错误,避免误导用户
2025-07-09 23:01:47 +08:00
x1ao4
116f3d5c28 修复大量文件转存时的索引越界错误
- 添加安全检查防止访问 save_as_top_fids 时索引越界
- 当索引超出范围时使用原始文件 fid 作为备用值
2025-07-09 22:35:04 +08:00
4 changed files with 92 additions and 22 deletions

View File

@ -75,7 +75,7 @@ docker run -d \
x1ao4/quark-auto-save-x:latest
```
Docker Compose
Docker Compose(推荐)
```yaml
version: "3.3"
@ -89,7 +89,6 @@ services:
- /自定义配置文件的存储目录/quark-auto-save-x/config:/app/config
- /自定义生成文件的存储目录:/media # 可选,插件 alist_strm_gen 生成 strm 使用
restart: unless-stopped
networks: {}
```
默认管理地址http://yourhost:5005

View File

@ -281,7 +281,7 @@ main div[v-if="activeTab === 'config'"] .row.title:first-child {
left: 0;
z-index: 100;
padding: 54px 0 0;
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .088);
transition: none; /* 禁用动画效果 */
overflow-x: hidden; /* 防止水平滚动条 */
}
@ -2137,7 +2137,7 @@ div.jsoneditor-tree button.jsoneditor-button:focus {
/* 侧边栏菜单项图标样式 */
.sidebar .nav-link .bi-list-ul {
font-size: 1.09rem;
font-size: 1.1rem;
position: relative;
top: 0.5px; /* 向下微调 */
}
@ -2149,7 +2149,7 @@ div.jsoneditor-tree button.jsoneditor-button:focus {
}
.sidebar .nav-link .bi-clock-history {
font-size: 1rem;
font-size: 1.015rem;
}
.sidebar .nav-link .bi-archive {

View File

@ -2453,7 +2453,7 @@
checkShareUrlStatus() {
// 只在任务列表页面检查
if (this.activeTab !== 'tasklist') return;
// 遍历所有任务
this.formData.tasklist.forEach((task, index) => {
// 如果任务有分享链接且没有设置shareurl_ban
@ -2463,7 +2463,13 @@
.then(response => {
const share_detail = response.data.data;
if (!response.data.success) {
// 使用格式化函数处理错误信息
// 检查是否是 request error如果是则忽略
if (share_detail.error && share_detail.error.includes("request error")) {
// 忽略 request error不设置 shareurl_ban
console.log('检查分享链接时出现网络错误,忽略此错误:', share_detail.error);
return;
}
// 使用格式化函数处理其他错误信息
this.$set(task, "shareurl_ban", this.formatShareUrlBanMessage(share_detail.error));
} else if (share_detail.list !== undefined && share_detail.list.length === 0) {
// 检查文件列表是否为空,确保列表存在且为空
@ -2471,8 +2477,8 @@
}
})
.catch(error => {
// 错误处理
console.error('检查分享链接状态失败:', error);
// 网络请求失败,忽略错误,不设置 shareurl_ban
console.log('检查分享链接状态时网络请求失败,忽略此错误:', error);
});
}
});
@ -3173,8 +3179,15 @@
return;
}
}
// 使用格式化函数处理错误信息
// 检查是否是 request error如果是则忽略
if (share_detail.error && share_detail.error.includes("request error")) {
// 忽略 request error不设置 shareurl_ban
console.log('修改分享链接时出现网络错误,忽略此错误:', share_detail.error);
return;
}
// 使用格式化函数处理其他错误信息
this.$set(task, "shareurl_ban", this.formatShareUrlBanMessage(share_detail.error));
} else {
// 检查文件列表是否为空
@ -3188,7 +3201,8 @@
}
})
.catch(error => {
// 错误处理
// 网络请求失败,忽略错误,不设置 shareurl_ban
console.log('修改分享链接时网络请求失败,忽略此错误:', error);
});
},
clearData(target) {
@ -3401,14 +3415,21 @@
// 检查是否包含已知的失效原因
const error = response.data.data.error || "";
let isInvalid = false;
// 如果是 request error视为有效网络问题不是资源问题
if (error.includes("request error")) {
this.smart_param.validateProgress.valid++;
resolve(link);
return;
}
for (const term of invalidTerms) {
if (error.includes(term)) {
isInvalid = true;
break;
}
}
// 如果不是已知的失效原因,保留该结果
if (!isInvalid) {
this.smart_param.validateProgress.valid++;

View File

@ -2251,8 +2251,17 @@ class Quark:
else:
target_name = episode_pattern.replace("[]", f"{episode_num:02d}") + file_ext
# 检查目标文件名是否已存在
target_exists = any(dir_file["file_name"] == target_name for dir_file in dir_file_list)
# 检查目标文件名是否已存在,支持忽略后缀选项
if task.get("ignore_extension", False):
# 忽略后缀模式:只比较文件名部分,不比较扩展名
target_name_base = os.path.splitext(target_name)[0]
target_exists = any(
os.path.splitext(dir_file["file_name"])[0] == target_name_base for dir_file in dir_file_list
)
else:
# 不忽略后缀模式:完整文件名必须匹配
target_exists = any(dir_file["file_name"] == target_name for dir_file in dir_file_list)
if target_exists:
is_duplicate = True
@ -2752,6 +2761,7 @@ class Quark:
if query_task_return["code"] == 0:
# 建立目录树
saved_files = []
for index, item in enumerate(need_save_list):
icon = (
"📁"
@ -2779,12 +2789,16 @@ class Quark:
saved_files.append(format_file_display("", icon, display_name))
# 检查节点是否已存在于树中,避免重复添加
if not tree.contains(item["fid"]):
# 安全地获取save_as_top_fids中的fid防止索引越界
save_as_top_fids = query_task_return.get('data', {}).get('save_as', {}).get('save_as_top_fids', [])
saved_fid = save_as_top_fids[index] if index < len(save_as_top_fids) else item["fid"]
tree.create_node(
display_name, # 只存储文件名,不包含图标
item["fid"],
parent=pdir_fid,
data={
"fid": f"{query_task_return['data']['save_as']['save_as_top_fids'][index]}",
"fid": f"{saved_fid}",
"path": f"{savepath}/{item['save_name']}",
"is_dir": item["dir"],
"icon": icon, # 将图标存储在data中
@ -2975,7 +2989,19 @@ class Quark:
else:
save_name = sequence_pattern.replace("{}", f"{current_sequence:02d}") + file_ext
if save_name != dir_file["file_name"] and save_name not in dir_file_name_list:
# 检查是否需要重命名,支持忽略后缀选项
name_conflict = False
if task.get("ignore_extension", False):
# 忽略后缀模式:只比较文件名部分,不比较扩展名
save_name_base = os.path.splitext(save_name)[0]
name_conflict = any(
os.path.splitext(existing_name)[0] == save_name_base for existing_name in dir_file_name_list
)
else:
# 不忽略后缀模式:完整文件名必须匹配
name_conflict = save_name in dir_file_name_list
if save_name != dir_file["file_name"] and not name_conflict:
# 收集重命名对,包含原始文件信息以便排序
renamed_pairs.append((dir_file, save_name, current_sequence))
dir_file_name_list.append(save_name)
@ -3464,8 +3490,19 @@ class Quark:
# 执行重命名操作,但不立即打印日志
for dir_file, new_name, _ in rename_operations:
# 防止重名
if new_name not in [f["file_name"] for f in dir_file_list]:
# 防止重名,支持忽略后缀选项
name_conflict = False
if task.get("ignore_extension", False):
# 忽略后缀模式:只比较文件名部分,不比较扩展名
new_name_base = os.path.splitext(new_name)[0]
name_conflict = any(
os.path.splitext(f["file_name"])[0] == new_name_base for f in dir_file_list
)
else:
# 不忽略后缀模式:完整文件名必须匹配
name_conflict = new_name in [f["file_name"] for f in dir_file_list]
if not name_conflict:
try:
rename_return = self.rename(dir_file["fid"], new_name)
if rename_return["code"] == 0:
@ -3621,8 +3658,21 @@ class Quark:
# 执行重命名操作,并收集日志
already_renamed_files = set() # 用于防止重复重命名
for dir_file, new_name in rename_operations:
# 检查是否会导致重名
if new_name not in [f["file_name"] for f in dir_file_list] and new_name not in already_renamed_files:
# 检查是否会导致重名,支持忽略后缀选项
name_conflict = False
if task.get("ignore_extension", False):
# 忽略后缀模式:只比较文件名部分,不比较扩展名
new_name_base = os.path.splitext(new_name)[0]
name_conflict = any(
os.path.splitext(f["file_name"])[0] == new_name_base for f in dir_file_list
) or any(
os.path.splitext(existing_name)[0] == new_name_base for existing_name in already_renamed_files
)
else:
# 不忽略后缀模式:完整文件名必须匹配
name_conflict = new_name in [f["file_name"] for f in dir_file_list] or new_name in already_renamed_files
if not name_conflict:
try:
rename_return = self.rename(dir_file["fid"], new_name)
if rename_return["code"] == 0: