Files

61 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 .services import SERVICES_KEY, ApplicationServices
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:
services: ApplicationServices = application.bot_data[SERVICES_KEY]
storage = services.storage
tz: ZoneInfo = services.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