105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
import re
|
|
|
|
from fastapi import APIRouter, Request
|
|
from fastapi.responses import HTMLResponse
|
|
from fastapi.templating import Jinja2Templates
|
|
|
|
from db import get_db_conn
|
|
|
|
templates = Jinja2Templates(directory="templates")
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/settings", response_class=HTMLResponse)
|
|
async def settings_page(request: Request):
|
|
return templates.TemplateResponse(request, "settings.html", {"active": "settings"})
|
|
|
|
|
|
@router.get("/api/break-patterns")
|
|
async def get_break_patterns():
|
|
with get_db_conn() as conn:
|
|
with conn.cursor() as cur:
|
|
cur.execute(
|
|
"SELECT id, pattern_type, pattern, enabled, is_default FROM break_patterns ORDER BY id"
|
|
)
|
|
return [
|
|
{
|
|
"id": r[0],
|
|
"pattern_type": r[1],
|
|
"pattern": r[2],
|
|
"enabled": r[3],
|
|
"is_default": r[4],
|
|
}
|
|
for r in cur.fetchall()
|
|
]
|
|
|
|
|
|
@router.post("/api/break-patterns")
|
|
async def add_break_pattern(request: Request):
|
|
body = await request.json()
|
|
ptype = (body.get("pattern_type") or "").strip()
|
|
pattern = (body.get("pattern") or "").strip()
|
|
if ptype not in ("regex", "css_class") or not pattern:
|
|
return {"error": "Invalid input"}
|
|
if ptype == "regex":
|
|
try:
|
|
re.compile(pattern)
|
|
except re.error as e:
|
|
return {"error": f"Invalid regex: {e}"}
|
|
|
|
with get_db_conn() as conn:
|
|
with conn:
|
|
with conn.cursor() as cur:
|
|
cur.execute(
|
|
"""
|
|
INSERT INTO break_patterns (pattern_type, pattern)
|
|
VALUES (%s, %s)
|
|
ON CONFLICT (pattern_type, pattern) DO NOTHING
|
|
RETURNING id
|
|
""",
|
|
(ptype, pattern),
|
|
)
|
|
row = cur.fetchone()
|
|
if not row:
|
|
return {"error": "Pattern already exists"}
|
|
return {"ok": True, "id": row[0]}
|
|
|
|
|
|
@router.patch("/api/break-patterns/{pid}")
|
|
async def update_break_pattern(pid: int, request: Request):
|
|
body = await request.json()
|
|
with get_db_conn() as conn:
|
|
with conn:
|
|
with conn.cursor() as cur:
|
|
if "enabled" in body:
|
|
cur.execute("UPDATE break_patterns SET enabled = %s WHERE id = %s", (bool(body["enabled"]), pid))
|
|
if "pattern" in body:
|
|
new_pat = (body.get("pattern") or "").strip()
|
|
cur.execute("SELECT pattern_type FROM break_patterns WHERE id = %s", (pid,))
|
|
row = cur.fetchone()
|
|
if row and row[0] == "regex":
|
|
try:
|
|
re.compile(new_pat)
|
|
except re.error as e:
|
|
return {"error": f"Invalid regex: {e}"}
|
|
cur.execute("UPDATE break_patterns SET pattern = %s WHERE id = %s", (new_pat, pid))
|
|
return {"ok": True}
|
|
|
|
|
|
@router.delete("/api/break-patterns/{pid}")
|
|
async def delete_break_pattern(pid: int):
|
|
with get_db_conn() as conn:
|
|
with conn:
|
|
with conn.cursor() as cur:
|
|
cur.execute("DELETE FROM break_patterns WHERE id = %s", (pid,))
|
|
return {"ok": True}
|
|
|
|
|
|
@router.delete("/api/reading-history")
|
|
async def reset_reading_history():
|
|
with get_db_conn() as conn:
|
|
with conn:
|
|
with conn.cursor() as cur:
|
|
cur.execute("DELETE FROM reading_sessions")
|
|
return {"ok": True}
|