mirror of
https://github.com/Cp0204/quark-auto-save.git
synced 2026-01-12 07:10:44 +08:00
🎨 运行日志流式输出
This commit is contained in:
parent
8e9451d3e9
commit
a9a9fe3e99
31
app/run.py
31
app/run.py
@ -2,14 +2,15 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from flask import (
|
from flask import (
|
||||||
Flask,
|
Flask,
|
||||||
render_template,
|
|
||||||
request,
|
|
||||||
redirect,
|
|
||||||
url_for,
|
url_for,
|
||||||
session,
|
session,
|
||||||
jsonify,
|
jsonify,
|
||||||
send_from_directory,
|
request,
|
||||||
|
redirect,
|
||||||
Response,
|
Response,
|
||||||
|
render_template,
|
||||||
|
send_from_directory,
|
||||||
|
stream_with_context,
|
||||||
)
|
)
|
||||||
from apscheduler.schedulers.background import BackgroundScheduler
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
from apscheduler.triggers.cron import CronTrigger
|
from apscheduler.triggers.cron import CronTrigger
|
||||||
@ -140,13 +141,12 @@ def update():
|
|||||||
|
|
||||||
|
|
||||||
# 处理运行脚本请求
|
# 处理运行脚本请求
|
||||||
@app.route("/run_script_now", methods=["POST"])
|
@app.route("/run_script_now", methods=["GET"])
|
||||||
def run_script_now():
|
def run_script_now():
|
||||||
if not is_login():
|
if not is_login():
|
||||||
return "未登录"
|
return "未登录"
|
||||||
payload = request.json
|
task_index = request.args.get("task_index", "")
|
||||||
task_index = str(payload.get("task_index", ""))
|
command = [python_path, "-u", script_path, config_path, task_index]
|
||||||
command = [python_path, script_path, config_path, task_index]
|
|
||||||
|
|
||||||
def generate_output():
|
def generate_output():
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
@ -154,11 +154,20 @@ def run_script_now():
|
|||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
universal_newlines=True,
|
universal_newlines=True,
|
||||||
|
bufsize=1,
|
||||||
)
|
)
|
||||||
for line in process.stdout:
|
try:
|
||||||
yield line
|
for line in iter(process.stdout.readline, ""):
|
||||||
|
yield f"data: {line}\n\n"
|
||||||
|
yield "data: [DONE]\n\n"
|
||||||
|
finally:
|
||||||
|
process.stdout.close()
|
||||||
|
process.wait()
|
||||||
|
|
||||||
return Response(generate_output(), mimetype="text/plain")
|
return Response(
|
||||||
|
stream_with_context(generate_output()),
|
||||||
|
content_type="text/event-stream;charset=utf-8",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# 定时任务执行的函数
|
# 定时任务执行的函数
|
||||||
|
|||||||
@ -26,6 +26,11 @@
|
|||||||
.title {
|
.title {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
max-height: calc(100vh - 200px);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -230,7 +235,8 @@
|
|||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title">执行日志</h5>
|
<h5 class="modal-title">运行日志 <div v-if="modalLoading" class="spinner-border spinner-border-sm m-1" role="status"></div>
|
||||||
|
</h5>
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
@ -280,7 +286,8 @@
|
|||||||
run_log: "",
|
run_log: "",
|
||||||
taskDirs: [""],
|
taskDirs: [""],
|
||||||
taskDirSelected: "",
|
taskDirSelected: "",
|
||||||
taskNameFilter: ""
|
taskNameFilter: "",
|
||||||
|
modalLoading: false
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'formData.push_config': {
|
'formData.push_config': {
|
||||||
@ -380,17 +387,27 @@
|
|||||||
},
|
},
|
||||||
runScriptNow(task_index = "") {
|
runScriptNow(task_index = "") {
|
||||||
$('#logModal').modal('toggle')
|
$('#logModal').modal('toggle')
|
||||||
this.run_log = '<div class="spinner-border" role="status"></div> 请耐心等待脚本全部执行完毕...'
|
this.modalLoading = true
|
||||||
axios.post('/run_script_now', {
|
this.run_log = ''
|
||||||
task_index: task_index,
|
const source = new EventSource(`/run_script_now?task_index=${task_index}`);
|
||||||
})
|
source.onmessage = (event) => {
|
||||||
.then(response => {
|
if (event.data == "[DONE]") {
|
||||||
this.run_log = response.data;
|
this.modalLoading = false
|
||||||
})
|
source.close();
|
||||||
.catch(error => {
|
} else {
|
||||||
this.run_log = "错误:\n" + error;
|
this.run_log += event.data + '\n';
|
||||||
console.error('Error:', error);
|
// 在更新 run_log 后将滚动条滚动到底部
|
||||||
});
|
this.$nextTick(() => {
|
||||||
|
const modalBody = document.querySelector('.modal-body');
|
||||||
|
modalBody.scrollTop = modalBody.scrollHeight;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
source.onerror = (error) => {
|
||||||
|
this.modalLoading = false
|
||||||
|
console.error('Error:', error);
|
||||||
|
source.close();
|
||||||
|
};
|
||||||
},
|
},
|
||||||
getParentDirectory(path) {
|
getParentDirectory(path) {
|
||||||
parentDir = path.substring(0, path.lastIndexOf('/'))
|
parentDir = path.substring(0, path.lastIndexOf('/'))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user