feat(asr-pipeline): merge PR #1 webauth/CSRF/locking hardening and web_password fallback
This commit is contained in:
@@ -157,7 +157,8 @@ class Entity:
|
||||
|
||||
def connect() -> sqlite3.Connection:
|
||||
CFG.state_dir.mkdir(parents=True, exist_ok=True)
|
||||
con = sqlite3.connect(CFG.lexicon_db)
|
||||
con = sqlite3.connect(CFG.lexicon_db, timeout=30)
|
||||
con.execute("PRAGMA journal_mode=WAL")
|
||||
con.row_factory = sqlite3.Row
|
||||
con.executescript(SCHEMA)
|
||||
# One-time compatibility migration for the 158 corrections learned before the
|
||||
@@ -527,7 +528,7 @@ def stats() -> dict:
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ Web UI CRUD
|
||||
def list_aliases(q: str = "", origin_filter: str = "", limit: int = 200) -> list[dict]:
|
||||
def list_aliases(q: str = "", origin_filter: str = "", limit: int = 200, offset: int = 0) -> list[dict]:
|
||||
con = connect()
|
||||
sql = "SELECT * FROM alias WHERE 1=1"
|
||||
args: list = []
|
||||
@@ -539,13 +540,30 @@ def list_aliases(q: str = "", origin_filter: str = "", limit: int = 200) -> list
|
||||
sql += " AND origin <> 'card'"
|
||||
elif origin_filter == "card":
|
||||
sql += " AND origin = 'card'"
|
||||
sql += " ORDER BY confirmed DESC, created_at DESC, alias ASC LIMIT ?"
|
||||
args.append(limit)
|
||||
sql += " ORDER BY confirmed DESC, created_at DESC, alias ASC LIMIT ? OFFSET ?"
|
||||
args.extend((max(1, min(limit, 500)), max(0, offset)))
|
||||
rows = [dict(r) for r in con.execute(sql, args).fetchall()]
|
||||
con.close()
|
||||
return rows
|
||||
|
||||
|
||||
def count_aliases(q: str = "", origin_filter: str = "") -> int:
|
||||
con = connect()
|
||||
sql = "SELECT count(*) FROM alias WHERE 1=1"
|
||||
args: list = []
|
||||
if q.strip():
|
||||
pat = f"%{q.strip()}%"
|
||||
sql += " AND (alias LIKE ? OR canonical LIKE ? OR note LIKE ?)"
|
||||
args.extend([pat, pat, pat])
|
||||
if origin_filter == "learned":
|
||||
sql += " AND origin <> 'card'"
|
||||
elif origin_filter == "card":
|
||||
sql += " AND origin = 'card'"
|
||||
n = int(con.execute(sql, args).fetchone()[0])
|
||||
con.close()
|
||||
return n
|
||||
|
||||
|
||||
def update_alias(
|
||||
old_alias: str,
|
||||
old_canonical: str,
|
||||
@@ -590,7 +608,7 @@ def delete_alias(alias: str, canonical: str) -> bool:
|
||||
return deleted
|
||||
|
||||
|
||||
def list_corrections(q: str = "", limit: int = 200) -> list[dict]:
|
||||
def list_corrections(q: str = "", limit: int = 200, offset: int = 0) -> list[dict]:
|
||||
con = connect()
|
||||
sql = "SELECT * FROM correction WHERE 1=1"
|
||||
args: list = []
|
||||
@@ -598,13 +616,26 @@ def list_corrections(q: str = "", limit: int = 200) -> list[dict]:
|
||||
pat = f"%{q.strip()}%"
|
||||
sql += " AND (surface LIKE ? OR canonical LIKE ? OR note LIKE ?)"
|
||||
args.extend([pat, pat, pat])
|
||||
sql += " ORDER BY confirmed DESC, n DESC, last_seen DESC LIMIT ?"
|
||||
args.append(limit)
|
||||
sql += " ORDER BY confirmed DESC, n DESC, last_seen DESC LIMIT ? OFFSET ?"
|
||||
args.extend((max(1, min(limit, 500)), max(0, offset)))
|
||||
rows = [dict(r) for r in con.execute(sql, args).fetchall()]
|
||||
con.close()
|
||||
return rows
|
||||
|
||||
|
||||
def count_corrections(q: str = "") -> int:
|
||||
con = connect()
|
||||
sql = "SELECT count(*) FROM correction WHERE 1=1"
|
||||
args: list = []
|
||||
if q.strip():
|
||||
pat = f"%{q.strip()}%"
|
||||
sql += " AND (surface LIKE ? OR canonical LIKE ? OR note LIKE ?)"
|
||||
args.extend([pat, pat, pat])
|
||||
n = int(con.execute(sql, args).fetchone()[0])
|
||||
con.close()
|
||||
return n
|
||||
|
||||
|
||||
def update_correction(
|
||||
old_surface: str,
|
||||
old_canonical: str,
|
||||
@@ -651,7 +682,7 @@ def delete_correction(surface: str, canonical: str) -> bool:
|
||||
return deleted
|
||||
|
||||
|
||||
def list_entities(q: str = "", kind: str = "", limit: int = 200) -> list[dict]:
|
||||
def list_entities(q: str = "", kind: str = "", limit: int = 200, offset: int = 0) -> list[dict]:
|
||||
con = connect()
|
||||
sql = "SELECT * FROM entity WHERE 1=1"
|
||||
args: list = []
|
||||
@@ -662,13 +693,29 @@ def list_entities(q: str = "", kind: str = "", limit: int = 200) -> list[dict]:
|
||||
if kind.strip():
|
||||
sql += " AND kind=?"
|
||||
args.append(kind.strip())
|
||||
sql += " ORDER BY (CASE WHEN card='' THEN 0 ELSE 1 END), canonical ASC LIMIT ?"
|
||||
args.append(limit)
|
||||
sql += " ORDER BY (CASE WHEN card='' THEN 0 ELSE 1 END), canonical ASC LIMIT ? OFFSET ?"
|
||||
args.extend((max(1, min(limit, 500)), max(0, offset)))
|
||||
rows = [dict(r) for r in con.execute(sql, args).fetchall()]
|
||||
con.close()
|
||||
return rows
|
||||
|
||||
|
||||
def count_entities(q: str = "", kind: str = "") -> int:
|
||||
con = connect()
|
||||
sql = "SELECT count(*) FROM entity WHERE 1=1"
|
||||
args: list = []
|
||||
if q.strip():
|
||||
pat = f"%{q.strip()}%"
|
||||
sql += " AND (canonical LIKE ? OR company LIKE ? OR role LIKE ? OR related LIKE ?)"
|
||||
args.extend([pat, pat, pat, pat])
|
||||
if kind.strip():
|
||||
sql += " AND kind=?"
|
||||
args.append(kind.strip())
|
||||
n = int(con.execute(sql, args).fetchone()[0])
|
||||
con.close()
|
||||
return n
|
||||
|
||||
|
||||
def upsert_entity(
|
||||
canonical: str,
|
||||
kind: str = "人名",
|
||||
@@ -723,7 +770,7 @@ def delete_entity(canonical: str) -> bool:
|
||||
return deleted
|
||||
|
||||
|
||||
def list_relations(q: str = "", limit: int = 200) -> list[dict]:
|
||||
def list_relations(q: str = "", limit: int = 200, offset: int = 0) -> list[dict]:
|
||||
con = connect()
|
||||
sql = "SELECT * FROM relation WHERE 1=1"
|
||||
args: list = []
|
||||
@@ -731,13 +778,26 @@ def list_relations(q: str = "", limit: int = 200) -> list[dict]:
|
||||
pat = f"%{q.strip()}%"
|
||||
sql += " AND (subject LIKE ? OR predicate LIKE ? OR object LIKE ? OR source LIKE ?)"
|
||||
args.extend([pat, pat, pat, pat])
|
||||
sql += " ORDER BY active DESC, confidence DESC, last_seen DESC LIMIT ?"
|
||||
args.append(limit)
|
||||
sql += " ORDER BY active DESC, confidence DESC, last_seen DESC LIMIT ? OFFSET ?"
|
||||
args.extend((max(1, min(limit, 500)), max(0, offset)))
|
||||
rows = [dict(r) for r in con.execute(sql, args).fetchall()]
|
||||
con.close()
|
||||
return rows
|
||||
|
||||
|
||||
def count_relations(q: str = "") -> int:
|
||||
con = connect()
|
||||
sql = "SELECT count(*) FROM relation WHERE 1=1"
|
||||
args: list = []
|
||||
if q.strip():
|
||||
pat = f"%{q.strip()}%"
|
||||
sql += " AND (subject LIKE ? OR predicate LIKE ? OR object LIKE ? OR source LIKE ?)"
|
||||
args.extend([pat, pat, pat, pat])
|
||||
n = int(con.execute(sql, args).fetchone()[0])
|
||||
con.close()
|
||||
return n
|
||||
|
||||
|
||||
def update_relation(
|
||||
old_subject: str,
|
||||
old_predicate: str,
|
||||
|
||||
Reference in New Issue
Block a user