feat: 添加账号支持选择学习平台
账号新增 platform 字段,登录/刷新课程/发现课程按平台分发;同时把 JS 脚本收进 script/(目录规范调整)。
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
"""账号 / 登录 / 登录记录接口。"""
|
||||
import time
|
||||
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from study_tool.webapp import app
|
||||
|
||||
from study_tool import store
|
||||
from study_tool.config import *
|
||||
from study_tool.models import *
|
||||
from study_tool.platforms import registry
|
||||
from study_tool.platforms.jspx import *
|
||||
from study_tool.runtime import log
|
||||
from study_tool.runtime import RUNS, RUNS_LOCK, log
|
||||
|
||||
def _log_login(username, ok, code, error, elapsed, stage=""):
|
||||
"""每次登录尝试:统一日志 + login_log 表(登录记录页用)。"""
|
||||
@@ -37,8 +40,14 @@ def api_login(b: LoginIn):
|
||||
_log_login(username or b.account_id, False, "no_credential", err, time.time() - t0,
|
||||
"LoginIn")
|
||||
return JSONResponse({"ok": False, "code": "no_credential", "error": err}, status_code=200)
|
||||
pf = registry.get((acc or {}).get("platform") or b.platform)
|
||||
if pf is None or pf.login is None:
|
||||
err = "平台「%s」还没有实现登录,请换一个平台或先在 platforms/ 里补上实现" % (
|
||||
(acc or {}).get("platform") or b.platform)
|
||||
_log_login(username, False, "no_platform", err, time.time() - t0, "LoginIn")
|
||||
return JSONResponse({"ok": False, "code": "no_platform", "error": err}, status_code=200)
|
||||
try:
|
||||
s, user = login(username, password)
|
||||
s, user = pf.login(username, password)
|
||||
except Exception as e:
|
||||
err = str(e)[:300]
|
||||
_log_login(username, False, "login_failed", err, time.time() - t0, type(e).__name__)
|
||||
@@ -49,10 +58,10 @@ def api_login(b: LoginIn):
|
||||
return JSONResponse({"ok": False, "code": "login_failed", "error": err}, status_code=200)
|
||||
warn = ""
|
||||
try:
|
||||
courses = scrape_courses(s)
|
||||
courses = pf.list_courses(s) if pf.list_courses else []
|
||||
except Exception as e:
|
||||
courses, warn = [], str(e)[:200]
|
||||
cookies = dump_cookies(s)
|
||||
cookies = (pf.dump_cookies or dump_cookies)(s)
|
||||
_log_login(username, True, "ok", warn, time.time() - t0, "user=%s" % user)
|
||||
if acc:
|
||||
store.account_save_login(acc["id"], user, cookies, courses)
|
||||
|
||||
@@ -65,13 +65,18 @@ def api_courses(b: CookiesIn):
|
||||
if not b.cookies:
|
||||
return JSONResponse({"ok": False, "code": "no_cookie",
|
||||
"error": "本机没有该账号的会话 cookie,请先点「登录」"}, status_code=200)
|
||||
s = new_session(b.cookies)
|
||||
pf = registry.get(b.platform)
|
||||
if pf is None or pf.list_courses is None:
|
||||
return JSONResponse({"ok": False, "code": "no_platform",
|
||||
"error": "平台「%s」还没有实现刷新课程,请先在 platforms/ 里补上"
|
||||
% b.platform}, status_code=200)
|
||||
s = (pf.session or new_session)(b.cookies)
|
||||
if not s.cookies:
|
||||
return JSONResponse({"ok": False, "code": "no_cookie",
|
||||
"error": "保存的 cookie 全部被过滤(domain 不含 dgjy),请重新登录"},
|
||||
status_code=200)
|
||||
try:
|
||||
courses = scrape_courses(s)
|
||||
courses = pf.list_courses(s)
|
||||
except SessionExpired as e:
|
||||
return JSONResponse({"ok": False, "code": "session_expired", "error": str(e)[:300]}, status_code=200)
|
||||
except Exception as e:
|
||||
@@ -81,21 +86,25 @@ def api_courses(b: CookiesIn):
|
||||
"error": "登录态有效,但该账号名下三个板块(在学/助学/督学)"
|
||||
"的进行中、未开始、已结束里都没有课程"}, status_code=200)
|
||||
try:
|
||||
user = whoami(fetch_admin(s))
|
||||
user = pf.profile(s) if pf.profile else ""
|
||||
except Exception:
|
||||
user = ""
|
||||
return {"ok": True, "courses": courses, "user": user,
|
||||
"in_study": len([c for c in courses if c["in_study"]]),
|
||||
# 补 jspx 会话时 cookie 会换新(JSESSIONID/route),回传让前端写回 IndexedDB
|
||||
"cookies": dump_cookies(s)}
|
||||
# 补 jspx 会话时 cookie 会换新(JSESSIONID/route),回传让前端写回
|
||||
"cookies": (pf.dump_cookies or dump_cookies)(s)}
|
||||
|
||||
|
||||
@app.post("/api/discover")
|
||||
def api_discover(b: DiscoverIn):
|
||||
s = new_session(b.cookies)
|
||||
pf = registry.get(b.platform)
|
||||
if pf is None or pf.discover is None:
|
||||
return JSONResponse({"ok": False, "code": "no_platform",
|
||||
"error": "平台「%s」还没有实现课程发现" % b.platform}, status_code=200)
|
||||
s = (pf.session or new_session)(b.cookies)
|
||||
try:
|
||||
d = discover(s, b.plan_id, b.project_id, b.name)
|
||||
return {"ok": True, **d, "cookies": dump_cookies(s)}
|
||||
d = pf.discover(s, b.plan_id, b.project_id, b.name)
|
||||
return {"ok": True, **d, "cookies": (pf.dump_cookies or dump_cookies)(s)}
|
||||
except Exception as e:
|
||||
return JSONResponse({"ok": False, "error": str(e)[:300]}, status_code=200)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user