debug line test
This commit is contained in:
+118
@@ -0,0 +1,118 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
import aiosqlite
|
||||
|
||||
from server.config_loader import MedsConfig, Slot, load_meds_config, slot_datetime, today_str
|
||||
from server.db import utc_now_iso
|
||||
|
||||
|
||||
async def get_log_for_day(db: aiosqlite.Connection, day: str) -> dict[str, dict[str, Any]]:
|
||||
cur = await db.execute(
|
||||
"SELECT slot_id, status, logged_at, source FROM intake_log WHERE day = ? ORDER BY logged_at DESC",
|
||||
(day,),
|
||||
)
|
||||
rows = await cur.fetchall()
|
||||
await cur.close()
|
||||
result: dict[str, dict[str, Any]] = {}
|
||||
for slot_id, status, logged_at, source in rows:
|
||||
if slot_id not in result:
|
||||
result[slot_id] = {"status": status, "logged_at": logged_at, "source": source}
|
||||
return result
|
||||
|
||||
|
||||
async def get_snooze_for_day(db: aiosqlite.Connection, day: str) -> dict[str, str]:
|
||||
cur = await db.execute("SELECT slot_id, snooze_until FROM snooze WHERE day = ?", (day,))
|
||||
rows = await cur.fetchall()
|
||||
await cur.close()
|
||||
return {slot_id: snooze_until for slot_id, snooze_until in rows}
|
||||
|
||||
|
||||
def compute_status(
|
||||
slot: Slot,
|
||||
now: datetime,
|
||||
tz: ZoneInfo,
|
||||
log_entry: dict[str, Any] | None,
|
||||
snooze_until: str | None,
|
||||
) -> str:
|
||||
if log_entry:
|
||||
return log_entry["status"]
|
||||
|
||||
slot_dt = slot_datetime(now, slot, tz)
|
||||
window_end = slot_dt + timedelta(minutes=slot.reminder_window_minutes)
|
||||
|
||||
if snooze_until:
|
||||
try:
|
||||
snooze_dt = datetime.fromisoformat(snooze_until)
|
||||
if now < snooze_dt:
|
||||
return "snoozed"
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if now < slot_dt:
|
||||
return "upcoming"
|
||||
|
||||
if now <= window_end:
|
||||
return "pending"
|
||||
|
||||
return "overdue"
|
||||
|
||||
|
||||
async def build_today(db: aiosqlite.Connection, config: MedsConfig | None = None) -> dict[str, Any]:
|
||||
config = config or load_meds_config()
|
||||
tz = config.timezone
|
||||
now = datetime.now(tz)
|
||||
day = today_str(tz)
|
||||
logs = await get_log_for_day(db, day)
|
||||
snoozes = await get_snooze_for_day(db, day)
|
||||
|
||||
slots_out: list[dict[str, Any]] = []
|
||||
for slot in config.slots:
|
||||
log_entry = logs.get(slot.id)
|
||||
snooze_until = snoozes.get(slot.id)
|
||||
status = compute_status(slot, now, tz, log_entry, snooze_until)
|
||||
slot_dt = slot_datetime(now, slot, tz)
|
||||
window_end = slot_dt + timedelta(minutes=slot.reminder_window_minutes)
|
||||
slots_out.append(
|
||||
{
|
||||
"id": slot.id,
|
||||
"time": slot.time.strftime("%H:%M"),
|
||||
"label": slot.label,
|
||||
"meds": [{"name": m.name, "dose": m.dose} for m in slot.meds],
|
||||
"status": status,
|
||||
"logged_at": log_entry["logged_at"] if log_entry else None,
|
||||
"window_end": window_end.isoformat(),
|
||||
"snooze_until": snooze_until,
|
||||
}
|
||||
)
|
||||
|
||||
return {"day": day, "timezone": str(tz), "now": now.isoformat(), "slots": slots_out}
|
||||
|
||||
|
||||
async def mark_missed_for_overdue(db: aiosqlite.Connection, config: MedsConfig | None = None) -> list[str]:
|
||||
from server.db import new_id
|
||||
|
||||
config = config or load_meds_config()
|
||||
tz = config.timezone
|
||||
now = datetime.now(tz)
|
||||
day = today_str(tz)
|
||||
logs = await get_log_for_day(db, day)
|
||||
marked: list[str] = []
|
||||
|
||||
for slot in config.slots:
|
||||
if slot.id in logs:
|
||||
continue
|
||||
status = compute_status(slot, now, tz, None, None)
|
||||
if status == "overdue":
|
||||
await db.execute(
|
||||
"INSERT INTO intake_log (id, slot_id, day, status, logged_at, source) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
(new_id(), slot.id, day, "missed", utc_now_iso(), "system"),
|
||||
)
|
||||
marked.append(slot.id)
|
||||
|
||||
if marked:
|
||||
await db.commit()
|
||||
return marked
|
||||
Reference in New Issue
Block a user