75 lines
3.4 KiB
Python
75 lines
3.4 KiB
Python
import json
|
|
|
|
from ..chat.base import Target
|
|
from ..db import Database
|
|
from .rules import Route
|
|
from .validation import RouteInput
|
|
|
|
COLUMNS = ("id, name, position, enabled, match_host, match_service, min_state, kinds, stop_on_match, "
|
|
"targets, delay_minutes, output_contains, ai_enabled, ai_hint, reminder_hours, loud, "
|
|
"use_default_targets")
|
|
KINDS_SEP = ","
|
|
INSERT_SQL = (
|
|
"INSERT INTO routes(name, enabled, match_host, match_service, min_state, kinds, stop_on_match, "
|
|
"targets, delay_minutes, output_contains, ai_enabled, ai_hint, reminder_hours, loud, "
|
|
"use_default_targets, position) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, "
|
|
"(SELECT COALESCE(MAX(position), 0) + 1 FROM routes))"
|
|
)
|
|
UPDATE_SQL = (
|
|
"UPDATE routes SET name=?, enabled=?, match_host=?, match_service=?, min_state=?, kinds=?, "
|
|
"stop_on_match=?, targets=?, delay_minutes=?, output_contains=?, ai_enabled=?, ai_hint=?, "
|
|
"reminder_hours=?, loud=?, use_default_targets=? WHERE id=?"
|
|
)
|
|
|
|
|
|
def _route(row) -> Route:
|
|
targets = tuple(Target(t["backend"], t["target"]) for t in json.loads(row["targets"]))
|
|
kinds = tuple(k for k in row["kinds"].split(KINDS_SEP) if k)
|
|
return Route(row["id"], row["name"], row["position"], bool(row["enabled"]), row["match_host"],
|
|
row["match_service"], row["min_state"], kinds, bool(row["stop_on_match"]), targets,
|
|
row["delay_minutes"], row["output_contains"], bool(row["ai_enabled"]), row["ai_hint"],
|
|
row["reminder_hours"], bool(row["loud"]), bool(row["use_default_targets"]))
|
|
|
|
|
|
def _values(data: RouteInput) -> tuple:
|
|
targets = json.dumps([t._asdict() for t in data.targets])
|
|
return (data.name.strip(), int(data.enabled), data.match_host.strip(), data.match_service.strip(),
|
|
data.min_state, KINDS_SEP.join(data.kinds), int(data.stop_on_match), targets,
|
|
data.delay_minutes, data.output_contains.strip(), int(data.ai_enabled), data.ai_hint.strip(),
|
|
data.reminder_hours or None, int(data.loud), int(data.use_default_targets))
|
|
|
|
|
|
def insert_statement(data: RouteInput) -> tuple[str, tuple]:
|
|
return INSERT_SQL, _values(data)
|
|
|
|
|
|
class RouteRepository:
|
|
def __init__(self, db: Database):
|
|
self._db = db
|
|
|
|
def list_all(self) -> list[Route]:
|
|
rows = self._db.query(f"SELECT {COLUMNS} FROM routes ORDER BY position, id")
|
|
return [_route(r) for r in rows]
|
|
|
|
def get(self, route_id: int) -> Route | None:
|
|
rows = self._db.query(f"SELECT {COLUMNS} FROM routes WHERE id=?", (route_id,))
|
|
return _route(rows[0]) if rows else None
|
|
|
|
def insert(self, data: RouteInput) -> int:
|
|
return self._db.insert(*insert_statement(data))
|
|
|
|
def update(self, route_id: int, data: RouteInput) -> bool:
|
|
return self._db.execute(UPDATE_SQL, (*_values(data), route_id)) > 0
|
|
|
|
def set_enabled(self, route_id: int, enabled: bool) -> bool:
|
|
return self._db.execute("UPDATE routes SET enabled=? WHERE id=?", (int(enabled), route_id)) > 0
|
|
|
|
def delete(self, route_id: int) -> bool:
|
|
return self._db.execute("DELETE FROM routes WHERE id=?", (route_id,)) > 0
|
|
|
|
def swap_positions(self, first: Route, second: Route) -> None:
|
|
self._db.execute_many([
|
|
("UPDATE routes SET position=? WHERE id=?", (second.position, first.id)),
|
|
("UPDATE routes SET position=? WHERE id=?", (first.position, second.id)),
|
|
])
|