import asyncio import logging from datetime import datetime, time from init import bot, dp, du, dc from script import delta_time, download_ical, dt_now, message_form, text_ical from handlers import router async def send(tg_id, text): await bot.send_message(chat_id=tg_id, disable_web_page_preview=True, text=text) async def check_user(user_id): events = sorted(text_ical(user_id, du.get_tz(user_id)), key=lambda e: (e[0], e[1], e[2])) tg_id = str(du.get_first_user_id(user_id)) start = dc.get_start(user_id) daily = dc.get_daily(user_id) alarm = dc.get_alarm(user_id) alarm2_status = dc.get_status2(user_id) today = dt_now(du.get_tz(user_id)).date() time_check = dt_now(du.get_tz(user_id)).time() # ДЛЯ DAILY counter = 0 txt = "События сегодня\n\n" delta_daily1 = time(hour=8, minute=0) delta_daily2 = time(hour=8, minute=1) # -------------------------------- for event in events: if event[0] == today: d_event = datetime.combine(today, event[1]) if daily and delta_daily1 <= time_check < delta_daily2: counter += 1 txt += message_form(counter, event[3]) # для событий на весь день напоминания по времени не шлём if event[3]["all_day"]: continue delta_start = delta_time(d_event, 1, 0) if start and delta_start[0] < time_check <= delta_start[1]: await send(tg_id, "Событие начинается!\n\n" + message_form(0, event[3])) delta_alarm1 = delta_time(d_event, alarm[0], alarm[0] - 1) if delta_alarm1[0] < time_check <= delta_alarm1[1]: await send(tg_id, f"Напоминаю!\nЧерез {alarm[0]} минут " f"будет событие:\n\n{message_form(0, event[3])}") if alarm2_status: delta_alarm2 = delta_time(d_event, alarm[1], alarm[1] - 1) if delta_alarm2[0] < time_check <= delta_alarm2[1]: await send(tg_id, f"Напоминаю!\nЧерез {alarm[1]} минут " f"будет событие:\n\n{message_form(0, event[3])}") if daily and delta_daily1 <= time_check < delta_daily2: if counter: await send(tg_id, txt) else: await send(tg_id, "Сегодня событий нет") # ПРОВЕРКА НА СОБЫТИЕ async def alarm(wait_for): while True: await asyncio.sleep(wait_for) for (user_id,) in du.all_users(): # ошибка у одного пользователя (заблокировал бота, битый календарь) не должна # останавливать рассылку остальным и весь бот try: if dc.clock_exists(user_id) and du.get_status(user_id): await check_user(user_id) except Exception: logging.exception("Ошибка проверки событий пользователя %s", user_id) async def update(wait_for): while True: await asyncio.sleep(wait_for) for (user_id,) in du.all_users(): try: if du.url_exists(user_id) and du.get_status(user_id): await download_ical(du.get_url(user_id), user_id) except Exception as err: # при сбое остаётся прошлая версия календаря logging.warning("Не удалось обновить календарь пользователя %s: %s", user_id, err) async def main() -> None: dp.include_router(router) await bot.delete_webhook(drop_pending_updates=True) await dp.start_polling(bot, allowed_updates=dp.resolve_used_update_types()) async def process() -> None: await asyncio.gather(main(), # ЗАПУСК ОСНОВНОЙ ПРОГРАММЫ alarm(60), # ПРОВЕРКА КАЖДУЮ 1 МИНУТУ update(780)) # ПРОВЕРКА КАЖДУЮ 13 МИНУТУ if __name__ == "__main__": logging.basicConfig(level=logging.INFO) try: asyncio.run(process()) except KeyboardInterrupt: pass