add format day in csv/maintenance mode

This commit is contained in:
Vladless
2025-04-26 11:14:13 +03:00
parent 422ce15dca
commit e1f5ee0e82
5 changed files with 46 additions and 16 deletions
+5
View File
@@ -1,6 +1,8 @@
from aiogram.types import InlineKeyboardMarkup from aiogram.types import InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder from aiogram.utils.keyboard import InlineKeyboardBuilder
from middlewares import maintenance
from ..panel.keyboard import AdminPanelCallback, build_admin_back_btn 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="restart").pack())
builder.button(text="🌐 Сменить домен", callback_data=AdminPanelCallback(action="change_domain").pack()) builder.button(text="🌐 Сменить домен", callback_data=AdminPanelCallback(action="change_domain").pack())
builder.button(text="🔑 Восстановить пробники", callback_data=AdminPanelCallback(action="restore_trials").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.row(build_admin_back_btn())
builder.adjust(1) builder.adjust(1)
return builder.as_markup() return builder.as_markup()
@@ -9,6 +9,7 @@ from logger import logger
from ..panel.keyboard import build_admin_back_kb from ..panel.keyboard import build_admin_back_kb
from .keyboard import AdminPanelCallback, build_management_kb from .keyboard import AdminPanelCallback, build_management_kb
from middlewares import maintenance
router = Router() 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 message.answer(f"✅ Домен успешно изменен на {new_domain}!", reply_markup=build_admin_back_kb("admin"))
await state.clear() 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())
+3 -14
View File
@@ -8,6 +8,8 @@ from .loggings import LoggingMiddleware
from .session import SessionMiddleware from .session import SessionMiddleware
from .throttling import ThrottlingMiddleware from .throttling import ThrottlingMiddleware
from .user import UserMiddleware from .user import UserMiddleware
from .maintenance import MaintenanceModeMiddleware
def register_middleware( def register_middleware(
@@ -16,40 +18,27 @@ def register_middleware(
exclude: Iterable[str] | None = None, exclude: Iterable[str] | None = None,
) -> None: ) -> None:
"""Регистрирует middleware в диспетчере. """Регистрирует middleware в диспетчере.
Args:
dispatcher: Экземпляр диспетчера Aiogram
middlewares: Опциональный список middleware для регистрации.
Если не указан, регистрируются все стандартные middleware.
exclude: Опциональный список имен middleware, которые нужно исключить из регистрации.
Применяется только если middlewares не указан.
""" """
# Если middleware не указаны, используем стандартный набор
if middlewares is None: if middlewares is None:
# Словарь всех доступных middleware
available_middlewares = { available_middlewares = {
"admin": AdminMiddleware(), "admin": AdminMiddleware(),
"session": SessionMiddleware(), "session": SessionMiddleware(),
"maintenance": MaintenanceModeMiddleware(),
"logging": LoggingMiddleware(), "logging": LoggingMiddleware(),
"throttling": ThrottlingMiddleware(), "throttling": ThrottlingMiddleware(),
"user": UserMiddleware(), "user": UserMiddleware(),
} }
# Фильтруем middleware по списку исключений
exclude_set = set(exclude or []) exclude_set = set(exclude or [])
middlewares = [middleware for name, middleware in available_middlewares.items() if name not in exclude_set] middlewares = [middleware for name, middleware in available_middlewares.items() if name not in exclude_set]
# Регистрируем middleware для всех типов обработчиков
handlers = [ handlers = [
dispatcher.message, dispatcher.message,
dispatcher.callback_query, dispatcher.callback_query,
dispatcher.inline_query, dispatcher.inline_query,
# Можно добавить другие типы обработчиков при необходимости
] ]
# Регистрируем каждый middleware для каждого типа обработчика
for middleware in middlewares: for middleware in middlewares:
# Если передан класс, а не экземпляр, создаем экземпляр
if isinstance(middleware, type): if isinstance(middleware, type):
middleware = middleware() middleware = middleware()
+20
View File
@@ -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)
+6 -2
View File
@@ -1,4 +1,5 @@
import csv import csv
from datetime import datetime
from io import StringIO from io import StringIO
from typing import Any from typing import Any
@@ -172,7 +173,7 @@ async def export_hot_leads_csv(session: Any) -> BufferedInputFile:
async def export_keys_csv(session) -> BufferedInputFile: async def export_keys_csv(session) -> BufferedInputFile:
""" """
Экспорт подписок в CSV. Экспорт подписок в CSV с нормальными датами.
""" """
keys = await session.fetch(""" keys = await session.fetch("""
SELECT tg_id, client_id, email, created_at, expiry_time, key, server_id, is_frozen, alias 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") buffer.write("tg_id,client_id,email,created_at,expiry_time,key,server_id,is_frozen,alias\n")
for row in keys: 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( buffer.write(
f"{row['tg_id']},{row['client_id']},{row['email']}," 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" f"{row['server_id']},{row['is_frozen']},{row['alias'] or ''}\n"
) )