fluxer-admin-alerts/state.py
Clarth dc831b430b Restructure project to flat layout and update run instructions
Move modules from fluxer_admin_alerts/ to the repository root, switch to absolute imports, fix PROJECT_ROOT resolution, and update README commands and notifier paths.
2026-11-13 20:26:05 -05:00

85 lines
2.5 KiB
Python

from __future__ import annotations
import sqlite3
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
SCHEMA = """
CREATE TABLE IF NOT EXISTS alerts (
key TEXT PRIMARY KEY,
source TEXT NOT NULL,
title TEXT NOT NULL,
first_seen TEXT NOT NULL,
last_alerted TEXT NOT NULL,
reminded INTEGER NOT NULL DEFAULT 0,
open INTEGER NOT NULL DEFAULT 1
)
"""
@dataclass(frozen=True)
class AlertRecord:
key: str
source: str
title: str
first_seen: datetime
last_alerted: datetime
reminded: bool
open: bool
class StateStore:
def __init__(self, path: Path) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
self._conn = sqlite3.connect(path)
self._conn.row_factory = sqlite3.Row
self._conn.execute(SCHEMA)
def close(self) -> None:
self._conn.close()
def load(self) -> dict[str, AlertRecord]:
rows = self._conn.execute("SELECT * FROM alerts").fetchall()
return {
row["key"]: AlertRecord(
key=row["key"],
source=row["source"],
title=row["title"],
first_seen=datetime.fromisoformat(row["first_seen"]),
last_alerted=datetime.fromisoformat(row["last_alerted"]),
reminded=bool(row["reminded"]),
open=bool(row["open"]),
)
for row in rows
}
def save(self, records: list[AlertRecord]) -> None:
if not records:
return
with self._conn:
self._conn.executemany(
"""
INSERT INTO alerts (key, source, title, first_seen, last_alerted, reminded, open)
VALUES (?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(key) DO UPDATE SET
source = excluded.source,
title = excluded.title,
first_seen = excluded.first_seen,
last_alerted = excluded.last_alerted,
reminded = excluded.reminded,
open = excluded.open
""",
[
(
r.key,
r.source,
r.title,
r.first_seen.isoformat(),
r.last_alerted.isoformat(),
int(r.reminded),
int(r.open),
)
for r in records
],
)