import html import traceback from aiogram import Router from aiogram.fsm.context import FSMContext from aiogram.types import CallbackQuery from aiogram import F from aiogram.filters import MagicData from helper_bot.keyboards.keyboards import create_keyboard_with_pagination, get_reply_keyboard_admin, \ create_keyboard_for_ban_reason from helper_bot.utils.helper_func import get_banned_users_list, get_banned_users_buttons from helper_bot.utils.base_dependency_factory import get_global_instance from .dependency_factory import get_post_publish_service, get_ban_service from .exceptions import UserBlockedBotError, PostNotFoundError, UserNotFoundError, PublishError, BanError from .constants import ( CALLBACK_PUBLISH, CALLBACK_DECLINE, CALLBACK_BAN, CALLBACK_UNLOCK, CALLBACK_RETURN, CALLBACK_PAGE, MESSAGE_PUBLISHED, MESSAGE_DECLINED, MESSAGE_USER_BANNED, MESSAGE_USER_UNLOCKED, MESSAGE_ERROR, ERROR_BOT_BLOCKED ) from logs.custom_logger import logger callback_router = Router() @callback_router.callback_query(F.data == CALLBACK_PUBLISH) async def post_for_group( call: CallbackQuery, settings: MagicData("settings") ): publish_service = get_post_publish_service() # TODO: переделать на MagicData logger.info( f'Получен callback-запрос с действием: {call.data} от пользователя {call.from_user.full_name} (ID сообщения: {call.message.message_id})') try: await publish_service.publish_post(call) await call.answer(text=MESSAGE_PUBLISHED, cache_time=3) except UserBlockedBotError: await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) except (PostNotFoundError, PublishError) as e: logger.error(f'Ошибка при публикации поста: {str(e)}') await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) except Exception as e: if str(e) == ERROR_BOT_BLOCKED: await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) else: important_logs = settings['Telegram']['important_logs'] await call.bot.send_message( chat_id=important_logs, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}" ) logger.error(f'Неожиданная ошибка при публикации поста: {str(e)}') await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) @callback_router.callback_query(F.data == CALLBACK_DECLINE) async def decline_post_for_group( call: CallbackQuery, settings: MagicData("settings") ): publish_service = get_post_publish_service() # TODO: переделать на MagicData logger.info( f'Получен callback-запрос с данными: {call.data} от пользователя {call.from_user.full_name} (ID: {call.from_user.id})') try: await publish_service.decline_post(call) await call.answer(text=MESSAGE_DECLINED, cache_time=3) except UserBlockedBotError: await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) except (PostNotFoundError, PublishError) as e: logger.error(f'Ошибка при отклонении поста: {str(e)}') await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) except Exception as e: if str(e) == ERROR_BOT_BLOCKED: await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) else: important_logs = settings['Telegram']['important_logs'] await call.bot.send_message( chat_id=important_logs, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}" ) logger.error(f'Неожиданная ошибка при отклонении поста: {str(e)}') await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) @callback_router.callback_query(F.data == CALLBACK_BAN) async def ban_user_from_post(call: CallbackQuery): ban_service = get_ban_service() # TODO: переделать на MagicData try: await ban_service.ban_user_from_post(call) await call.answer(text=MESSAGE_USER_BANNED, cache_time=3) except UserBlockedBotError: await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) except (UserNotFoundError, BanError) as e: logger.error(f'Ошибка при блокировке пользователя: {str(e)}') await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) except Exception as e: if str(e) == ERROR_BOT_BLOCKED: await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) else: logger.error(f'Неожиданная ошибка при блокировке пользователя: {str(e)}') await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) @callback_router.callback_query(F.data.contains(CALLBACK_BAN)) async def process_ban_user(call: CallbackQuery, state: FSMContext): ban_service = get_ban_service() # TODO: переделать на MagicData user_id = call.data[4:] logger.info(f"Вызов функции process_ban_user. Данные callback: {call.data} пользователь: {user_id}") try: user_name = await ban_service.ban_user(user_id, "") await state.update_data(user_id=user_id, user_name=user_name, message_for_user=None, date_to_unban=None) markup = create_keyboard_for_ban_reason() user_name_escaped = html.escape(str(user_name)) full_name_escaped = html.escape(str(call.message.from_user.full_name)) await call.message.answer( text=f"Выбран пользователь:\nid: {user_id}\nusername: {user_name_escaped}\nИмя:{full_name_escaped}\nВыбери причину бана из списка или напиши ее в чат", reply_markup=markup ) await state.set_state('BAN_2') except UserNotFoundError: markup = get_reply_keyboard_admin() await call.message.answer(text='Пользователь с таким ID не найден в базе', reply_markup=markup) await state.set_state('ADMIN') @callback_router.callback_query(F.data.contains(CALLBACK_UNLOCK)) async def process_unlock_user(call: CallbackQuery): ban_service = get_ban_service() # TODO: переделать на MagicData user_id = call.data[7:] try: username = await ban_service.unlock_user(user_id) await call.answer(f'{MESSAGE_USER_UNLOCKED} {username}', show_alert=True) except UserNotFoundError: await call.answer(text='Пользователь не найден в базе', show_alert=True, cache_time=3) except Exception as e: logger.error(f'Ошибка при разблокировке пользователя: {str(e)}') await call.answer(text=MESSAGE_ERROR, show_alert=True, cache_time=3) @callback_router.callback_query(F.data == CALLBACK_RETURN) async def return_to_main_menu(call: CallbackQuery): await call.message.delete() logger.info(f"Запуск админ панели для пользователя: {call.message.from_user.id}") markup = get_reply_keyboard_admin() await call.message.answer("Добро пожаловать в админку. Выбери что хочешь:", reply_markup=markup) @callback_router.callback_query(F.data.contains(CALLBACK_PAGE)) async def change_page( call: CallbackQuery, bot_db: MagicData("bot_db") ): page_number = int(call.data[5:]) logger.info(f"Переход на страницу {page_number}") if call.message.text == 'Список пользователей которые последними обращались к боту': list_users = bot_db.get_last_users_from_db() keyboard = create_keyboard_with_pagination(int(page_number), len(list_users), list_users, 'ban') await call.bot.edit_message_reply_markup( chat_id=call.message.chat.id, message_id=call.message.message_id, reply_markup=keyboard ) else: message_user = get_banned_users_list(int(page_number) * 7 - 7, bot_db) await call.bot.edit_message_text( chat_id=call.message.chat.id, message_id=call.message.message_id, text=message_user ) buttons = get_banned_users_buttons(bot_db) keyboard = create_keyboard_with_pagination(int(call.data[5:]), len(buttons), buttons, 'unlock') await call.bot.edit_message_reply_markup( chat_id=call.message.chat.id, message_id=call.message.message_id, reply_markup=keyboard )