aa
This commit is contained in:
52
app_web.py
52
app_web.py
@@ -801,6 +801,58 @@ async def save_config(request: Request):
|
||||
return RedirectResponse(url=app_home_url(), status_code=303)
|
||||
|
||||
|
||||
def _logs_tail(n: int = 50) -> List[str]:
|
||||
return list(service.logs)[-n:] if service.logs else []
|
||||
|
||||
|
||||
@app.post("/api/session/init")
|
||||
async def api_session_init(request: Request):
|
||||
"""JSON 初始化:便于面板内展示结果,避免仅依赖 303 与整页刷新排错。"""
|
||||
denied = json_if_console_unauthed(request)
|
||||
if denied:
|
||||
return denied
|
||||
try:
|
||||
await service.ensure_ready()
|
||||
return {
|
||||
"ok": True,
|
||||
"connected": service.is_connected(),
|
||||
"message": "Telegram 客户端已就绪。",
|
||||
"logs_tail": _logs_tail(50),
|
||||
}
|
||||
except Exception as e:
|
||||
msg = str(e)
|
||||
service._append(f"初始化失败:{msg}")
|
||||
return {
|
||||
"ok": False,
|
||||
"connected": service.is_connected(),
|
||||
"error": msg,
|
||||
"logs_tail": _logs_tail(50),
|
||||
}
|
||||
|
||||
|
||||
@app.post("/api/session/disconnect")
|
||||
async def api_session_disconnect(request: Request):
|
||||
denied = json_if_console_unauthed(request)
|
||||
if denied:
|
||||
return denied
|
||||
try:
|
||||
await service.disconnect()
|
||||
return {
|
||||
"ok": True,
|
||||
"connected": service.is_connected(),
|
||||
"message": "已断开 Telegram。",
|
||||
"logs_tail": _logs_tail(50),
|
||||
}
|
||||
except Exception as e:
|
||||
service._append(f"断开失败:{e}")
|
||||
return {
|
||||
"ok": False,
|
||||
"connected": service.is_connected(),
|
||||
"error": str(e),
|
||||
"logs_tail": _logs_tail(50),
|
||||
}
|
||||
|
||||
|
||||
@app.post("/start")
|
||||
async def start_scraper(request: Request):
|
||||
redir = redirect_if_console_unauthed(request)
|
||||
|
||||
@@ -868,13 +868,18 @@
|
||||
{% if error %}
|
||||
<p class="alert-warn" role="alert">客户端:{{ error }}</p>
|
||||
{% endif %}
|
||||
<p class="hint" style="margin-bottom:12px;">
|
||||
初始化可能较慢(网络、扫码登录等)。结果会显示在下方灰色框内,无需只看浏览器网络里的 303;
|
||||
无头登录请开 <code>TELEGRAM_HEADLESS_QR=1</code> 并在<strong>运行日志</strong>中打开二维码链接。
|
||||
</p>
|
||||
<div id="conn-action-result" class="list" style="display:none;margin-bottom:14px;max-height:200px;font-size:0.8125rem;" role="status" aria-live="polite"></div>
|
||||
<div class="btn-row">
|
||||
<form method="post" action="{{ app_url('/start') }}">
|
||||
<button class="btn-primary" type="submit">初始化 / 连接 Telegram</button>
|
||||
</form>
|
||||
<form method="post" action="{{ app_url('/stop') }}">
|
||||
<button class="btn-danger" type="submit">断开 Telegram</button>
|
||||
</form>
|
||||
<div>
|
||||
<button class="btn-primary" type="button" id="btn-session-init">初始化 / 连接 Telegram</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn-danger" type="button" id="btn-session-disconnect">断开 Telegram</button>
|
||||
</div>
|
||||
<form method="post" action="{{ app_url('/jobs/continuous/start') }}">
|
||||
<button class="btn-primary" type="submit">启动持续抓取(含心跳)</button>
|
||||
</form>
|
||||
@@ -1401,6 +1406,140 @@
|
||||
|
||||
setInterval(refreshStatus, 3000);
|
||||
|
||||
(function () {
|
||||
var initBtn = document.getElementById("btn-session-init");
|
||||
var discBtn = document.getElementById("btn-session-disconnect");
|
||||
var out = document.getElementById("conn-action-result");
|
||||
if (!initBtn || !out) return;
|
||||
|
||||
function showConnResult(html, isErr) {
|
||||
out.style.display = "block";
|
||||
out.innerHTML = html;
|
||||
out.style.borderColor = isErr ? "rgba(239,68,68,0.45)" : "rgba(34,197,94,0.35)";
|
||||
}
|
||||
|
||||
function renderInitPayload(data, httpStatus) {
|
||||
var ok = data && data.ok === true;
|
||||
var lines = [];
|
||||
if (ok) {
|
||||
lines.push(
|
||||
"<p class=\"line\" style=\"margin:0 0 8px;color:#86efac;font-weight:600;\">成功:" +
|
||||
escapeHtml(data.message || "已就绪") +
|
||||
"</p>"
|
||||
);
|
||||
lines.push(
|
||||
"<p class=\"line\" style=\"margin:0 0 4px;color:#94a3b8;\">连接状态:" +
|
||||
(data.connected ? "已连接" : "未连接(请查看日志)") +
|
||||
"</p>"
|
||||
);
|
||||
} else {
|
||||
var errText =
|
||||
(data && data.error) ||
|
||||
(httpStatus && httpStatus !== 200 ? "HTTP " + httpStatus : "") ||
|
||||
"未知错误";
|
||||
lines.push(
|
||||
"<p class=\"line\" style=\"margin:0 0 8px;color:#fca5a5;font-weight:600;\">失败:" +
|
||||
escapeHtml(String(errText)) +
|
||||
"</p>"
|
||||
);
|
||||
lines.push(
|
||||
"<p class=\"line\" style=\"margin:0 0 4px;color:#94a3b8;\">连接状态:" +
|
||||
(data && data.connected ? "已连接" : "未连接") +
|
||||
"</p>"
|
||||
);
|
||||
}
|
||||
if (data && data.logs_tail && data.logs_tail.length) {
|
||||
lines.push(
|
||||
"<pre style=\"margin:8px 0 0;font-size:0.75rem;color:#bae6fd;white-space:pre-wrap;word-break:break-word;\">" +
|
||||
escapeHtml(data.logs_tail.join("\n")) +
|
||||
"</pre>"
|
||||
);
|
||||
}
|
||||
return { html: lines.join(""), isErr: !ok };
|
||||
}
|
||||
|
||||
initBtn.addEventListener("click", async function () {
|
||||
initBtn.disabled = true;
|
||||
if (discBtn) discBtn.disabled = true;
|
||||
showConnResult("<p class=\"line\" style=\"margin:0;color:#94a3b8;\">正在连接,请稍候(扫码场景可能需数分钟)…</p>", false);
|
||||
try {
|
||||
var res = await fetch(appPath("/api/session/init"), {
|
||||
method: "POST",
|
||||
credentials: "same-origin",
|
||||
headers: { Accept: "application/json" },
|
||||
});
|
||||
var data = await res.json().catch(function () {
|
||||
return {};
|
||||
});
|
||||
var r = renderInitPayload(data, res.status);
|
||||
showConnResult(r.html, r.isErr);
|
||||
await refreshStatus();
|
||||
} catch (e) {
|
||||
showConnResult(
|
||||
"<p class=\"line\" style=\"margin:0;color:#fca5a5;\">请求失败:" +
|
||||
escapeHtml(e && e.message ? e.message : String(e)) +
|
||||
"</p>",
|
||||
true
|
||||
);
|
||||
} finally {
|
||||
initBtn.disabled = false;
|
||||
if (discBtn) discBtn.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (discBtn) {
|
||||
discBtn.addEventListener("click", async function () {
|
||||
initBtn.disabled = true;
|
||||
discBtn.disabled = true;
|
||||
showConnResult("<p class=\"line\" style=\"margin:0;color:#94a3b8;\">正在断开…</p>", false);
|
||||
try {
|
||||
var res = await fetch(appPath("/api/session/disconnect"), {
|
||||
method: "POST",
|
||||
credentials: "same-origin",
|
||||
headers: { Accept: "application/json" },
|
||||
});
|
||||
var data = await res.json().catch(function () {
|
||||
return {};
|
||||
});
|
||||
var ok = data && data.ok === true;
|
||||
var lines = [];
|
||||
if (ok) {
|
||||
lines.push(
|
||||
"<p class=\"line\" style=\"margin:0 0 8px;color:#86efac;font-weight:600;\">" +
|
||||
escapeHtml(data.message || "已断开") +
|
||||
"</p>"
|
||||
);
|
||||
} else {
|
||||
lines.push(
|
||||
"<p class=\"line\" style=\"margin:0;color:#fca5a5;font-weight:600;\">失败:" +
|
||||
escapeHtml((data && data.error) || "未知错误") +
|
||||
"</p>"
|
||||
);
|
||||
}
|
||||
if (data && data.logs_tail && data.logs_tail.length) {
|
||||
lines.push(
|
||||
"<pre style=\"margin:8px 0 0;font-size:0.75rem;color:#bae6fd;white-space:pre-wrap;word-break:break-word;\">" +
|
||||
escapeHtml(data.logs_tail.join("\n")) +
|
||||
"</pre>"
|
||||
);
|
||||
}
|
||||
showConnResult(lines.join(""), !ok);
|
||||
await refreshStatus();
|
||||
} catch (e) {
|
||||
showConnResult(
|
||||
"<p class=\"line\" style=\"margin:0;color:#fca5a5;\">请求失败:" +
|
||||
escapeHtml(e && e.message ? e.message : String(e)) +
|
||||
"</p>",
|
||||
true
|
||||
);
|
||||
} finally {
|
||||
initBtn.disabled = false;
|
||||
discBtn.disabled = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
(function () {
|
||||
var form = document.querySelector(".account-pick-form");
|
||||
if (!form) return;
|
||||
|
||||
Reference in New Issue
Block a user