diff --git a/tg/tasks.py b/tg/tasks.py index e4acbf3..304c316 100644 --- a/tg/tasks.py +++ b/tg/tasks.py @@ -3,7 +3,7 @@ import traceback from asyncio import sleep from aiogram import Bot -from aiogram.exceptions import TelegramBadRequest +from aiogram.exceptions import TelegramBadRequest, TelegramMigrateToChat from aiogram.types import ChatMemberBanned, ChatMemberLeft from aiogram.utils.formatting import Bold @@ -11,6 +11,53 @@ import tg.tg_database as database from tg.handlers.user import format_rating +async def is_user_in_chat(bot: Bot, chat_id: int, user_id: int) -> bool: + found = True + try: + info = await bot.get_chat_member(chat_id, user_id) + if isinstance(info, ChatMemberLeft) or isinstance(info, ChatMemberBanned): + found = False + except TelegramBadRequest: + found = False + except Exception: + pass + return found + + +async def cleanup_chats(bot: Bot): + me = await bot.get_me() + + # Обработка миграций чатов + for chat in database.DB.get_chats(): + chat_id = chat['id'] + if chat_id > 0: + continue + + try: + await bot.get_chat(chat_id) + except TelegramMigrateToChat as e: + new_id = e.migrate_to_chat_id + new_chat = database.DB.get_chat(new_id) + + if new_chat is None or new_chat['active'] == 0: + database.DB.chat_delete(new_id) + database.DB.chat_update(chat_id, id=new_id) + else: + database.DB.chat_delete(chat_id) + except Exception: + continue + + # Удаление чатов, в которых больше нет бота + for chat in database.DB.get_chats(): + chat_id = chat['id'] + if chat_id > 0: + # TODO + continue + + if not is_user_in_chat(bot, chat_id, me.id): + database.DB.chat_delete(chat_id) + + async def cleanup_users(bot: Bot): for chat in database.DB.get_chats(): if chat['active'] == 0: @@ -20,15 +67,7 @@ async def cleanup_users(bot: Bot): for user in database.DB.get_top_silent(chat_id=chat_id, threshold_days=14): user_id = user['user_id'] - found = False - try: - info = await bot.get_chat_member(chat_id, user_id) - if not isinstance(info, ChatMemberLeft) and not isinstance(info, ChatMemberBanned): - found = True - except TelegramBadRequest: - pass - - if not found: + if not is_user_in_chat(bot, chat_id, user_id): database.DB.delete_user(chat_id, user_id) print(f'Из чата (id={chat_id}) удален пользователь (id={user_id})') @@ -77,8 +116,17 @@ async def daily_maintenance_task(bot: Bot): while True: await wait_until(target_datetime) + try: + await cleanup_chats(bot) + except Exception: + print(traceback.format_exc()) + try: await cleanup_users(bot) + except Exception: + print(traceback.format_exc()) + + try: await reset_counters(target_datetime.day == 1, bot) except Exception: print(traceback.format_exc())