mirror of
https://github.com/Cp0204/quark-auto-save.git
synced 2026-01-12 07:10:44 +08:00
在文件整理页面增加了刷新 Plex 媒体库和刷新 AList 目录功能,为 Plex 和 AList 插件增加了多账号支持功能
This commit is contained in:
parent
7d4672cb8e
commit
6f68c5a290
179
app/run.py
179
app/run.py
@ -241,6 +241,21 @@ def get_data():
|
||||
if not is_login():
|
||||
return jsonify({"success": False, "message": "未登录"})
|
||||
data = Config.read_json(CONFIG_PATH)
|
||||
|
||||
# 处理插件配置中的多账号支持字段,将数组格式转换为逗号分隔的字符串用于显示
|
||||
if "plugins" in data:
|
||||
# 处理Plex的quark_root_path
|
||||
if "plex" in data["plugins"] and "quark_root_path" in data["plugins"]["plex"]:
|
||||
data["plugins"]["plex"]["quark_root_path"] = format_array_config_for_display(
|
||||
data["plugins"]["plex"]["quark_root_path"]
|
||||
)
|
||||
|
||||
# 处理AList的storage_id
|
||||
if "alist" in data["plugins"] and "storage_id" in data["plugins"]["alist"]:
|
||||
data["plugins"]["alist"]["storage_id"] = format_array_config_for_display(
|
||||
data["plugins"]["alist"]["storage_id"]
|
||||
)
|
||||
|
||||
# 发送webui信息,但不发送密码原文
|
||||
data["webui"] = {
|
||||
"username": config_data["webui"]["username"],
|
||||
@ -307,6 +322,21 @@ def sync_task_plugins_config():
|
||||
current_config[key] = default_value
|
||||
|
||||
|
||||
def parse_comma_separated_config(value):
|
||||
"""解析逗号分隔的配置字符串为数组"""
|
||||
if isinstance(value, str) and value.strip():
|
||||
# 分割字符串,去除空白字符
|
||||
items = [item.strip() for item in value.split(',') if item.strip()]
|
||||
# 如果只有一个项目,返回字符串(向后兼容)
|
||||
return items[0] if len(items) == 1 else items
|
||||
return value
|
||||
|
||||
def format_array_config_for_display(value):
|
||||
"""将数组配置格式化为逗号分隔的字符串用于显示"""
|
||||
if isinstance(value, list):
|
||||
return ', '.join(value)
|
||||
return value
|
||||
|
||||
# 更新数据
|
||||
@app.route("/update", methods=["POST"])
|
||||
def update():
|
||||
@ -320,6 +350,19 @@ def update():
|
||||
# 更新webui凭据
|
||||
config_data["webui"]["username"] = value.get("username", config_data["webui"]["username"])
|
||||
config_data["webui"]["password"] = value.get("password", config_data["webui"]["password"])
|
||||
elif key == "plugins":
|
||||
# 处理插件配置中的多账号支持字段
|
||||
if "plex" in value and "quark_root_path" in value["plex"]:
|
||||
value["plex"]["quark_root_path"] = parse_comma_separated_config(
|
||||
value["plex"]["quark_root_path"]
|
||||
)
|
||||
|
||||
if "alist" in value and "storage_id" in value["alist"]:
|
||||
value["alist"]["storage_id"] = parse_comma_separated_config(
|
||||
value["alist"]["storage_id"]
|
||||
)
|
||||
|
||||
config_data.update({key: value})
|
||||
else:
|
||||
config_data.update({key: value})
|
||||
|
||||
@ -441,6 +484,142 @@ def refresh_alist_directory():
|
||||
return jsonify({"success": True, "message": "成功刷新 AList 目录"})
|
||||
|
||||
|
||||
# 文件整理页面刷新Plex媒体库
|
||||
@app.route("/refresh_filemanager_plex_library", methods=["POST"])
|
||||
def refresh_filemanager_plex_library():
|
||||
if not is_login():
|
||||
return jsonify({"success": False, "message": "未登录"})
|
||||
|
||||
folder_path = request.json.get("folder_path")
|
||||
account_index = request.json.get("account_index", 0)
|
||||
|
||||
if not folder_path:
|
||||
return jsonify({"success": False, "message": "缺少文件夹路径"})
|
||||
|
||||
# 检查Plex插件配置
|
||||
if not config_data.get("plugins", {}).get("plex", {}).get("url"):
|
||||
return jsonify({"success": False, "message": "Plex 插件未配置"})
|
||||
|
||||
# 导入Plex插件
|
||||
from plugins.plex import Plex
|
||||
|
||||
# 初始化Plex插件
|
||||
plex = Plex(**config_data["plugins"]["plex"])
|
||||
if not plex.is_active:
|
||||
return jsonify({"success": False, "message": "Plex 插件未正确配置"})
|
||||
|
||||
# 获取夸克账号信息
|
||||
try:
|
||||
account = Quark(config_data["cookie"][account_index], account_index)
|
||||
|
||||
# 将文件夹路径转换为实际的保存路径
|
||||
# folder_path是相对于夸克网盘根目录的路径
|
||||
# quark_root_path是夸克网盘在本地文件系统中的挂载点
|
||||
# 根据账号索引获取对应的夸克根路径
|
||||
quark_root_path = plex.get_quark_root_path(account_index)
|
||||
if not quark_root_path:
|
||||
return jsonify({"success": False, "message": f"Plex 插件未配置账号 {account_index} 的夸克根路径"})
|
||||
|
||||
if folder_path == "" or folder_path == "/":
|
||||
# 空字符串或根目录表示夸克网盘根目录
|
||||
full_path = quark_root_path
|
||||
else:
|
||||
# 确保路径格式正确
|
||||
if not folder_path.startswith("/"):
|
||||
folder_path = "/" + folder_path
|
||||
|
||||
# 拼接完整路径:夸克根路径 + 相对路径
|
||||
import os
|
||||
full_path = os.path.normpath(os.path.join(quark_root_path, folder_path.lstrip("/"))).replace("\\", "/")
|
||||
|
||||
# 确保库信息已加载
|
||||
if plex._libraries is None:
|
||||
plex._libraries = plex._get_libraries()
|
||||
|
||||
# 执行刷新
|
||||
success = plex.refresh(full_path)
|
||||
|
||||
if success:
|
||||
return jsonify({"success": True, "message": "成功刷新 Plex 媒体库"})
|
||||
else:
|
||||
return jsonify({"success": False, "message": "刷新 Plex 媒体库失败,请检查路径配置"})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({"success": False, "message": f"刷新 Plex 媒体库失败: {str(e)}"})
|
||||
|
||||
|
||||
# 文件整理页面刷新AList目录
|
||||
@app.route("/refresh_filemanager_alist_directory", methods=["POST"])
|
||||
def refresh_filemanager_alist_directory():
|
||||
if not is_login():
|
||||
return jsonify({"success": False, "message": "未登录"})
|
||||
|
||||
folder_path = request.json.get("folder_path")
|
||||
account_index = request.json.get("account_index", 0)
|
||||
|
||||
if not folder_path:
|
||||
return jsonify({"success": False, "message": "缺少文件夹路径"})
|
||||
|
||||
# 检查AList插件配置
|
||||
if not config_data.get("plugins", {}).get("alist", {}).get("url"):
|
||||
return jsonify({"success": False, "message": "AList 插件未配置"})
|
||||
|
||||
# 导入AList插件
|
||||
from plugins.alist import Alist
|
||||
|
||||
# 初始化AList插件
|
||||
alist = Alist(**config_data["plugins"]["alist"])
|
||||
if not alist.is_active:
|
||||
return jsonify({"success": False, "message": "AList 插件未正确配置"})
|
||||
|
||||
# 获取夸克账号信息
|
||||
try:
|
||||
account = Quark(config_data["cookie"][account_index], account_index)
|
||||
|
||||
# 将文件夹路径转换为实际的保存路径
|
||||
# folder_path是相对于夸克网盘根目录的路径,如 "/" 或 "/测试/文件夹"
|
||||
# 根据账号索引获取对应的存储配置
|
||||
storage_mount_path, quark_root_dir = alist.get_storage_config(account_index)
|
||||
|
||||
if not storage_mount_path or not quark_root_dir:
|
||||
return jsonify({"success": False, "message": f"AList 插件未配置账号 {account_index} 的存储信息"})
|
||||
|
||||
if folder_path == "/":
|
||||
# 根目录,直接使用夸克根路径
|
||||
full_path = quark_root_dir
|
||||
else:
|
||||
# 子目录,拼接路径
|
||||
import os
|
||||
# 移除folder_path开头的/,然后拼接
|
||||
relative_path = folder_path.lstrip("/")
|
||||
if quark_root_dir == "/":
|
||||
full_path = "/" + relative_path
|
||||
else:
|
||||
full_path = os.path.normpath(os.path.join(quark_root_dir, relative_path)).replace("\\", "/")
|
||||
|
||||
# 检查路径是否在夸克根目录内
|
||||
if quark_root_dir == "/" or full_path.startswith(quark_root_dir):
|
||||
# 使用账号对应的存储配置映射到AList路径
|
||||
# 构建AList路径
|
||||
if quark_root_dir == "/":
|
||||
relative_path = full_path.lstrip("/")
|
||||
else:
|
||||
relative_path = full_path.replace(quark_root_dir, "", 1).lstrip("/")
|
||||
|
||||
alist_path = os.path.normpath(
|
||||
os.path.join(storage_mount_path, relative_path)
|
||||
).replace("\\", "/")
|
||||
|
||||
# 执行刷新
|
||||
alist.refresh(alist_path)
|
||||
return jsonify({"success": True, "message": "成功刷新 AList 目录"})
|
||||
else:
|
||||
return jsonify({"success": False, "message": "路径不在AList配置的夸克根目录内"})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({"success": False, "message": f"刷新 AList 目录失败: {str(e)}"})
|
||||
|
||||
|
||||
@app.route("/task_suggestions")
|
||||
def get_task_suggestions():
|
||||
if not is_login():
|
||||
|
||||
@ -3965,14 +3965,14 @@ table.selectable-records .expand-button:hover {
|
||||
|
||||
/* Plex图标样式 */
|
||||
.plex-icon {
|
||||
width: 10.4px;
|
||||
width: 10.3px;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* AList图标样式 */
|
||||
.alist-icon {
|
||||
width: 17.8px;
|
||||
width: 18px;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
position: relative;
|
||||
@ -4201,11 +4201,32 @@ select.task-filter-select,
|
||||
}
|
||||
|
||||
.batch-rename-btn {
|
||||
margin-left: 8px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px !important;
|
||||
color: var(--dark-text-color) !important;
|
||||
border-color: var(--dark-text-color) !important;
|
||||
}
|
||||
|
||||
/* 为相邻的batch-rename-btn按钮添加左边距 */
|
||||
.batch-rename-btn + .batch-rename-btn {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* 文件整理页面按钮与前面元素的间距 */
|
||||
.file-manager-rule-bar .batch-rename-btn:first-of-type {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* 移动端文件整理页面按钮与前面元素的间距 */
|
||||
.file-manager-rule-bar-responsive .batch-rename-btn:first-of-type {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.batch-rename-btn:hover {
|
||||
background-color: var(--dark-text-color) !important;
|
||||
border-color: var(--dark-text-color) !important;
|
||||
@ -4217,6 +4238,50 @@ select.task-filter-select,
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
/* 确保文件整理页面的Plex和AList按钮样式与任务列表一致 */
|
||||
.batch-rename-btn.btn-outline-plex,
|
||||
.batch-rename-btn.btn-outline-alist {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px !important;
|
||||
}
|
||||
|
||||
/* 文件整理页面Plex按钮样式 */
|
||||
.batch-rename-btn.btn-outline-plex {
|
||||
border-color: #EBAF00 !important;
|
||||
color: #EBAF00 !important;
|
||||
}
|
||||
|
||||
.batch-rename-btn.btn-outline-plex:hover {
|
||||
background-color: #EBAF00 !important;
|
||||
border-color: #EBAF00 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.batch-rename-btn.btn-outline-plex:hover .plex-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
/* 文件整理页面AList按钮样式 */
|
||||
.batch-rename-btn.btn-outline-alist {
|
||||
border-color: #70C6BE !important;
|
||||
color: #70C6BE !important;
|
||||
}
|
||||
|
||||
.batch-rename-btn.btn-outline-alist:hover {
|
||||
background-color: #70C6BE !important;
|
||||
border-color: #70C6BE !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.batch-rename-btn.btn-outline-alist:hover .alist-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
/* 文件表格中的展开按钮 */
|
||||
.expand-button {
|
||||
position: absolute;
|
||||
@ -4274,8 +4339,24 @@ select.task-filter-select,
|
||||
}
|
||||
|
||||
.batch-rename-btn {
|
||||
margin-left: 0;
|
||||
margin-top: 10px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px !important;
|
||||
}
|
||||
|
||||
/* 移动端按钮间距重置 */
|
||||
.batch-rename-btn + .batch-rename-btn {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* 移动端第一个按钮与前面元素的间距 */
|
||||
.file-manager-rule-bar-responsive .batch-rename-btn:first-of-type {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
#batchRenameModal .modal-dialog {
|
||||
@ -5126,6 +5207,13 @@ body .selectable-files tr.selected-file .file-size-cell .delete-record-btn {
|
||||
/* 只影响移动端的“预览并执行重命名”按钮上边距 */
|
||||
.file-manager-rule-bar-responsive .batch-rename-btn {
|
||||
margin-top: 0px; /* 你想要的上边距 */
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px !important;
|
||||
}
|
||||
|
||||
/* 移动端预览并执行重命名按钮与含文件夹间距 */
|
||||
@ -5133,8 +5221,12 @@ body .selectable-files tr.selected-file .file-size-cell .delete-record-btn {
|
||||
margin-left: 8px !important;
|
||||
}
|
||||
|
||||
/* 移动端账号选择栏中的刷新按钮间距 */
|
||||
.file-manager-rule-bar-responsive .d-flex .batch-rename-btn {
|
||||
/* 移动端账号选择栏中的按钮间距 */
|
||||
.file-manager-rule-bar-responsive .d-flex .batch-rename-btn:first-of-type {
|
||||
margin-left: 8px !important;
|
||||
}
|
||||
|
||||
.file-manager-rule-bar-responsive .d-flex .batch-rename-btn + .batch-rename-btn {
|
||||
margin-left: 8px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -451,9 +451,11 @@
|
||||
<div class="collapse" :id="'collapse_'+pluginName" style="margin-left: 26px;">
|
||||
<div v-for="(value, key, keyIndex) in plugin" :key="key" class="input-group mb-2" :style="{ marginBottom: keyIndex === Object.keys(plugin).length - 1 && pluginName === Object.keys(getAvailablePlugins(formData.plugins)).pop() ? '8.5px !important' : '' }">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" v-html="key"></span>
|
||||
<span class="input-group-text" v-html="key" :title="getPluginConfigHelp(pluginName, key)"></span>
|
||||
</div>
|
||||
<input type="text" v-model="formData.plugins[pluginName][key]" class="form-control">
|
||||
<input type="text" v-model="formData.plugins[pluginName][key]" class="form-control"
|
||||
:placeholder="getPluginConfigPlaceholder(pluginName, key)"
|
||||
:title="getPluginConfigHelp(pluginName, key)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1047,6 +1049,8 @@
|
||||
<option v-for="(account, index) in accountsDetail" :key="index" :value="index">{{ account.display_text }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-plex batch-rename-btn" v-if="formData.plugins && formData.plugins.plex && formData.plugins.plex.url && formData.plugins.plex.token && formData.plugins.plex.quark_root_path && formData.button_display.refresh_plex !== 'disabled'" @click="refreshFileManagerPlexLibrary" title="刷新Plex媒体库"><img src="./static/Plex.svg" class="plex-icon"></button>
|
||||
<button type="button" class="btn btn-outline-alist batch-rename-btn" v-if="formData.plugins && formData.plugins.alist && formData.plugins.alist.url && formData.plugins.alist.token && formData.plugins.alist.storage_id && formData.button_display.refresh_alist !== 'disabled'" @click="refreshFileManagerAlistDirectory" title="刷新AList目录"><img src="https://cdn.jsdelivr.net/gh/alist-org/logo@main/logo.svg" class="alist-icon"></button>
|
||||
<button type="button" class="btn btn-outline-primary batch-rename-btn" @click="refreshCurrentFolderCache" title="刷新当前目录缓存">
|
||||
<i class="bi bi-arrow-clockwise"></i>
|
||||
</button>
|
||||
@ -1062,6 +1066,8 @@
|
||||
<option v-for="(account, index) in accountsDetail" :key="index" :value="index">{{ account.display_text }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-plex batch-rename-btn" v-if="formData.plugins && formData.plugins.plex && formData.plugins.plex.url && formData.plugins.plex.token && formData.plugins.plex.quark_root_path && formData.button_display.refresh_plex !== 'disabled'" @click="refreshFileManagerPlexLibrary" title="刷新Plex媒体库"><img src="./static/Plex.svg" class="plex-icon"></button>
|
||||
<button type="button" class="btn btn-outline-alist batch-rename-btn" v-if="formData.plugins && formData.plugins.alist && formData.plugins.alist.url && formData.plugins.alist.token && formData.plugins.alist.storage_id && formData.button_display.refresh_alist !== 'disabled'" @click="refreshFileManagerAlistDirectory" title="刷新AList目录"><img src="https://cdn.jsdelivr.net/gh/alist-org/logo@main/logo.svg" class="alist-icon"></button>
|
||||
<button type="button" class="btn btn-outline-primary batch-rename-btn" @click="refreshCurrentFolderCache" title="刷新当前目录缓存">
|
||||
<i class="bi bi-arrow-clockwise"></i>
|
||||
</button>
|
||||
@ -1946,7 +1952,27 @@
|
||||
|
||||
return message;
|
||||
},
|
||||
|
||||
|
||||
// 获取插件配置的占位符文本
|
||||
getPluginConfigPlaceholder(pluginName, key) {
|
||||
if (pluginName === 'plex' && key === 'quark_root_path') {
|
||||
return '输入夸克根目录相对于 Plex 媒体库目录的路径,多个路径用逗号分隔';
|
||||
} else if (pluginName === 'alist' && key === 'storage_id') {
|
||||
return '输入 AList 服务器夸克存储的 ID,多个 ID 用逗号分隔';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
// 获取插件配置的帮助文本
|
||||
getPluginConfigHelp(pluginName, key) {
|
||||
if (pluginName === 'plex' && key === 'quark_root_path') {
|
||||
return '多账号支持:多个路径用逗号分隔,顺序与Cookie顺序对应,如:/path1, /path2';
|
||||
} else if (pluginName === 'alist' && key === 'storage_id') {
|
||||
return '多账号支持:多个存储ID用逗号分隔,顺序与Cookie顺序对应,如:1, 2, 3';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
fetchUserInfo() {
|
||||
// 获取所有cookie对应的用户信息
|
||||
axios.get('/get_user_info')
|
||||
@ -3093,7 +3119,7 @@
|
||||
// 短暂延迟后重试
|
||||
setTimeout(() => {
|
||||
this.getSavepathDetail(params, retryCount + 1, maxRetries);
|
||||
}, 2000); // 2秒后重试
|
||||
}, 1000); // 1秒后重试
|
||||
} else {
|
||||
// 超过最大重试次数,显示错误信息
|
||||
this.fileSelect.error = "获取文件夹列表失败,请关闭窗口再试一次";
|
||||
@ -3178,7 +3204,7 @@
|
||||
// 短暂延迟后重试
|
||||
setTimeout(() => {
|
||||
this.getShareDetail(retryCount + 1, maxRetries);
|
||||
}, 2000); // 2秒后重试
|
||||
}, 1000); // 1秒后重试
|
||||
} else {
|
||||
// 超过最大重试次数,显示错误信息
|
||||
this.fileSelect.error = "获取文件夹列表失败,请关闭窗口再试一次";
|
||||
@ -4440,6 +4466,59 @@
|
||||
alert("刷新 AList 目录失败: " + (error.response?.data?.message || error.message || "未知错误"));
|
||||
});
|
||||
},
|
||||
// 文件整理页面刷新Plex媒体库
|
||||
refreshFileManagerPlexLibrary() {
|
||||
// 获取当前目录路径
|
||||
const currentPath = this.getCurrentFolderPath();
|
||||
|
||||
axios.post('/refresh_filemanager_plex_library', {
|
||||
folder_path: currentPath,
|
||||
account_index: this.fileManager.selectedAccountIndex
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data.success) {
|
||||
this.showToast(response.data.message);
|
||||
} else {
|
||||
alert(response.data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert("刷新 Plex 媒体库失败: " + (error.response?.data?.message || error.message || "未知错误"));
|
||||
});
|
||||
},
|
||||
// 文件整理页面刷新AList目录
|
||||
refreshFileManagerAlistDirectory() {
|
||||
// 获取当前目录路径
|
||||
const currentPath = this.getCurrentFolderPath();
|
||||
|
||||
axios.post('/refresh_filemanager_alist_directory', {
|
||||
folder_path: currentPath,
|
||||
account_index: this.fileManager.selectedAccountIndex
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data.success) {
|
||||
this.showToast(response.data.message);
|
||||
} else {
|
||||
alert(response.data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert("刷新 AList 目录失败: " + (error.response?.data?.message || error.message || "未知错误"));
|
||||
});
|
||||
},
|
||||
// 获取当前文件夹路径(相对于夸克网盘根目录)
|
||||
getCurrentFolderPath() {
|
||||
if (this.fileManager.currentFolder === 'root') {
|
||||
return '/'; // 根目录返回 /,表示夸克网盘根目录
|
||||
}
|
||||
|
||||
// 构建完整路径(相对于夸克网盘根目录)
|
||||
let path = '';
|
||||
for (const pathItem of this.fileManager.paths) {
|
||||
path += '/' + pathItem.name;
|
||||
}
|
||||
return path || '/';
|
||||
},
|
||||
filterByTaskName(taskName, event) {
|
||||
// 防止事件冒泡,避免触发行选择
|
||||
if (event) {
|
||||
|
||||
@ -16,6 +16,9 @@ class Alist:
|
||||
# 缓存参数
|
||||
storage_mount_path = None
|
||||
quark_root_dir = None
|
||||
# 多账号支持
|
||||
storage_mount_paths = []
|
||||
quark_root_dirs = []
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""初始化AList插件"""
|
||||
@ -28,8 +31,17 @@ class Alist:
|
||||
if key in kwargs:
|
||||
setattr(self, key, kwargs[key])
|
||||
else:
|
||||
print(f"{self.plugin_name} 模块缺少必要参数: {key}")
|
||||
|
||||
pass # 不显示缺少参数的提示
|
||||
|
||||
# 处理多账号配置:支持数组形式的storage_id
|
||||
if isinstance(self.storage_id, list):
|
||||
self.storage_ids = self.storage_id
|
||||
# 为了向后兼容,使用第一个ID作为默认值
|
||||
self.storage_id = self.storage_ids[0] if self.storage_ids else ""
|
||||
else:
|
||||
# 单一配置转换为数组格式
|
||||
self.storage_ids = [self.storage_id] if self.storage_id else []
|
||||
|
||||
# 检查基本配置
|
||||
if not self.url or not self.token or not self.storage_id:
|
||||
return
|
||||
@ -43,27 +55,56 @@ class Alist:
|
||||
|
||||
# 验证AList连接
|
||||
if self.get_info():
|
||||
# 解析存储ID
|
||||
success, result = self.storage_id_to_path(self.storage_id)
|
||||
if success:
|
||||
self.storage_mount_path, self.quark_root_dir = result
|
||||
|
||||
# 确保路径格式正确
|
||||
if self.quark_root_dir != "/":
|
||||
if not self.quark_root_dir.startswith("/"):
|
||||
self.quark_root_dir = f"/{self.quark_root_dir}"
|
||||
self.quark_root_dir = self.quark_root_dir.rstrip("/")
|
||||
|
||||
if not self.storage_mount_path.startswith("/"):
|
||||
self.storage_mount_path = f"/{self.storage_mount_path}"
|
||||
self.storage_mount_path = self.storage_mount_path.rstrip("/")
|
||||
|
||||
# 解析所有存储ID
|
||||
for i, storage_id in enumerate(self.storage_ids):
|
||||
success, result = self.storage_id_to_path(storage_id)
|
||||
if success:
|
||||
mount_path, root_dir = result
|
||||
|
||||
# 确保路径格式正确
|
||||
if root_dir != "/":
|
||||
if not root_dir.startswith("/"):
|
||||
root_dir = f"/{root_dir}"
|
||||
root_dir = root_dir.rstrip("/")
|
||||
|
||||
if not mount_path.startswith("/"):
|
||||
mount_path = f"/{mount_path}"
|
||||
mount_path = mount_path.rstrip("/")
|
||||
|
||||
self.storage_mount_paths.append(mount_path)
|
||||
self.quark_root_dirs.append(root_dir)
|
||||
|
||||
if i == 0:
|
||||
# 设置默认值(向后兼容)
|
||||
self.storage_mount_path = mount_path
|
||||
self.quark_root_dir = root_dir
|
||||
|
||||
|
||||
else:
|
||||
print(f"AList 刷新: 存储ID [{i}] {storage_id} 解析失败")
|
||||
# 添加空值保持索引对应
|
||||
self.storage_mount_paths.append("")
|
||||
self.quark_root_dirs.append("")
|
||||
|
||||
# 只要有一个存储ID解析成功就激活插件
|
||||
if any(self.storage_mount_paths):
|
||||
self.is_active = True
|
||||
else:
|
||||
print(f"AList 刷新: 存储信息解析失败")
|
||||
print(f"AList 刷新: 所有存储ID解析失败")
|
||||
else:
|
||||
print(f"AList 刷新: 服务器连接失败")
|
||||
|
||||
def get_storage_config(self, account_index=0):
|
||||
"""根据账号索引获取对应的存储配置"""
|
||||
if account_index < len(self.storage_mount_paths) and account_index < len(self.quark_root_dirs):
|
||||
return self.storage_mount_paths[account_index], self.quark_root_dirs[account_index]
|
||||
else:
|
||||
# 如果索引超出范围,使用第一个配置作为默认值
|
||||
if self.storage_mount_paths and self.quark_root_dirs:
|
||||
return self.storage_mount_paths[0], self.quark_root_dirs[0]
|
||||
else:
|
||||
return "", ""
|
||||
|
||||
def run(self, task, **kwargs):
|
||||
"""
|
||||
插件主入口,当有新文件保存时触发刷新AList目录
|
||||
|
||||
@ -46,12 +46,10 @@ class Alist_strm_gen:
|
||||
missing_configs.append(key)
|
||||
|
||||
if missing_configs:
|
||||
print(f"{self.plugin_name} 模块缺少必要参数: {', '.join(missing_configs)}")
|
||||
return
|
||||
|
||||
return # 不显示缺少参数的提示
|
||||
|
||||
if not self.url or not self.token or not self.storage_id:
|
||||
print(f"{self.plugin_name} 模块配置不完整,请检查配置")
|
||||
return
|
||||
return # 不显示配置不完整的提示
|
||||
|
||||
# 检查 strm_save_dir 是否存在
|
||||
if not os.path.exists(self.strm_save_dir):
|
||||
|
||||
@ -18,11 +18,29 @@ class Plex:
|
||||
if key in kwargs:
|
||||
setattr(self, key, kwargs[key])
|
||||
else:
|
||||
print(f"{self.__class__.__name__} 模块缺少必要参数: {key}")
|
||||
pass # 不显示缺少参数的提示
|
||||
|
||||
# 处理多账号配置:支持数组形式的quark_root_path
|
||||
if isinstance(self.quark_root_path, list):
|
||||
self.quark_root_paths = self.quark_root_path
|
||||
# 为了向后兼容,使用第一个路径作为默认值
|
||||
self.quark_root_path = self.quark_root_paths[0] if self.quark_root_paths else ""
|
||||
else:
|
||||
# 单一配置转换为数组格式
|
||||
self.quark_root_paths = [self.quark_root_path] if self.quark_root_path else []
|
||||
|
||||
if self.url and self.token and self.quark_root_path:
|
||||
if self.get_info():
|
||||
self.is_active = True
|
||||
|
||||
def get_quark_root_path(self, account_index=0):
|
||||
"""根据账号索引获取对应的quark_root_path"""
|
||||
if account_index < len(self.quark_root_paths):
|
||||
return self.quark_root_paths[account_index]
|
||||
else:
|
||||
# 如果索引超出范围,使用第一个路径作为默认值
|
||||
return self.quark_root_paths[0] if self.quark_root_paths else ""
|
||||
|
||||
def run(self, task, **kwargs):
|
||||
if task.get("savepath"):
|
||||
# 检查是否已缓存库信息
|
||||
@ -59,10 +77,8 @@ class Plex:
|
||||
try:
|
||||
for library in self._libraries:
|
||||
for location in library.get("Location", []):
|
||||
if (
|
||||
os.path.commonpath([folder_path, location["path"]])
|
||||
== location["path"]
|
||||
):
|
||||
location_path = location.get("path", "")
|
||||
if folder_path.startswith(location_path):
|
||||
refresh_url = f"{self.url}/library/sections/{library['key']}/refresh?path={folder_path}"
|
||||
refresh_response = requests.get(refresh_url, headers=headers)
|
||||
if refresh_response.status_code == 200:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user