diff --git a/web/app.py b/web/app.py index be2c471..2c6d5ca 100644 --- a/web/app.py +++ b/web/app.py @@ -280,13 +280,17 @@ def candidates_select(request: Request, id: int = Form(...), direction: str = Fo @app.post("/candidates/bulk") -def candidates_bulk(request: Request, action: str = Form(...), ids: list[int] = Form(...), +def candidates_bulk(request: Request, action: str = Form(...), ids: list[int] = Form(default_factory=list), direction: str = Form(""), status: str = Form(""), own: str = Form(""), q: str = Form(""), group_by: str = Form("source")): - """Bulk-операции: approve/reject/reject-old по отмеченным ids.""" + """Bulk-операции: approve/reject/reject-old/process по отмеченным ids.""" _require_auth(request) + back = f"/candidates?group_by={group_by}" + for k, v in (("direction", direction), ("status", status), ("own", own), ("q", q)): + if v: + back += f"&{k}={quote(v)}" if not ids: - return RedirectResponse(url="/candidates?error=no_selection", status_code=302) + return RedirectResponse(url=back + "&error=no_selection", status_code=302) conn = _db() ph = ",".join("?" * len(ids)) rows = conn.execute(f"SELECT * FROM posts WHERE id IN ({ph})", ids).fetchall() @@ -294,7 +298,7 @@ def candidates_bulk(request: Request, action: str = Form(...), ids: list[int] = conn.execute(f"UPDATE posts SET status='rejected' WHERE id IN ({ph})", ids) conn.commit() conn.close() - return RedirectResponse(url=f"/candidates?status=rejected&group_by={group_by}", status_code=302) + return RedirectResponse(url=back + "&status=rejected", status_code=302) if action == "reject-old": # все выбранные, кроме самых свежих (по 1 от источника) — «почистить старьё» keep = {} @@ -307,9 +311,22 @@ def candidates_bulk(request: Request, action: str = Form(...), ids: list[int] = conn.execute(f"UPDATE posts SET status='rejected' WHERE id IN ({ph2})", kill) conn.commit() conn.close() - return RedirectResponse(url=f"/candidates?status=rejected&group_by={group_by}", status_code=302) - # approve — каждый через существующую логику (публикация + бандл) + return RedirectResponse(url=back + "&status=rejected", status_code=302) conn.close() + if action == "process": + # обработка локальной моделью (переклассификация) по выбранным + errs = [] + done = 0 + for r in rows: + try: + impl_reclassify(int(r["id"])) + done += 1 + except Exception as e: + errs.append(f"{r['id']}({e})") + if errs: + return RedirectResponse(url=f"/candidates?error=process_partial:{','.join(map(str,errs))[:120]}&group_by={group_by}", status_code=302) + return RedirectResponse(url=back + "&error=processed:" + str(done), status_code=302) + # approve — каждый через существующую логику (публикация + бандл) errs = [] for r in rows: if r["status"] == "published": @@ -334,25 +351,30 @@ def post_comment(post_id: int, request: Request, comment: str = Form("")): @app.post("/posts/{post_id}/reclassify") def post_reclassify(post_id: int, request: Request): + """Переклассификация кандидата локальной моделью (qwen).""" _require_auth(request) + try: + impl_reclassify(post_id) + except Exception as e: + return RedirectResponse(url=f"/candidates?selected={post_id}&error=reclassify:{e}", status_code=302) + return RedirectResponse(url=f"/candidates?selected={post_id}", status_code=302) + + +def impl_reclassify(post_id: int): + """Перезапуск классификации локальной моделью. Бросает исключение при неудаче.""" from classifier.classify import classify_text conn = _db() p = conn.execute("SELECT * FROM posts WHERE id=?", (post_id,)).fetchone() if not p: conn.close() - return RedirectResponse(url="/candidates?error=notfound", status_code=302) - try: - res = classify_text(dict(p)) - except Exception as e: - conn.close() - return RedirectResponse(url=f"/candidates?selected={post_id}&error=reclassify:{e}", status_code=302) + raise ValueError("notfound") + res = classify_text(dict(p)) conn.execute( "UPDATE posts SET direction=?, relevance=?, interest=?, summary=?, classified=? WHERE id=?", (res["direction"], res["relevance"], res["interest"], res["summary"], 1 if res["classified"] else 0, post_id), ) conn.commit() conn.close() - return RedirectResponse(url=f"/candidates?selected={post_id}", status_code=302) @app.post("/posts/{post_id}/rewrite") diff --git a/web/templates/base.html b/web/templates/base.html index b778ea0..2266767 100644 --- a/web/templates/base.html +++ b/web/templates/base.html @@ -6,14 +6,14 @@