mirror of
https://github.com/Cp0204/quark-auto-save.git
synced 2026-01-18 19:00:44 +08:00
Compare commits
6 Commits
e9ae452cd2
...
b9b80b33a6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9b80b33a6 | ||
|
|
d9fc4659b8 | ||
|
|
8309f4a4d4 | ||
|
|
805f624b89 | ||
|
|
e0cb7443fe | ||
|
|
fd46206024 |
20
app/run.py
20
app/run.py
@ -46,7 +46,7 @@ PYTHON_PATH = "python3" if os.path.exists("/usr/bin/python3") else "python"
|
|||||||
SCRIPT_PATH = os.environ.get("SCRIPT_PATH", "./quark_auto_save.py")
|
SCRIPT_PATH = os.environ.get("SCRIPT_PATH", "./quark_auto_save.py")
|
||||||
CONFIG_PATH = os.environ.get("CONFIG_PATH", "./config/quark_config.json")
|
CONFIG_PATH = os.environ.get("CONFIG_PATH", "./config/quark_config.json")
|
||||||
PLUGIN_FLAGS = os.environ.get("PLUGIN_FLAGS", "")
|
PLUGIN_FLAGS = os.environ.get("PLUGIN_FLAGS", "")
|
||||||
DEBUG = os.environ.get("DEBUG", False)
|
DEBUG = os.environ.get("DEBUG", "false").lower() == "true"
|
||||||
|
|
||||||
config_data = {}
|
config_data = {}
|
||||||
task_plugins_config_default = {}
|
task_plugins_config_default = {}
|
||||||
@ -86,10 +86,7 @@ def get_login_token():
|
|||||||
|
|
||||||
def is_login():
|
def is_login():
|
||||||
login_token = get_login_token()
|
login_token = get_login_token()
|
||||||
if (
|
if session.get("token") == login_token or request.args.get("token") == login_token:
|
||||||
session.get("token") == login_token
|
|
||||||
or request.args.get("token") == login_token
|
|
||||||
):
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@ -224,7 +221,12 @@ def get_task_suggestions():
|
|||||||
query = request.args.get("q", "").lower()
|
query = request.args.get("q", "").lower()
|
||||||
deep = request.args.get("d", "").lower()
|
deep = request.args.get("d", "").lower()
|
||||||
try:
|
try:
|
||||||
if cs_data := config_data.get("source", {}).get("cloudsaver", {}):
|
cs_data = config_data.get("source", {}).get("cloudsaver", {})
|
||||||
|
if (
|
||||||
|
cs_data.get("server")
|
||||||
|
and cs_data.get("username")
|
||||||
|
and cs_data.get("password")
|
||||||
|
):
|
||||||
cs = CloudSaver(cs_data.get("server"))
|
cs = CloudSaver(cs_data.get("server"))
|
||||||
cs.set_auth(
|
cs.set_auth(
|
||||||
cs_data.get("username", ""),
|
cs_data.get("username", ""),
|
||||||
@ -237,16 +239,16 @@ def get_task_suggestions():
|
|||||||
cs_data["token"] = search.get("new_token")
|
cs_data["token"] = search.get("new_token")
|
||||||
Config.write_json(CONFIG_PATH, config_data)
|
Config.write_json(CONFIG_PATH, config_data)
|
||||||
search_results = cs.clean_search_results(search.get("data"))
|
search_results = cs.clean_search_results(search.get("data"))
|
||||||
return jsonify({"success": True, "data": search_results})
|
return jsonify({"success": True, "source": "CloudSaver", "data": search_results})
|
||||||
else:
|
else:
|
||||||
return jsonify({"success": True, "message": search.get("message")})
|
return jsonify({"success": True, "message": search.get("message")})
|
||||||
else:
|
else:
|
||||||
base_url = base64.b64decode("aHR0cHM6Ly9zLjkxNzc4OC54eXo=").decode()
|
base_url = base64.b64decode("aHR0cHM6Ly9zLjkxNzc4OC54eXo=").decode()
|
||||||
url = f"{base_url}/task_suggestions?q={query}&d={deep}"
|
url = f"{base_url}/task_suggestions?q={query}&d={deep}"
|
||||||
response = requests.get(url)
|
response = requests.get(url)
|
||||||
return jsonify({"success": True, "data": response.json()})
|
return jsonify({"success": True, "source": "网络公开", "data": response.json()})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({"success": False, "message": str(e)})
|
return jsonify({"success": True, "message": f"error: {str(e)}"})
|
||||||
|
|
||||||
|
|
||||||
@app.route("/get_share_detail")
|
@app.route("/get_share_detail")
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import re
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
@ -76,7 +77,10 @@ class CloudSaver:
|
|||||||
if result.get("success"):
|
if result.get("success"):
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
if result.get("message") == "无效的 token" or result.get("message") == "未提供 token":
|
if (
|
||||||
|
result.get("message") == "无效的 token"
|
||||||
|
or result.get("message") == "未提供 token"
|
||||||
|
):
|
||||||
login_result = self.login()
|
login_result = self.login()
|
||||||
if login_result.get("success"):
|
if login_result.get("success"):
|
||||||
result = self.search(keyword, last_message_id)
|
result = self.search(keyword, last_message_id)
|
||||||
@ -99,24 +103,38 @@ class CloudSaver:
|
|||||||
Returns:
|
Returns:
|
||||||
list: 夸克网盘链接列表
|
list: 夸克网盘链接列表
|
||||||
"""
|
"""
|
||||||
|
pattern_title = r"(名称|标题)[::]?(.*)"
|
||||||
|
pattern_content = r"(描述|简介)[::]?(.*)(链接|标签)"
|
||||||
clean_results = []
|
clean_results = []
|
||||||
|
link_array = []
|
||||||
for channel in search_results:
|
for channel in search_results:
|
||||||
for item in channel.get("list", []):
|
for item in channel.get("list", []):
|
||||||
cloud_links = item.get("cloudLinks", [])
|
cloud_links = item.get("cloudLinks", [])
|
||||||
for link in cloud_links:
|
for link in cloud_links:
|
||||||
if link.get("cloudType") == "quark":
|
if link.get("cloudType") == "quark":
|
||||||
|
# 清洗标题
|
||||||
|
title = item.get("title", "")
|
||||||
|
if match := re.search(pattern_title, title, re.DOTALL):
|
||||||
|
title = match.group(2)
|
||||||
|
title = title.replace("&", "&").strip()
|
||||||
|
# 清洗内容
|
||||||
|
content = item.get("content", "")
|
||||||
|
if match := re.search(pattern_content, content, re.DOTALL):
|
||||||
|
content = match.group(2)
|
||||||
|
content = content.replace('<mark class="highlight">', "")
|
||||||
|
content = content.replace("</mark>", "")
|
||||||
|
content = content.strip()
|
||||||
|
# 链接去重
|
||||||
|
if link.get("link") not in link_array:
|
||||||
|
link_array.append(link.get("link"))
|
||||||
clean_results.append(
|
clean_results.append(
|
||||||
{
|
{
|
||||||
"shareurl": link.get("link"),
|
"shareurl": link.get("link"),
|
||||||
"taskname": item.get("title", "")
|
"taskname": title,
|
||||||
.strip("名称:")
|
"content": content,
|
||||||
.replace("&", "&"),
|
|
||||||
"content": item.get("content", "")
|
|
||||||
.split("描述:")[1]
|
|
||||||
.split("链接:")[0]
|
|
||||||
.replace('<mark class="highlight">', "")
|
|
||||||
.replace("</mark>", ""),
|
|
||||||
"tags": item.get("tags", []),
|
"tags": item.get("tags", []),
|
||||||
|
"channel": item.get("channel", ""),
|
||||||
|
"channel_id": item.get("channelId", ""),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return clean_results
|
return clean_results
|
||||||
|
|||||||
@ -198,7 +198,7 @@
|
|||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-2 col-form-label">服务器</label>
|
<label class="col-sm-2 col-form-label">服务器</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" v-model="formData.source.cloudsaver.server" class="form-control" placeholder="资源搜索服务器地址">
|
<input type="text" v-model="formData.source.cloudsaver.server" class="form-control" placeholder="资源搜索服务器地址,如 http://172.17.0.1:8008">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
@ -272,7 +272,7 @@
|
|||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" name="taskname[]" class="form-control" v-model="task.taskname" placeholder="必填" @focus="smart_param.showSuggestions=true;focusTaskname(index, task)" @input="changeTaskname(index, task)">
|
<input type="text" name="taskname[]" class="form-control" v-model="task.taskname" placeholder="必填" @focus="smart_param.showSuggestions=true;focusTaskname(index, task)" @input="changeTaskname(index, task)">
|
||||||
<div class="dropdown-menu show task-suggestions" v-if="smart_param.showSuggestions && smart_param.taskSuggestions.success && smart_param.index === index">
|
<div class="dropdown-menu show task-suggestions" v-if="smart_param.showSuggestions && smart_param.taskSuggestions.success && smart_param.index === index">
|
||||||
<div class="text-muted text-center" style="font-size:12px;">{{ smart_param.taskSuggestions.message ? smart_param.taskSuggestions.message : smart_param.taskSuggestions.data.length ? "以下资源来自网络公开搜索,请自行辨识,如有侵权请联系资源方" : "未搜索到资源" }}</div>
|
<div class="text-muted text-center" style="font-size:12px;">{{ smart_param.taskSuggestions.message ? smart_param.taskSuggestions.message : smart_param.taskSuggestions.data.length ? `以下资源来自 ${smart_param.taskSuggestions.source} 搜索,请自行辨识,如有侵权请联系资源方` : "未搜索到资源" }}</div>
|
||||||
<div v-for="suggestion in smart_param.taskSuggestions.data" :key="suggestion.taskname" class="dropdown-item" @click.prevent="selectSuggestion(task, suggestion)" style="cursor: pointer;font-size: 12px;" :title="suggestion.content">
|
<div v-for="suggestion in smart_param.taskSuggestions.data" :key="suggestion.taskname" class="dropdown-item" @click.prevent="selectSuggestion(task, suggestion)" style="cursor: pointer;font-size: 12px;" :title="suggestion.content">
|
||||||
<span v-html="suggestion.verify ? '✅': '❔'"></span> {{ suggestion.taskname }}
|
<span v-html="suggestion.verify ? '✅': '❔'"></span> {{ suggestion.taskname }}
|
||||||
<small class="text-muted">
|
<small class="text-muted">
|
||||||
@ -516,8 +516,8 @@
|
|||||||
origin_savepath: "",
|
origin_savepath: "",
|
||||||
taskSuggestions: {},
|
taskSuggestions: {},
|
||||||
showSuggestions: false,
|
showSuggestions: false,
|
||||||
lastSuggestionsTime: 0,
|
|
||||||
isSearching: false,
|
isSearching: false,
|
||||||
|
searchTimer: null,
|
||||||
},
|
},
|
||||||
activeTab: 'tasklist',
|
activeTab: 'tasklist',
|
||||||
configModified: false,
|
configModified: false,
|
||||||
@ -707,7 +707,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
changeTaskname(index, task) {
|
changeTaskname(index, task) {
|
||||||
this.searchSuggestions(index, task.taskname, 500);
|
if (this.smart_param.searchTimer) {
|
||||||
|
clearTimeout(this.smart_param.searchTimer);
|
||||||
|
}
|
||||||
|
this.smart_param.searchTimer = setTimeout(() => {
|
||||||
|
this.searchSuggestions(index, task.taskname, 0);
|
||||||
|
}, 1000);
|
||||||
if (this.smart_param.savepath)
|
if (this.smart_param.savepath)
|
||||||
task.savepath = this.smart_param.savepath.replace('TASKNAME', task.taskname);
|
task.savepath = this.smart_param.savepath.replace('TASKNAME', task.taskname);
|
||||||
},
|
},
|
||||||
@ -870,22 +875,16 @@
|
|||||||
task.runweek = [1, 2, 3, 4, 5, 6, 7];
|
task.runweek = [1, 2, 3, 4, 5, 6, 7];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
searchSuggestions(index, taskname, limit_msec = 0) {
|
searchSuggestions(index, taskname, deep = 1) {
|
||||||
if (taskname.length == 0)
|
if (taskname.length == 0)
|
||||||
return
|
|
||||||
if (limit_msec > 0) {
|
|
||||||
const now = Date.now();
|
|
||||||
if (now - this.smart_param.lastSuggestionsTime < limit_msec)
|
|
||||||
return;
|
return;
|
||||||
this.smart_param.lastSuggestionsTime = now;
|
this.smart_param.isSearching = true;
|
||||||
}
|
|
||||||
this.smart_param.isSearching = true
|
|
||||||
this.smart_param.index = index;
|
this.smart_param.index = index;
|
||||||
try {
|
try {
|
||||||
axios.get('/task_suggestions', {
|
axios.get('/task_suggestions', {
|
||||||
params: {
|
params: {
|
||||||
q: taskname,
|
q: taskname,
|
||||||
d: limit_msec == 0 ? 1 : 0
|
d: deep
|
||||||
}
|
}
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
this.smart_param.taskSuggestions = response.data;
|
this.smart_param.taskSuggestions = response.data;
|
||||||
|
|||||||
@ -17,6 +17,10 @@ import requests
|
|||||||
import importlib
|
import importlib
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
# ========== 修改内容开始 ==========
|
||||||
|
MAX_SAVE_FILES = 0 # 最大保存文件数量,0 为不限制保存数量
|
||||||
|
# ========== 修改内容结束 ==========
|
||||||
|
|
||||||
# 兼容青龙
|
# 兼容青龙
|
||||||
try:
|
try:
|
||||||
from treelib import Tree
|
from treelib import Tree
|
||||||
@ -402,9 +406,20 @@ class Quark:
|
|||||||
"__dt": int(random.uniform(1, 5) * 60 * 1000),
|
"__dt": int(random.uniform(1, 5) * 60 * 1000),
|
||||||
"__t": datetime.now().timestamp(),
|
"__t": datetime.now().timestamp(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ========== 修改内容开始 ==========
|
||||||
|
# 当 MAX_SAVE_FILES = 0 时,不限制保存文件数量
|
||||||
|
if MAX_SAVE_FILES > 0:
|
||||||
|
files_to_save = fid_list[:MAX_SAVE_FILES]
|
||||||
|
tokens_to_save = fid_token_list[:MAX_SAVE_FILES]
|
||||||
|
else:
|
||||||
|
files_to_save = fid_list
|
||||||
|
tokens_to_save = fid_token_list
|
||||||
|
# ========== 修改内容结束 ==========
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"fid_list": fid_list,
|
"fid_list": files_to_save, # 修改为 files_to_save
|
||||||
"fid_token_list": fid_token_list,
|
"fid_token_list": tokens_to_save, # 修改为 tokens_to_save
|
||||||
"to_pdir_fid": to_pdir_fid,
|
"to_pdir_fid": to_pdir_fid,
|
||||||
"pwd_id": pwd_id,
|
"pwd_id": pwd_id,
|
||||||
"stoken": stoken,
|
"stoken": stoken,
|
||||||
@ -743,6 +758,12 @@ class Quark:
|
|||||||
if share_file["fid"] == task.get("startfid", ""):
|
if share_file["fid"] == task.get("startfid", ""):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# ========== 修改内容开始 ==========
|
||||||
|
# 当 MAX_SAVE_FILES = 0 时,不限制保存文件数量
|
||||||
|
if MAX_SAVE_FILES > 0:
|
||||||
|
need_save_list = need_save_list[:MAX_SAVE_FILES]
|
||||||
|
# ========== 修改内容结束 ==========
|
||||||
|
|
||||||
fid_list = [item["fid"] for item in need_save_list]
|
fid_list = [item["fid"] for item in need_save_list]
|
||||||
fid_token_list = [item["share_fid_token"] for item in need_save_list]
|
fid_token_list = [item["share_fid_token"] for item in need_save_list]
|
||||||
if fid_list:
|
if fid_list:
|
||||||
@ -884,6 +905,11 @@ def do_save(account, tasklist=[]):
|
|||||||
# 获取全部保存目录fid
|
# 获取全部保存目录fid
|
||||||
account.update_savepath_fid(tasklist)
|
account.update_savepath_fid(tasklist)
|
||||||
|
|
||||||
|
# ========== 修改内容开始 ==========
|
||||||
|
# 初始化计数器
|
||||||
|
total_files_transferred = 0 # 无论 MAX_SAVE_FILES 的值如何,都初始化计数器
|
||||||
|
# ========== 修改内容结束 ==========
|
||||||
|
|
||||||
def check_date(task):
|
def check_date(task):
|
||||||
return (
|
return (
|
||||||
not task.get("enddate")
|
not task.get("enddate")
|
||||||
@ -901,6 +927,12 @@ def do_save(account, tasklist=[]):
|
|||||||
for index, task in enumerate(tasklist):
|
for index, task in enumerate(tasklist):
|
||||||
# 判断任务期限
|
# 判断任务期限
|
||||||
if check_date(task):
|
if check_date(task):
|
||||||
|
# ========== 修改内容开始 ==========
|
||||||
|
# 当 MAX_SAVE_FILES > 0 时,检查是否已转存超过限制
|
||||||
|
if MAX_SAVE_FILES > 0 and total_files_transferred >= MAX_SAVE_FILES:
|
||||||
|
print("⚠️ 已达到转存文件总数上限,停止转存任务")
|
||||||
|
break
|
||||||
|
# ========== 修改内容结束 ==========
|
||||||
print()
|
print()
|
||||||
print(f"#{index+1}------------------")
|
print(f"#{index+1}------------------")
|
||||||
print(f"任务名称: {task['taskname']}")
|
print(f"任务名称: {task['taskname']}")
|
||||||
@ -920,6 +952,13 @@ def do_save(account, tasklist=[]):
|
|||||||
is_new_tree = account.do_save_task(task)
|
is_new_tree = account.do_save_task(task)
|
||||||
is_rename = account.do_rename_task(task)
|
is_rename = account.do_rename_task(task)
|
||||||
|
|
||||||
|
# ========== 修改内容开始 ==========
|
||||||
|
# 当 MAX_SAVE_FILES > 0 时,更新计数器
|
||||||
|
if MAX_SAVE_FILES > 0 and (is_new_tree or is_rename):
|
||||||
|
total_files_transferred += 1 # 每成功转存或重命名一个文件,计数器加1
|
||||||
|
# ========== 修改内容结束 ==========
|
||||||
|
|
||||||
|
|
||||||
# 补充任务的插件配置
|
# 补充任务的插件配置
|
||||||
def merge_dicts(a, b):
|
def merge_dicts(a, b):
|
||||||
result = a.copy()
|
result = a.copy()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user