60 lines
1.9 KiB
Python
60 lines
1.9 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 .telegram_utils import escape_markdown_text, markdown_code, send_markdown
|
|
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 send_markdown(
|
|
application.bot,
|
|
chat_id=reminder["chat_id"],
|
|
markdown=(
|
|
f"**⏰ Напоминание "
|
|
f"{markdown_code('#' + str(reminder['id']))}**\n\n"
|
|
f"**Время:** "
|
|
f"{markdown_code(format_local_dt(reminder['remind_at'], tz))}\n"
|
|
f"**Задача:** {escape_markdown_text(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
|