Files
checkbot/app/routing/repository.py
T
patrickandClaude Sonnet 5.5 5278530467
test / pytest (3.11) (push) Waiting to run
test / pytest (3.13) (push) Waiting to run
feat: Phase 6b rules with delay, delta format, reminders, zpool default rule
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 02:38:10 +01:00

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)),
])