#!/usr/bin/env python3 """Run by the cron container every ~60s to send meal reminders. For each household, checks the current local time. If it's 10:00–10:04, sends lunch reminders; if 16:00–16:04, sends dinner reminders. A per-household sent-date guard prevents duplicate sends. """ import os import sys from datetime import datetime from zoneinfo import ZoneInfo, available_timezones # Ensure we can import from the app directory sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from models import get_all_households, get_users_with_ntfy, update_reminder_sent, init_db from ntfy import send_meal_reminder APP_BASE_URL = os.environ.get("APP_BASE_URL", "http://meal-tracker:5000") # Reminder schedule (local time) REMINDERS = { "lunch": 10, # 10:00 "dinner": 16, # 16:00 } def _resolve_timezone(tz_str: str) -> ZoneInfo: """Return a ZoneInfo for *tz_str*, falling back to UTC on error.""" try: return ZoneInfo(tz_str) except Exception: return ZoneInfo("UTC") def main() -> None: init_db() # ensure tables exist (first run before web container) now_utc = datetime.now(ZoneInfo("UTC")) sent = 0 for hh in get_all_households(): tz = _resolve_timezone(hh.get("timezone", "UTC")) local_now = now_utc.astimezone(tz) today_str = local_now.strftime("%Y-%m-%d") hour = local_now.hour minute = local_now.minute for meal_type, trigger_hour in REMINDERS.items(): if hour != trigger_hour or minute >= 5: continue last_col = f"last_{meal_type}_reminder" if hh.get(last_col) == today_str: continue # already sent today users = get_users_with_ntfy(hh["id"]) if not users: continue for user in users: ok = send_meal_reminder( ntfy_url=user["ntfy_url"], ntfy_token=user["ntfy_token"], callback_token=user["callback_token"], meal_type=meal_type, for_date=local_now.date(), app_base_url=APP_BASE_URL, ) if ok: print(f"[{local_now:%Y-%m-%d %H:%M}] sent {meal_type} → {user['username']}") sent += 1 update_reminder_sent(hh["id"], meal_type, today_str) if sent: print(f"Sent {sent} reminder(s)") if __name__ == "__main__": main()