ui update and some backend functionality adding in accordance with research on adhd and ux design
This commit is contained in:
@@ -7,7 +7,7 @@ Override poll_callback() with your domain-specific logic.
|
||||
import os
|
||||
import time
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
import core.postgres as postgres
|
||||
import core.notifications as notifications
|
||||
@@ -18,60 +18,81 @@ logger = logging.getLogger(__name__)
|
||||
POLL_INTERVAL = int(os.environ.get("POLL_INTERVAL", 60))
|
||||
|
||||
|
||||
def _user_now_for(user_uuid):
|
||||
"""Get current datetime in a user's timezone using their stored offset."""
|
||||
prefs = postgres.select_one("user_preferences", {"user_uuid": user_uuid})
|
||||
offset_minutes = 0
|
||||
if prefs and prefs.get("timezone_offset") is not None:
|
||||
offset_minutes = prefs["timezone_offset"]
|
||||
# JS getTimezoneOffset: positive = behind UTC, so negate
|
||||
tz_obj = timezone(timedelta(minutes=-offset_minutes))
|
||||
return datetime.now(tz_obj)
|
||||
|
||||
|
||||
def check_medication_reminders():
|
||||
"""Check for medications due now and send notifications."""
|
||||
try:
|
||||
from datetime import date as date_type
|
||||
meds = postgres.select("medications", where={"active": True})
|
||||
now = datetime.now()
|
||||
current_time = now.strftime("%H:%M")
|
||||
current_day = now.strftime("%a").lower() # "mon","tue", etc.
|
||||
today = now.date()
|
||||
today_str = today.isoformat()
|
||||
|
||||
# Group by user so we only look up timezone once per user
|
||||
user_meds = {}
|
||||
for med in meds:
|
||||
freq = med.get("frequency", "daily")
|
||||
uid = med.get("user_uuid")
|
||||
if uid not in user_meds:
|
||||
user_meds[uid] = []
|
||||
user_meds[uid].append(med)
|
||||
|
||||
# Skip as_needed -- no scheduled reminders for PRN
|
||||
if freq == "as_needed":
|
||||
continue
|
||||
for user_uuid, user_med_list in user_meds.items():
|
||||
now = _user_now_for(user_uuid)
|
||||
current_time = now.strftime("%H:%M")
|
||||
current_day = now.strftime("%a").lower()
|
||||
today = now.date()
|
||||
today_str = today.isoformat()
|
||||
|
||||
# Day-of-week check for specific_days
|
||||
if freq == "specific_days":
|
||||
days = med.get("days_of_week", [])
|
||||
if current_day not in days:
|
||||
for med in user_med_list:
|
||||
freq = med.get("frequency", "daily")
|
||||
|
||||
# Skip as_needed -- no scheduled reminders for PRN
|
||||
if freq == "as_needed":
|
||||
continue
|
||||
|
||||
# Interval check for every_n_days
|
||||
if freq == "every_n_days":
|
||||
start = med.get("start_date")
|
||||
interval = med.get("interval_days")
|
||||
if start and interval:
|
||||
start_d = start if isinstance(start, date_type) else datetime.strptime(str(start), "%Y-%m-%d").date()
|
||||
if (today - start_d).days < 0 or (today - start_d).days % interval != 0:
|
||||
# Day-of-week check for specific_days
|
||||
if freq == "specific_days":
|
||||
med_days = med.get("days_of_week", [])
|
||||
if current_day not in med_days:
|
||||
continue
|
||||
else:
|
||||
|
||||
# Interval check for every_n_days
|
||||
if freq == "every_n_days":
|
||||
start = med.get("start_date")
|
||||
interval = med.get("interval_days")
|
||||
if start and interval:
|
||||
start_d = start if isinstance(start, date_type) else datetime.strptime(str(start), "%Y-%m-%d").date()
|
||||
if (today - start_d).days < 0 or (today - start_d).days % interval != 0:
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
|
||||
# Time check
|
||||
times = med.get("times", [])
|
||||
if current_time not in times:
|
||||
continue
|
||||
|
||||
# Time check
|
||||
times = med.get("times", [])
|
||||
if current_time not in times:
|
||||
continue
|
||||
# Already taken today? Check by created_at date
|
||||
logs = postgres.select("med_logs", where={"medication_id": med["id"], "action": "taken"})
|
||||
already_taken = any(
|
||||
log.get("scheduled_time") == current_time
|
||||
and str(log.get("created_at", ""))[:10] == today_str
|
||||
for log in logs
|
||||
)
|
||||
if already_taken:
|
||||
continue
|
||||
|
||||
# Already taken today? Check by created_at date
|
||||
logs = postgres.select("med_logs", where={"medication_id": med["id"], "action": "taken"})
|
||||
already_taken = any(
|
||||
log.get("scheduled_time") == current_time
|
||||
and str(log.get("created_at", ""))[:10] == today_str
|
||||
for log in logs
|
||||
)
|
||||
if already_taken:
|
||||
continue
|
||||
|
||||
user_settings = notifications.getNotificationSettings(med["user_uuid"])
|
||||
if user_settings:
|
||||
msg = f"Time to take {med['name']} ({med['dosage']} {med['unit']})"
|
||||
notifications._sendToEnabledChannels(user_settings, msg, user_uuid=med["user_uuid"])
|
||||
user_settings = notifications.getNotificationSettings(user_uuid)
|
||||
if user_settings:
|
||||
msg = f"Time to take {med['name']} ({med['dosage']} {med['unit']})"
|
||||
notifications._sendToEnabledChannels(user_settings, msg, user_uuid=user_uuid)
|
||||
except Exception as e:
|
||||
logger.error(f"Error checking medication reminders: {e}")
|
||||
|
||||
@@ -79,22 +100,23 @@ def check_medication_reminders():
|
||||
def check_routine_reminders():
|
||||
"""Check for scheduled routines due now and send notifications."""
|
||||
try:
|
||||
now = datetime.now()
|
||||
current_time = now.strftime("%H:%M")
|
||||
current_day = now.strftime("%a").lower()
|
||||
schedules = postgres.select("routine_schedules", where={"remind": True})
|
||||
|
||||
for schedule in schedules:
|
||||
routine = postgres.select_one("routines", {"id": schedule["routine_id"]})
|
||||
if not routine:
|
||||
continue
|
||||
|
||||
now = _user_now_for(routine["user_uuid"])
|
||||
current_time = now.strftime("%H:%M")
|
||||
current_day = now.strftime("%a").lower()
|
||||
|
||||
if current_time != schedule.get("time"):
|
||||
continue
|
||||
days = schedule.get("days", [])
|
||||
if current_day not in days:
|
||||
continue
|
||||
|
||||
routine = postgres.select_one("routines", {"id": schedule["routine_id"]})
|
||||
if not routine:
|
||||
continue
|
||||
|
||||
user_settings = notifications.getNotificationSettings(routine["user_uuid"])
|
||||
if user_settings:
|
||||
msg = f"Time to start your routine: {routine['name']}"
|
||||
|
||||
Reference in New Issue
Block a user