migrace /remind na sqlite

This commit is contained in:
lachtan
2026-06-10 07:10:11 +02:00
parent be01fe7a07
commit b2d367e6a4
8 changed files with 1315 additions and 231 deletions

View File

@@ -0,0 +1,124 @@
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.11"
# dependencies = ["pyyaml"]
# ///
"""Migrate reminders from reminder.yaml to SQLite.
Reads reminder.yaml, inserts into reminders.sqlite, then renames YAML to .bak.
"""
from __future__ import annotations
import sys
from datetime import datetime, timezone
from os import environ
from pathlib import Path
# db.py lives in skills/remind/scripts/
SCRIPTS_DIR = Path(__file__).resolve().parent.parent / "skills" / "remind" / "scripts"
sys.path.insert(0, str(SCRIPTS_DIR))
import yaml
from db import get_db, init_db
WORKSPACE = Path(__file__).resolve().parent.parent
YAML_PATH = WORKSPACE / "reminder.yaml"
DEFAULT_DB_PATH = WORKSPACE / "db" / "reminders.sqlite"
DB_PATH = Path(environ.get("REMIND_DB", str(DEFAULT_DB_PATH)))
def _now() -> str:
return datetime.now(timezone.utc).isoformat(timespec="seconds")
def _parse_window(window: str) -> tuple[int, int]:
start_str, end_str = window.split("-", 1)
start = _hhmm_to_minutes(start_str.strip())
end = _hhmm_to_minutes(end_str.strip())
return start, end
def _hhmm_to_minutes(value: str) -> int:
h, m = value.split(":")
return int(h) * 60 + int(m)
def main() -> int:
if not YAML_PATH.exists():
print("No reminder.yaml found — nothing to migrate.")
return 0
data = yaml.safe_load(YAML_PATH.read_text(encoding="utf-8")) or {}
reminders = data.get("reminders", [])
if not reminders:
print("reminder.yaml is empty — nothing to migrate.")
return 0
init_db(DB_PATH)
conn = get_db(DB_PATH)
try:
conn.execute("BEGIN")
for item in reminders:
text = (item.get("text") or "").strip()
if not text:
continue
now = _now()
cur = conn.execute(
"INSERT INTO reminders (text, enabled, timezone, created_at, updated_at) VALUES (?, 1, 'Europe/Prague', ?, ?)",
(text, now, now),
)
rid = cur.lastrowid
at = item.get("at")
at_times = item.get("at_times", [])
if at:
at_times = [at] + list(at_times)
for at_str in at_times:
conn.execute(
"INSERT INTO schedule_at (reminder_id, at_datetime) VALUES (?, ?)",
(rid, at_str),
)
for expr in item.get("cron_exprs", []):
conn.execute(
"INSERT INTO schedule_cron (reminder_id, cron_expr) VALUES (?, ?)",
(rid, expr),
)
random_cfg = item.get("random")
if random_cfg:
start, end = _parse_window(random_cfg["window"])
conn.execute(
"""
INSERT INTO schedule_random
(reminder_id, times_per_day, window_start, window_end, days_filter, from_date, until_date)
VALUES (?, ?, ?, ?, ?, ?, ?)
""",
(
rid,
random_cfg["times_per_day"],
start,
end,
random_cfg.get("days"),
random_cfg.get("from"),
random_cfg.get("until"),
),
)
conn.execute("COMMIT")
backup = YAML_PATH.with_suffix(".yaml.bak")
YAML_PATH.rename(backup)
print(f"Migrated {len(reminders)} reminders to {DB_PATH}")
print(f"Renamed {YAML_PATH} to {backup}")
return 0
except Exception as exc:
conn.execute("ROLLBACK")
print(f"Migration failed: {exc}", file=sys.stderr)
return 1
finally:
conn.close()
if __name__ == "__main__":
sys.exit(main())