From 18d3b4246a35c8f632464a53d65c6aa031659fb4 Mon Sep 17 00:00:00 2001 From: Vladless Date: Sat, 26 Apr 2025 11:14:13 +0300 Subject: [PATCH] add format day in csv/maintenance mode --- handlers/admin/management/keyboard.py | 5 +++++ .../admin/management/management_handler.py | 12 +++++++++++ middlewares/__init__.py | 17 +++------------- middlewares/maintenance.py | 20 +++++++++++++++++++ utils/csv_export.py | 8 ++++++-- 5 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 middlewares/maintenance.py diff --git a/handlers/admin/management/keyboard.py b/handlers/admin/management/keyboard.py index 09c7a379..b98a5666 100644 --- a/handlers/admin/management/keyboard.py +++ b/handlers/admin/management/keyboard.py @@ -1,6 +1,8 @@ from aiogram.types import InlineKeyboardMarkup from aiogram.utils.keyboard import InlineKeyboardBuilder +from middlewares import maintenance + from ..panel.keyboard import AdminPanelCallback, build_admin_back_btn @@ -11,6 +13,9 @@ def build_management_kb() -> InlineKeyboardMarkup: 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()) + maintenance_text = "🛠️ Выключить тех. работы" if maintenance.maintenance_mode else "🛠️ Включить тех. работы" + builder.button(text=maintenance_text, callback_data=AdminPanelCallback(action="toggle_maintenance").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 index 3467161f..176d3bfc 100644 --- a/handlers/admin/management/management_handler.py +++ b/handlers/admin/management/management_handler.py @@ -9,6 +9,7 @@ from logger import logger from ..panel.keyboard import build_admin_back_kb from .keyboard import AdminPanelCallback, build_management_kb +from middlewares import maintenance router = Router() @@ -73,3 +74,14 @@ async def process_new_domain(message: Message, state: FSMContext, session: Conne await message.answer(f"✅ Домен успешно изменен на {new_domain}!", reply_markup=build_admin_back_kb("admin")) await state.clear() + + +@router.callback_query(AdminPanelCallback.filter(F.action == "toggle_maintenance")) +async def toggle_maintenance_mode(callback: CallbackQuery): + + maintenance.maintenance_mode = not maintenance.maintenance_mode + + new_status = "включён" if maintenance.maintenance_mode else "выключен" + await callback.answer(f"🛠️ Режим обслуживания {new_status}.", show_alert=True) + + await callback.message.edit_reply_markup(reply_markup=build_management_kb()) \ No newline at end of file diff --git a/middlewares/__init__.py b/middlewares/__init__.py index de2c7b64..51e4b236 100644 --- a/middlewares/__init__.py +++ b/middlewares/__init__.py @@ -8,6 +8,8 @@ from .loggings import LoggingMiddleware from .session import SessionMiddleware from .throttling import ThrottlingMiddleware from .user import UserMiddleware +from .maintenance import MaintenanceModeMiddleware + def register_middleware( @@ -16,40 +18,27 @@ def register_middleware( exclude: Iterable[str] | None = None, ) -> None: """Регистрирует middleware в диспетчере. - - Args: - dispatcher: Экземпляр диспетчера Aiogram - middlewares: Опциональный список middleware для регистрации. - Если не указан, регистрируются все стандартные middleware. - exclude: Опциональный список имен middleware, которые нужно исключить из регистрации. - Применяется только если middlewares не указан. """ - # Если middleware не указаны, используем стандартный набор if middlewares is None: - # Словарь всех доступных middleware available_middlewares = { "admin": AdminMiddleware(), "session": SessionMiddleware(), + "maintenance": MaintenanceModeMiddleware(), "logging": LoggingMiddleware(), "throttling": ThrottlingMiddleware(), "user": UserMiddleware(), } - # Фильтруем middleware по списку исключений exclude_set = set(exclude or []) middlewares = [middleware for name, middleware in available_middlewares.items() if name not in exclude_set] - # Регистрируем middleware для всех типов обработчиков handlers = [ dispatcher.message, dispatcher.callback_query, dispatcher.inline_query, - # Можно добавить другие типы обработчиков при необходимости ] - # Регистрируем каждый middleware для каждого типа обработчика for middleware in middlewares: - # Если передан класс, а не экземпляр, создаем экземпляр if isinstance(middleware, type): middleware = middleware() diff --git a/middlewares/maintenance.py b/middlewares/maintenance.py new file mode 100644 index 00000000..bbcef0a6 --- /dev/null +++ b/middlewares/maintenance.py @@ -0,0 +1,20 @@ +from aiogram import BaseMiddleware +from aiogram.types import Message, CallbackQuery +from config import ADMIN_ID + +maintenance_mode = False + +class MaintenanceModeMiddleware(BaseMiddleware): + async def __call__(self, handler, event, data): + if maintenance_mode: + user_id = None + if isinstance(event, Message): + user_id = event.from_user.id + elif isinstance(event, CallbackQuery): + user_id = event.from_user.id + + if user_id and user_id not in ADMIN_ID: + await event.answer("⚙️ Бот временно недоступен. Ведутся технические работы.") + return + + return await handler(event, data) diff --git a/utils/csv_export.py b/utils/csv_export.py index be605649..40d99dca 100644 --- a/utils/csv_export.py +++ b/utils/csv_export.py @@ -1,4 +1,5 @@ import csv +from datetime import datetime from io import StringIO from typing import Any @@ -172,7 +173,7 @@ async def export_hot_leads_csv(session: Any) -> BufferedInputFile: async def export_keys_csv(session) -> BufferedInputFile: """ - Экспорт подписок в CSV. + Экспорт подписок в CSV с нормальными датами. """ keys = await session.fetch(""" SELECT tg_id, client_id, email, created_at, expiry_time, key, server_id, is_frozen, alias @@ -184,9 +185,12 @@ async def export_keys_csv(session) -> BufferedInputFile: buffer.write("tg_id,client_id,email,created_at,expiry_time,key,server_id,is_frozen,alias\n") for row in keys: + created_at = datetime.utcfromtimestamp(row['created_at'] / 1000).strftime("%Y-%m-%d %H:%M:%S") + expiry_time = datetime.utcfromtimestamp(row['expiry_time'] / 1000).strftime("%Y-%m-%d %H:%M:%S") + buffer.write( f"{row['tg_id']},{row['client_id']},{row['email']}," - f"{row['created_at']},{row['expiry_time']},{row['key']}," + f"{created_at},{expiry_time},{row['key']}," f"{row['server_id']},{row['is_frozen']},{row['alias'] or ''}\n" )