From fcca168052a409acf799d2c0397f8d929be07c1c Mon Sep 17 00:00:00 2001 From: hteppl Date: Tue, 25 Mar 2025 17:21:05 +0300 Subject: [PATCH] Do not use clusters_handler for handling management actions --- handlers/admin/__init__.py | 2 + handlers/admin/clusters/clusters_handler.py | 50 ------------- handlers/admin/management/__init__.py | 3 + handlers/admin/management/keyboard.py | 16 ++++ .../admin/management/management_handler.py | 73 +++++++++++++++++++ handlers/admin/panel/keyboard.py | 12 --- handlers/admin/panel/panel_handler.py | 11 +-- 7 files changed, 95 insertions(+), 72 deletions(-) create mode 100644 handlers/admin/management/__init__.py create mode 100644 handlers/admin/management/keyboard.py create mode 100644 handlers/admin/management/management_handler.py diff --git a/handlers/admin/__init__.py b/handlers/admin/__init__.py index f77eff4d..4ac02168 100644 --- a/handlers/admin/__init__.py +++ b/handlers/admin/__init__.py @@ -6,6 +6,7 @@ from .backups import router as backups_router from .bans import router as bans_router from .clusters import router as clusters_router from .coupons import router as coupons_router +from .management import router as management_router from .panel import router as panel_router from .restart import router as restart_router from .sender import router as sender_router @@ -17,6 +18,7 @@ router = Router(name="admins_main_router") router.include_routers( panel_router, + management_router, servers_router, clusters_router, users_router, diff --git a/handlers/admin/clusters/clusters_handler.py b/handlers/admin/clusters/clusters_handler.py index 31496a69..16253a0e 100644 --- a/handlers/admin/clusters/clusters_handler.py +++ b/handlers/admin/clusters/clusters_handler.py @@ -29,7 +29,6 @@ class AdminClusterStates(StatesGroup): waiting_for_inbound_id = State() waiting_for_server_name = State() waiting_for_subscription_url = State() - waiting_for_new_domain = State() @router.callback_query( @@ -370,52 +369,3 @@ async def handle_clusters_sync( await callback_query.message.answer( text=f"❌ Произошла ошибка при синхронизации: {e}", reply_markup=build_admin_back_kb("clusters") ) - - -@router.callback_query(AdminClusterCallback.filter(F.action == "change_domain"), IsAdminFilter()) -async def request_new_domain(callback_query: AdminClusterCallback, state: FSMContext): - """Запрашивает у администратора новый домен.""" - await state.set_state(AdminClusterStates.waiting_for_new_domain) - await callback_query.message.edit_text( - text="🌐 Введите новый домен (без https://):\nПример: pocomachodomen.ru", - ) - - -@router.message(AdminClusterStates.waiting_for_new_domain) -async def process_new_domain(message: Message, state: FSMContext, session: asyncpg.Connection): - """Обновляет домен в таблице keys.""" - new_domain = message.text.strip() - logger.info(f"[DomainChange] Новый домен, введённый администратором: '{new_domain}'") - - if not new_domain or " " in new_domain or not new_domain.replace(".", "").isalnum(): - logger.warning("[DomainChange] Некорректный домен") - await message.answer( - "🚫 Некорректный домен! Введите домен без http:// и без пробелов.", - reply_markup=build_admin_back_kb("admin"), - ) - return - - new_domain_url = f"https://{new_domain}" - logger.info(f"[DomainChange] Новый домен с протоколом: '{new_domain_url}'") - - query = """ - UPDATE keys - SET key = regexp_replace(key, '^https://[^/]+', $1::TEXT) - WHERE key NOT LIKE $1 || '%' - """ - try: - await session.execute(query, new_domain_url) - logger.info("[DomainChange] Запрос на обновление домена выполнен успешно.") - except Exception as e: - logger.error(f"[DomainChange] Ошибка при выполнении запроса: {e}") - await message.answer(f"❌ Ошибка при обновлении домена: {e}", reply_markup=build_admin_back_kb("admin")) - return - - try: - sample = await session.fetchrow("SELECT key FROM keys LIMIT 1") - logger.info(f"[DomainChange] Пример обновленной записи: {sample}") - except Exception as e: - logger.error(f"[DomainChange] Ошибка при выборке обновленной записи: {e}") - - await message.answer(f"✅ Домен успешно изменен на {new_domain}!", reply_markup=build_admin_back_kb("admin")) - await state.clear() diff --git a/handlers/admin/management/__init__.py b/handlers/admin/management/__init__.py new file mode 100644 index 00000000..1a6a84ae --- /dev/null +++ b/handlers/admin/management/__init__.py @@ -0,0 +1,3 @@ +__all__ = ("router",) + +from management_handler import router diff --git a/handlers/admin/management/keyboard.py b/handlers/admin/management/keyboard.py new file mode 100644 index 00000000..61fb3408 --- /dev/null +++ b/handlers/admin/management/keyboard.py @@ -0,0 +1,16 @@ +from aiogram.types import InlineKeyboardMarkup +from aiogram.utils.keyboard import InlineKeyboardBuilder + +from ..panel.keyboard import build_admin_back_btn, AdminPanelCallback + + +def build_management_kb() -> InlineKeyboardMarkup: + builder = InlineKeyboardBuilder() + builder.button(text="💾 Создать резервную копию", callback_data=AdminPanelCallback(action="backups").pack()) + builder.button(text="🚫 Заблокировавшие бота", callback_data=AdminPanelCallback(action="bans").pack()) + builder.button(text="🔄 Перезагрузить бота", callback_data=AdminPanelCallback(action="restart").pack()) + builder.button(text="🌐 Сменить домен", callback_data=AdminPanelCallback(action="change_domain").pack()) + builder.button(text="🔑 Восстановить пробники", callback_data=AdminPanelCallback(action="restore_trials").pack()) + builder.row(build_admin_back_btn()) + builder.adjust(1) + return builder.as_markup() diff --git a/handlers/admin/management/management_handler.py b/handlers/admin/management/management_handler.py new file mode 100644 index 00000000..cf3629e8 --- /dev/null +++ b/handlers/admin/management/management_handler.py @@ -0,0 +1,73 @@ +from aiogram import F, Router +from aiogram.fsm.context import FSMContext +from aiogram.fsm.state import StatesGroup, State +from aiogram.types import CallbackQuery, Message +from asyncpg import Connection + +from filters.admin import IsAdminFilter +from keyboard import AdminPanelCallback, build_management_kb +from logger import logger +from ..panel.keyboard import build_admin_back_kb + +router = Router() + + +class AdminManagementStates(StatesGroup): + waiting_for_new_domain = State() + + +@router.callback_query(AdminPanelCallback.filter(F.action == "management"), IsAdminFilter()) +async def handle_management(callback_query: CallbackQuery): + await callback_query.message.edit_text( + text="🤖 Управление ботом", + reply_markup=build_management_kb(), + ) + + +@router.callback_query(AdminPanelCallback.filter(F.action == "change_domain"), IsAdminFilter()) +async def request_new_domain(callback_query: AdminPanelCallback, state: FSMContext): + """Запрашивает у администратора новый домен.""" + await state.set_state(AdminManagementStates.waiting_for_new_domain) + await callback_query.message.edit_text( + text="🌐 Введите новый домен (без https://):\nПример: pocomachodomen.ru", + ) + + +@router.message(AdminManagementStates.waiting_for_new_domain) +async def process_new_domain(message: Message, state: FSMContext, session: Connection): + """Обновляет домен в таблице keys.""" + new_domain = message.text.strip() + logger.info(f"[DomainChange] Новый домен, введённый администратором: '{new_domain}'") + + if not new_domain or " " in new_domain or not new_domain.replace(".", "").isalnum(): + logger.warning("[DomainChange] Некорректный домен") + await message.answer( + "🚫 Некорректный домен! Введите домен без http:// и без пробелов.", + reply_markup=build_admin_back_kb("admin"), + ) + return + + new_domain_url = f"https://{new_domain}" + logger.info(f"[DomainChange] Новый домен с протоколом: '{new_domain_url}'") + + query = """ + UPDATE keys + SET key = regexp_replace(key, '^https://[^/]+', $1::TEXT) + WHERE key NOT LIKE $1 || '%' + """ + try: + await session.execute(query, new_domain_url) + logger.info("[DomainChange] Запрос на обновление домена выполнен успешно.") + except Exception as e: + logger.error(f"[DomainChange] Ошибка при выполнении запроса: {e}") + await message.answer(f"❌ Ошибка при обновлении домена: {e}", reply_markup=build_admin_back_kb("admin")) + return + + try: + sample = await session.fetchrow("SELECT key FROM keys LIMIT 1") + logger.info(f"[DomainChange] Пример обновленной записи: {sample}") + except Exception as e: + logger.error(f"[DomainChange] Ошибка при выборке обновленной записи: {e}") + + await message.answer(f"✅ Домен успешно изменен на {new_domain}!", reply_markup=build_admin_back_kb("admin")) + await state.clear() diff --git a/handlers/admin/panel/keyboard.py b/handlers/admin/panel/keyboard.py index f897e34f..4fab750c 100644 --- a/handlers/admin/panel/keyboard.py +++ b/handlers/admin/panel/keyboard.py @@ -33,18 +33,6 @@ def build_panel_kb() -> InlineKeyboardMarkup: return builder.as_markup() -def build_management_kb() -> InlineKeyboardMarkup: - builder = InlineKeyboardBuilder() - builder.button(text="💾 Создать резервную копию", callback_data=AdminPanelCallback(action="backups").pack()) - builder.button(text="🚫 Заблокировавшие бота", callback_data=AdminPanelCallback(action="bans").pack()) - builder.button(text="🔄 Перезагрузить бота", callback_data=AdminPanelCallback(action="restart").pack()) - builder.button(text="🌐 Сменить домен", callback_data=AdminPanelCallback(action="change_domain").pack()) - builder.button(text="🔑 Восстановить пробники", callback_data=AdminPanelCallback(action="restore_trials").pack()) - builder.row(build_admin_back_btn()) - builder.adjust(1) - return builder.as_markup() - - def build_restart_kb() -> InlineKeyboardMarkup: builder = InlineKeyboardBuilder() builder.button(text="✅ Да, перезагрузить", callback_data=AdminPanelCallback(action="restart_confirm").pack()) diff --git a/handlers/admin/panel/panel_handler.py b/handlers/admin/panel/panel_handler.py index 6e244516..328eb047 100644 --- a/handlers/admin/panel/panel_handler.py +++ b/handlers/admin/panel/panel_handler.py @@ -5,8 +5,7 @@ from aiogram.types import CallbackQuery, Message from bot import version from filters.admin import IsAdminFilter -from keyboard import AdminPanelCallback, build_management_kb, build_panel_kb - +from keyboard import AdminPanelCallback, build_panel_kb router = Router() @@ -39,11 +38,3 @@ async def handle_admin_message(message: Message, state: FSMContext): await state.clear() await message.answer(text=text, reply_markup=build_panel_kb()) - - -@router.callback_query(AdminPanelCallback.filter(F.action == "management"), IsAdminFilter()) -async def handle_management(callback_query: CallbackQuery): - await callback_query.message.edit_text( - text="🤖 Управление ботом", - reply_markup=build_management_kb(), - )