mirror of
https://github.com/Cp0204/quark-auto-save.git
synced 2026-01-12 23:30:44 +08:00
Compare commits
7 Commits
21ee9dab48
...
5e8ecd4052
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e8ecd4052 | ||
|
|
3c4b92160d | ||
|
|
30a0d07b1a | ||
|
|
9593ec4811 | ||
|
|
a59af79423 | ||
|
|
7d1552eeca | ||
|
|
d05db559ab |
@ -110,7 +110,7 @@ services:
|
||||
| ---------------- | ---------- | -------- |
|
||||
| `WEBUI_USERNAME` | `admin` | 管理账号 |
|
||||
| `WEBUI_PASSWORD` | `admin123` | 管理密码 |
|
||||
| `PLUGIN_FLAGS` | | 插件标志,示例使用 `-emby,-aria2` 来关闭插件 |
|
||||
| `PLUGIN_FLAGS` | | 插件标志,如 `-emby,-aria2` 禁用某些插件 |
|
||||
|
||||
#### 一键更新
|
||||
|
||||
|
||||
21
app/run.py
21
app/run.py
@ -15,8 +15,10 @@ from flask import (
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
import subprocess
|
||||
import requests
|
||||
import hashlib
|
||||
import logging
|
||||
import base64
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
@ -139,7 +141,9 @@ def logout():
|
||||
def index():
|
||||
if not is_login():
|
||||
return redirect(url_for("login"))
|
||||
return render_template("index.html", version=app.config["APP_VERSION"], plugin_flags=PLUGIN_FLAGS)
|
||||
return render_template(
|
||||
"index.html", version=app.config["APP_VERSION"], plugin_flags=PLUGIN_FLAGS
|
||||
)
|
||||
|
||||
|
||||
# 获取配置数据
|
||||
@ -212,6 +216,21 @@ def run_script_now():
|
||||
)
|
||||
|
||||
|
||||
@app.route("/task_suggestions")
|
||||
def get_task_suggestions():
|
||||
if not is_login():
|
||||
return jsonify({"error": "未登录"})
|
||||
base_url = base64.b64decode("aHR0cHM6Ly9zLjkxNzc4OC54eXo=").decode()
|
||||
query = request.args.get("q", "").lower()
|
||||
deep = request.args.get("d", "").lower()
|
||||
url = f"{base_url}/task_suggestions?q={query}&d={deep}"
|
||||
try:
|
||||
response = requests.get(url)
|
||||
return jsonify(response.json())
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)})
|
||||
|
||||
|
||||
@app.route("/get_share_detail")
|
||||
def get_share_files():
|
||||
if not is_login():
|
||||
|
||||
@ -36,6 +36,16 @@
|
||||
max-height: calc(100vh - 200px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.task-suggestions {
|
||||
width: 100%;
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
transform: translate(0, -100%);
|
||||
top: 0;
|
||||
margin-top: -5px;
|
||||
border: 1px solid #007bff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@ -176,10 +186,23 @@
|
||||
<label class="col-sm-2 col-form-label">任务名称</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group">
|
||||
<input type="text" name="taskname[]" class="form-control" v-model="task.taskname" placeholder="必填">
|
||||
<div class="input-group-append" v-if="task.taskname">
|
||||
<div class="input-group-text">
|
||||
<a target="_blank" :href="`https://www.google.com/search?q=%22pan.quark%22+${task.taskname}`"><i class="bi bi-search"></i></a>
|
||||
<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.length && smart_param.index === index">
|
||||
<div class="text-muted text-center" style="font-size: small;">以下资源来自第三方,网络公开搜集,请自行辨识,如有侵权请联系夸克官方</div>
|
||||
<div v-for="suggestion in smart_param.taskSuggestions" :key="suggestion.taskname" class="dropdown-item" @click.prevent="selectSuggestion(task, suggestion)" style="cursor: pointer;">
|
||||
<span v-html="suggestion.verify ? '✅': '❔'"></span> {{ suggestion.taskname }}
|
||||
<small class="text-muted">
|
||||
<a :href="suggestion.shareurl" target="_blank" @click.stop>{{ suggestion.shareurl }}</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group-append" title="深度搜索">
|
||||
<button class="btn btn-primary" type="button" @click="searchSuggestions(index, task.taskname)">
|
||||
<i v-if="smart_param.isSearching && smart_param.index === index" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></i>
|
||||
<i v-else class="bi bi-search-heart"></i>
|
||||
</button>
|
||||
<div class="input-group-text" title="谷歌搜索">
|
||||
<a target="_blank" :href="`https://www.google.com/search?q=%22pan.quark.cn/s%22+${task.taskname}`"><i class="bi bi-google"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -202,8 +225,10 @@
|
||||
<label class="col-sm-2 col-form-label">保存路径</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group">
|
||||
<input type="text" name="savepath[]" class="form-control" v-model="task.savepath" placeholder="必填">
|
||||
<input type="text" name="savepath[]" class="form-control" v-model="task.savepath" placeholder="必填" @focus="focusTaskname(index, task)">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-secondary" type="button" v-if="smart_param.savepath && smart_param.index == index && task.savepath != smart_param.origin_savepath" @click="task.savepath = smart_param.origin_savepath"><i class="
|
||||
bi bi-reply"></i></button>
|
||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" @click="getSavepathDirs(task.savepath)" data-toggle="dropdown" aria-expanded="false">选择</button>
|
||||
<div class="dropdown-menu" style="max-height: 300px; overflow-y: auto;">
|
||||
<a class="dropdown-item" @click.stop.prevent="selectSavepath(index,getParentDirectory(task.savepath),'..')" href="#">..</a>
|
||||
@ -391,7 +416,7 @@
|
||||
newTask: {
|
||||
taskname: "",
|
||||
shareurl: "",
|
||||
savepath: "",
|
||||
savepath: "/",
|
||||
pattern: "",
|
||||
replace: "",
|
||||
enddate: "",
|
||||
@ -406,7 +431,16 @@
|
||||
savepaths: [],
|
||||
modalLoading: false,
|
||||
shareFiles: [],
|
||||
forceTaskIndex: null
|
||||
forceTaskIndex: null,
|
||||
smart_param: {
|
||||
index: null,
|
||||
savepath: "",
|
||||
origin_savepath: "",
|
||||
taskSuggestions: [],
|
||||
showSuggestions: false,
|
||||
lastSuggestionsTime: 0,
|
||||
isSearching: false,
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
ts2date: function (value) {
|
||||
@ -429,6 +463,11 @@
|
||||
this.checkNewVersion();
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
document.addEventListener('keydown', this.handleKeyDown);
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!e.target.closest('.input-group')) {
|
||||
this.smart_param.showSuggestions = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
checkNewVersion() {
|
||||
@ -510,12 +549,18 @@
|
||||
},
|
||||
addTask() {
|
||||
newTask = { ...this.newTask }
|
||||
newTask.taskname = this.taskNameFilter
|
||||
lastTask = this.formData.tasklist[this.formData.tasklist.length - 1]
|
||||
if (this.formData.tasklist.length > 0 && lastTask.taskname) {
|
||||
newTask.savepath = lastTask.savepath.replace(lastTask.taskname, 'TASKNAME')
|
||||
} else {
|
||||
newTask.savepath = this.taskDirSelected + "/" + newTask.taskname
|
||||
newTask.taskname = this.taskNameFilter;
|
||||
if (this.formData.tasklist.length > 0) {
|
||||
lastTask = this.formData.tasklist[this.formData.tasklist.length - 1];
|
||||
if (this.taskDirSelected) {
|
||||
newTask.savepath = this.taskDirSelected + '/TASKNAME';
|
||||
} else {
|
||||
if (newTask.taskname) {
|
||||
newTask.savepath = lastTask.savepath.replace(lastTask.taskname, newTask.taskname);
|
||||
} else {
|
||||
newTask.savepath = lastTask.taskname ? lastTask.savepath.replace(lastTask.taskname, 'TASKNAME') : lastTask.savepath;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.formData.tasklist.push(newTask);
|
||||
// 滚到最下
|
||||
@ -525,6 +570,23 @@
|
||||
});
|
||||
}, 1);
|
||||
},
|
||||
focusTaskname(index, task) {
|
||||
this.smart_param.index = index
|
||||
this.smart_param.origin_savepath = task.savepath
|
||||
regex = new RegExp(`/${task.taskname.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(/|$)`)
|
||||
if (task.savepath.includes('TASKNAME')) {
|
||||
this.smart_param.savepath = task.savepath;
|
||||
} else if (task.savepath.match(regex)) {
|
||||
this.smart_param.savepath = task.savepath.replace(task.taskname, 'TASKNAME');
|
||||
} else {
|
||||
this.smart_param.savepath = undefined;
|
||||
}
|
||||
},
|
||||
changeTaskname(index, task) {
|
||||
this.searchSuggestions(index, task.taskname, 500);
|
||||
if (this.smart_param.savepath)
|
||||
task.savepath = this.smart_param.savepath.replace('TASKNAME', task.taskname);
|
||||
},
|
||||
removeTask(index) {
|
||||
if (confirm("确认删除任务 [#" + (index + 1) + ": " + this.formData.tasklist[index].taskname + "] 吗?"))
|
||||
this.formData.tasklist.splice(index, 1);
|
||||
@ -665,7 +727,38 @@
|
||||
} else {
|
||||
task.runweek = [1, 2, 3, 4, 5, 6, 7];
|
||||
}
|
||||
}
|
||||
},
|
||||
searchSuggestions(index, taskname, limit_msec = 0) {
|
||||
if (taskname.length == 0)
|
||||
return
|
||||
if (limit_msec > 0) {
|
||||
const now = Date.now();
|
||||
if (now - this.smart_param.lastSuggestionsTime < limit_msec)
|
||||
return;
|
||||
this.smart_param.lastSuggestionsTime = now;
|
||||
}
|
||||
this.smart_param.isSearching = true
|
||||
this.smart_param.index = index;
|
||||
axios.get('/task_suggestions', {
|
||||
params: {
|
||||
q: taskname,
|
||||
d: limit_msec == 0 ? 1 : 0
|
||||
}
|
||||
}).then(response => {
|
||||
this.smart_param.taskSuggestions = response.data;
|
||||
this.smart_param.showSuggestions = true;
|
||||
}).catch(error => {
|
||||
console.error('Error fetching suggestions:', error);
|
||||
}).finally(() => {
|
||||
this.smart_param.isSearching = false;
|
||||
});
|
||||
},
|
||||
selectSuggestion(task, suggestion) {
|
||||
task.taskname = suggestion.taskname;
|
||||
task.shareurl = suggestion.shareurl;
|
||||
this.changeShareurl(task);
|
||||
this.smart_param.showSuggestions = false;
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user