mr potato head

This commit is contained in:
2026-02-16 13:42:24 -06:00
parent a395f221cc
commit 028bdfa4f9

View File

@@ -1,6 +1,4 @@
"""
Medications command handler - bot-side hooks for medication management
"""
import asyncio
import re
@@ -30,10 +28,8 @@ def _get_nearest_scheduled_time(times, user_tz=None):
# If user_tz is an offset in minutes, convert to timezone object
# Positive offset means behind UTC, so we need to use Etc/GMT+N
# where N = -offset_minutes/60 (because Etc/GMT+5 means 5 hours behind UTC)
from pytz import timezone as pytz_timezone
offset_hours = -user_tz // 60
user_tz = pytz_timezone(f"Etc/GMT+{offset_hours}")
user_tz = pytz.timezone(f"Etc/GMT+{offset_hours}")
now = datetime.now(user_tz)
now_minutes = now.hour * 60 + now.minute
@@ -61,10 +57,6 @@ def _get_nearest_scheduled_time(times, user_tz=None):
# If no time within window, use the most recent past time
if best_time is None:
# Get current time in user's timezone again for reference
now = datetime.now(user_tz)
now_minutes = now.hour * 60 + now.minute
# Find the most recent past time
past_times = []
for time_str in times:
@@ -86,23 +78,7 @@ def _get_nearest_scheduled_time(times, user_tz=None):
past_times.sort()
best_time = past_times[-1][1]
return best_time
if not best_time:
for time_str in times:
try:
hour, minute = map(int, time_str.split(":"))
time_minutes = hour * 60 + minute
# If this time was earlier today, it's a candidate
if time_minutes <= now_minutes:
diff = now_minutes - time_minutes
if diff < best_diff:
best_diff = diff
best_time = time_str
except (ValueError, AttributeError):
continue
# If still no time found, use the first scheduled time
# Fallback: if still no time found, use the first scheduled time
if not best_time and times:
best_time = times[0]
@@ -110,38 +86,7 @@ def _get_nearest_scheduled_time(times, user_tz=None):
async def _get_user_timezone(message, session, token):
"""Get user's timezone offset. Returns offset_minutes or None if not set.
Also checks for pending timezone confirmation in session.
"""
# Check if there's a pending timezone confirmation
pending = session.get("pending_confirmations", {}).get("timezone")
if pending:
# User just replied with timezone info
user_response = message.content.strip()
# Try to parse common timezone formats
# Format: "UTC-8", "PST", "EST", "-8", "+5:30", etc.
offset = _parse_timezone(user_response)
if offset is not None:
# Save to API
resp, status = api_request(
"put", "/api/preferences", token, {"timezone_offset": offset}
)
if status == 200:
# Remove pending confirmation
del session["pending_confirmations"]["timezone"]
return offset
# Invalid timezone format
await message.channel.send(
"I didn't understand that timezone format. Please say something like:\n"
'- "UTC-8" or "-8" for Pacific Time\n'
'- "UTC+1" or "+1" for Central European Time\n'
'- "PST", "EST", "CST", "MST" for US timezones'
)
return None
"""Get user's timezone offset. Returns offset_minutes or None if not set."""
# Check if user has timezone set in preferences
resp, status = api_request("get", "/api/preferences", token)
if status == 200 and resp:
@@ -149,7 +94,7 @@ async def _get_user_timezone(message, session, token):
if offset is not None:
return offset
# No timezone set - need to ask user
# No timezone set
return None
@@ -267,10 +212,74 @@ async def _get_scheduled_time_from_context(message, med_name):
async def handle_medication(message, session, parsed):
action = parsed.get("action", "unknown")
token = session["token"]
user_uuid = session["user_uuid"]
# --- PENDING CONFIRMATION HANDLER ---
# Check if we are waiting for a response (e.g., timezone, yes/no confirmation)
pending = session.get("pending_confirmations", {})
# 1. Handle Pending Timezone
if "timezone" in pending:
user_response = message.content.strip()
offset = _parse_timezone(user_response)
if offset is not None:
# Save to API
resp, status = api_request(
"put", "/api/preferences", token, {"timezone_offset": offset}
)
if status == 200:
# Retrieve the stored action context
prev_context = pending["timezone"]
del session["pending_confirmations"]["timezone"]
await message.channel.send(f"✅ Timezone set successfully.")
# Restore the previous action so we can resume it
# We merge the context into 'parsed' so the logic below continues correctly
parsed = prev_context
else:
await message.channel.send("Error saving timezone. Please try again.")
return
else:
await message.channel.send(
"I didn't understand that timezone format. Please say something like:\n"
'- "UTC-8" or "-8" for Pacific Time\n'
'- "UTC+1" or "+1" for Central European Time\n'
'- "PST", "EST", "CST", "MST" for US timezones'
)
return
# 2. Handle Generic Yes/No Confirmations (Add/Delete meds)
# Find keys that look like confirmations (excluding timezone)
confirm_keys = [k for k in pending if k.startswith("med_")]
if confirm_keys:
text = message.content.strip().lower()
key = confirm_keys[0] # Handle one confirmation at a time
stored_action = pending[key]
if text in ["yes", "y", "confirm"]:
del session["pending_confirmations"][key]
# Resume the action with confirmation bypassed
parsed = stored_action
# Force needs_confirmation to False just in case
parsed["needs_confirmation"] = False
elif text in ["no", "n", "cancel"]:
del session["pending_confirmations"][key]
await message.channel.send("Okay, cancelled.")
return
else:
# User said something else, remind them
await message.channel.send(
"I'm waiting for a confirmation. Please reply **yes** to proceed or **no** to cancel."
)
return
# --- MAIN ACTION HANDLER ---
action = parsed.get("action", "unknown")
if action == "list":
resp, status = api_request("get", "/api/medications", token)
if status == 200:
@@ -767,4 +776,4 @@ def validate_medication_json(data):
register_module("medication", handle_medication)
ai_parser.register_validator("medication", validate_medication_json)
ai_parser.register_validator("medication", validate_medication_json)