Commit 7295d704 authored by 郭阔's avatar 郭阔

feat: recipe discovery for source-less sites

- platform.sh nh_login_autodiscover: no installed source for the site
  (bloomberg/statista) exports NH_LOGIN_URL from the credential's url
- web: site rows without sources can run 自动配置配方/登录测试 (probe
  falls back to site name); credential url serves as discovery entry
parent a17c0314
...@@ -440,6 +440,12 @@ nh_login_autodiscover() { # <source> 自动发现登录流程生成配方,并 ...@@ -440,6 +440,12 @@ nh_login_autodiscover() { # <source> 自动发现登录流程生成配方,并
nh_ensure_instance "$source" nh_ensure_instance "$source"
export NH_LOGIN_USER="$(jq -r '.user // empty' "$creds" 2>/dev/null)" export NH_LOGIN_USER="$(jq -r '.user // empty' "$creds" 2>/dev/null)"
export NH_LOGIN_PASS="$(jq -r '.password // empty' "$creds" 2>/dev/null)" export NH_LOGIN_PASS="$(jq -r '.password // empty' "$creds" 2>/dev/null)"
# 未接入源的站点(bloomberg/statista 等)没有 homepageUrl:用凭据里的首页作发现入口
if ! jq -e --arg s "$source" '.sources[]? | select(.id == $s and .homepageUrl) | 1' \
"$tools_dir/config.json" >/dev/null 2>&1; then
NH_LOGIN_URL="$(jq -r '.url // empty' "$creds" 2>/dev/null)"
[ -n "$NH_LOGIN_URL" ] && export NH_LOGIN_URL
fi
(cd "$tools_dir" && node scripts/login-tools.js discover "$source") (cd "$tools_dir" && node scripts/login-tools.js discover "$source")
} }
......
...@@ -973,11 +973,11 @@ _login_test = {} # {site: {"running": bool, "done": bool, "rc": int, "output": ...@@ -973,11 +973,11 @@ _login_test = {} # {site: {"running": bool, "done": bool, "rc": int, "output":
def _site_probe_source(site): def _site_probe_source(site):
"""该站点的代表源(自动配方/登录测试的浏览器入口);未接入源返回 ''。""" """该站点的探测入口:优先取已接入源,无源站点回退站点名(凭据首页作发现入口)。"""
for row in pl.login_rows(): for row in pl.login_rows():
if row["site"] == site: if row["site"] == site:
return row["probe_source"] return row["probe_source"] or site
return "" return site
@app.route("/logins") @app.route("/logins")
...@@ -1031,9 +1031,6 @@ def login_discover(site): ...@@ -1031,9 +1031,6 @@ def login_discover(site):
flash(f"站点 {site} 未配置凭据,请先在下方表单保存", "error") flash(f"站点 {site} 未配置凭据,请先在下方表单保存", "error")
return redirect(url_for("login_list")) return redirect(url_for("login_list"))
probe = _site_probe_source(site) probe = _site_probe_source(site)
if not probe:
flash(f"站点 {site} 尚未接入任何数据源,先在「栏目管理」添加 {site}-* 源后再自动配置配方", "error")
return redirect(url_for("login_list"))
with _login_test_lock: with _login_test_lock:
if _login_test.get(site, {}).get("running"): if _login_test.get(site, {}).get("running"):
flash(f"站点 {site} 已有登录测试在运行", "error") flash(f"站点 {site} 已有登录测试在运行", "error")
...@@ -1051,7 +1048,7 @@ def login_discover(site): ...@@ -1051,7 +1048,7 @@ def login_discover(site):
} }
threading.Thread(target=_run, daemon=True).start() threading.Thread(target=_run, daemon=True).start()
flash(f"站点 {site} 自动配置配方并测试已启动(经 {probe} 探测,约 30-90 秒,页面自动刷新)", "success") flash(f"站点 {site} 自动配置配方并测试已启动(入口 {probe},约 30-120 秒,页面自动刷新)", "success")
return redirect(url_for("login_list")) return redirect(url_for("login_list"))
...@@ -1062,9 +1059,6 @@ def login_test(site): ...@@ -1062,9 +1059,6 @@ def login_test(site):
if not re.match(r"^[a-zA-Z0-9_-]+$", site): if not re.match(r"^[a-zA-Z0-9_-]+$", site):
abort(404) abort(404)
probe = _site_probe_source(site) probe = _site_probe_source(site)
if not probe:
flash(f"站点 {site} 尚未接入任何数据源,无法测试", "error")
return redirect(url_for("login_list"))
with _login_test_lock: with _login_test_lock:
if _login_test.get(site, {}).get("running"): if _login_test.get(site, {}).get("running"):
flash(f"站点 {site} 登录测试已在运行", "error") flash(f"站点 {site} 登录测试已在运行", "error")
...@@ -1082,7 +1076,7 @@ def login_test(site): ...@@ -1082,7 +1076,7 @@ def login_test(site):
} }
threading.Thread(target=_run, daemon=True).start() threading.Thread(target=_run, daemon=True).start()
flash(f"站点 {site} 登录测试已启动(经 {probe} 频道,约 10-60 秒,页面自动刷新显示结果)", "success") flash(f"站点 {site} 登录测试已启动(入口 {probe},约 10-60 秒,页面自动刷新显示结果)", "success")
return redirect(url_for("login_list")) return redirect(url_for("login_list"))
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
{% if r.sources %} {% if r.sources %}
{% for s in r.sources %}<code style="margin-right:4px">{{ s }}</code>{% endfor %} {% for s in r.sources %}<code style="margin-right:4px">{{ s }}</code>{% endfor %}
{% else %} {% else %}
<span class="badge unknown">未接入源(先在栏目管理添加 {{ r.site }}-* 源)</span> <span class="badge unknown">未接入源(配方与凭据先行,装源后直接生效)</span>
{% endif %} {% endif %}
</td> </td>
<td> <td>
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
<form method="POST" action="{{ url_for('login_test', site=r.site) }}" style="display:inline"> <form method="POST" action="{{ url_for('login_test', site=r.site) }}" style="display:inline">
<button type="submit" class="btn btn-sm" {% if st and st.running %}disabled{% endif %}>测试登录</button> <button type="submit" class="btn btn-sm" {% if st and st.running %}disabled{% endif %}>测试登录</button>
</form> </form>
{% elif r.configured and r.probe_source %} {% elif r.configured %}
<form method="POST" action="{{ url_for('login_discover', site=r.site) }}" style="display:inline" <form method="POST" action="{{ url_for('login_discover', site=r.site) }}" style="display:inline"
onsubmit="return confirm('自动识别 {{ r.site }} 的登录流程并生成站点级配方,随后立即用凭据实登验证?')"> onsubmit="return confirm('自动识别 {{ r.site }} 的登录流程并生成站点级配方,随后立即用凭据实登验证?')">
<button type="submit" class="btn btn-sm btn-primary" {% if st and st.running %}disabled{% endif %}>自动配置配方并测试</button> <button type="submit" class="btn btn-sm btn-primary" {% if st and st.running %}disabled{% endif %}>自动配置配方并测试</button>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment