56 lines
1.6 KiB
Python
56 lines
1.6 KiB
Python
import asyncio
|
|
import logging
|
|
from contextlib import suppress
|
|
from zoneinfo import ZoneInfo
|
|
|
|
from telegram.ext import Application
|
|
|
|
from .config import REMINDER_POLL_SECONDS
|
|
from .storage import AssistantStorage
|
|
from .time_utils import format_local_dt, utc_now
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def reminder_loop(application: Application) -> None:
|
|
storage: AssistantStorage = application.bot_data["storage"]
|
|
tz: ZoneInfo = application.bot_data["timezone"]
|
|
|
|
while True:
|
|
try:
|
|
due_reminders = storage.due_reminders(utc_now())
|
|
for reminder in due_reminders:
|
|
await application.bot.send_message(
|
|
chat_id=reminder["chat_id"],
|
|
text=(
|
|
f"Напоминание #{reminder['id']} "
|
|
f"({format_local_dt(reminder['remind_at'], tz)}):\n"
|
|
f"{reminder['text']}"
|
|
),
|
|
)
|
|
storage.mark_reminder_sent(int(reminder["id"]))
|
|
except asyncio.CancelledError:
|
|
raise
|
|
except Exception:
|
|
logger.exception("Reminder loop failed")
|
|
|
|
await asyncio.sleep(REMINDER_POLL_SECONDS)
|
|
|
|
|
|
async def post_init(application: Application) -> None:
|
|
application.bot_data["reminder_task"] = asyncio.create_task(
|
|
reminder_loop(application),
|
|
name="reminder-loop",
|
|
)
|
|
|
|
|
|
async def post_shutdown(application: Application) -> None:
|
|
task = application.bot_data.pop("reminder_task", None)
|
|
if task is None:
|
|
return
|
|
|
|
task.cancel()
|
|
with suppress(asyncio.CancelledError):
|
|
await task
|