Small refactoring admin
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from aiogram import Bot, Dispatcher, Router
|
||||
from aiogram.fsm.storage.memory import MemoryStorage
|
||||
|
||||
from config import API_TOKEN, CRYPTO_BOT_ENABLE, FREEKASSA_ENABLE, YOOKASSA_ENABLE,STARS_ENABLE
|
||||
from config import API_TOKEN, CRYPTO_BOT_ENABLE, FREEKASSA_ENABLE, STARS_ENABLE, YOOKASSA_ENABLE
|
||||
from middlewares.logging import UserActivityMiddleware
|
||||
|
||||
bot = Bot(token=API_TOKEN)
|
||||
@@ -12,7 +12,7 @@ router = Router()
|
||||
from handlers import commands, notifications, pay, profile, start
|
||||
from handlers.admin import admin, admin_panel, user_editor
|
||||
from handlers.keys import key_management, keys
|
||||
from handlers.payments import cryprobot_pay, freekassa_pay, yookassa_pay, stars_pay
|
||||
from handlers.payments import cryprobot_pay, freekassa_pay, stars_pay, yookassa_pay
|
||||
|
||||
dp.include_router(admin.router)
|
||||
dp.include_router(admin_panel.router)
|
||||
|
||||
@@ -14,14 +14,16 @@ async def cmd_add_balance(message: types.Message):
|
||||
amount = float(amount)
|
||||
|
||||
if not await check_connection_exists(int(client_id)):
|
||||
await message.reply(f"Клиент с ID {client_id} не найден.")
|
||||
await message.reply(f"❌ Клиент с ID {client_id} не найден в базе данных.")
|
||||
return
|
||||
|
||||
await add_balance_to_client(int(client_id), amount)
|
||||
await message.reply(f"Баланс клиента {client_id} увеличен на {amount} у.е.")
|
||||
await message.reply(f"✅ Баланс клиента {client_id} успешно пополнен на {amount}")
|
||||
except ValueError:
|
||||
await message.reply(
|
||||
"Пожалуйста, используйте формат: /add_balance <client_id> <amount>"
|
||||
"❓ Неверный формат команды!\n"
|
||||
"Пожалуйста, используйте следующий шаблон:\n"
|
||||
"/add_balance <ID клиента> <сумма пополнения>"
|
||||
)
|
||||
except Exception as e:
|
||||
await message.reply(f"Произошла ошибка: {e}")
|
||||
await message.reply(f"🚨 Произошла непредвиденная ошибка: {e}")
|
||||
|
||||
@@ -28,23 +28,23 @@ async def handle_admin_command(message: types.Message):
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="Статистика пользователей", callback_data="user_stats"
|
||||
text="📊 Статистика пользователей", callback_data="user_stats"
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="Редактор пользователей", callback_data="user_editor")
|
||||
InlineKeyboardButton(text="👥 Управление пользователями", callback_data="user_editor")
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="Отправить сообщение всем клиентам", callback_data="send_to_alls"
|
||||
text="📢 Массовая рассылка", callback_data="send_to_alls"
|
||||
)
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="Создать бэкап", callback_data="backups"))
|
||||
builder.row(InlineKeyboardButton(text="💾 Создать резервную копию", callback_data="backups"))
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="Перезапустить бота", callback_data="restart_bot")
|
||||
InlineKeyboardButton(text="🔄 Перезагрузить бота", callback_data="restart_bot")
|
||||
)
|
||||
await bot.send_message(
|
||||
message.chat.id, "Панель администратора.", reply_markup=builder.as_markup()
|
||||
message.chat.id, "🤖 Панель администратора", reply_markup=builder.as_markup()
|
||||
)
|
||||
|
||||
|
||||
@@ -63,17 +63,17 @@ async def user_stats_menu(callback_query: CallbackQuery):
|
||||
expired_keys = total_keys - active_keys
|
||||
|
||||
stats_message = (
|
||||
f"🔹 <b>Общая статистика пользователей:</b>\n"
|
||||
f"• Всего пользователей: <b>{total_users}</b>\n"
|
||||
f"• Всего ключей: <b>{total_keys}</b>\n"
|
||||
f"• Всего рефералов: <b>{total_referrals}</b>\n"
|
||||
f"• Активные ключи: <b>{active_keys}</b>\n"
|
||||
f"• Истекшие ключи: <b>{expired_keys}</b>"
|
||||
f"📈 <b>Подробная статистика проекта:</b>\n\n"
|
||||
f"👤 Зарегистрированных пользователей: <b>{total_users}</b>\n"
|
||||
f"🔑 Всего сгенерированных ключей: <b>{total_keys}</b>\n"
|
||||
f"🤝 Привлеченных рефералов: <b>{total_referrals}</b>\n"
|
||||
f"✅ Действующих ключей: <b>{active_keys}</b>\n"
|
||||
f"❌ Просроченных ключей: <b>{expired_keys}</b>"
|
||||
)
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="Назад", callback_data="back_to_admin_menu")
|
||||
InlineKeyboardButton(text="🔙 Вернуться в меню", callback_data="back_to_admin_menu")
|
||||
)
|
||||
|
||||
await callback_query.message.edit_text(
|
||||
@@ -92,9 +92,9 @@ async def handle_send_to_all(callback_query: CallbackQuery, state: FSMContext):
|
||||
|
||||
@router.callback_query(F.data == "backups", IsAdminFilter())
|
||||
async def handle_backup(message: Message):
|
||||
await message.answer("Запускаю бэкап базы данных...")
|
||||
await message.answer("💾 Инициализация резервного копирования базы данных...")
|
||||
await backup_database()
|
||||
await message.answer("Бэкап завершен и отправлен админу.")
|
||||
await message.answer("✅ Резервная копия успешно создана и отправлена администратору.")
|
||||
|
||||
|
||||
@router.callback_query(F.data == "restart_bot", IsAdminFilter)
|
||||
@@ -106,10 +106,10 @@ async def handle_restart(callback_query: CallbackQuery):
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
await callback_query.message.answer("Бот успешно перезапущен.")
|
||||
await callback_query.message.answer("🔄 Бот успешно перезапущен.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
await callback_query.message.answer(
|
||||
f"Бот будет перезапущен через 30 секунд {e.stderr}"
|
||||
f"⚠️ Перезагрузка бота будет выполнена через 30 секунд. Детали: {e.stderr}"
|
||||
)
|
||||
|
||||
|
||||
@@ -118,15 +118,15 @@ async def user_editor_menu(callback_query: CallbackQuery):
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="Поиск по имени ключа", callback_data="search_by_key_name"
|
||||
text="🔍 Поиск по названию ключа", callback_data="search_by_key_name"
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="Поиск по tg_id", callback_data="search_by_tg_id")
|
||||
InlineKeyboardButton(text="🆔 Поиск по Telegram ID", callback_data="search_by_tg_id")
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="Назад", callback_data="back_to_admin_menu"))
|
||||
builder.row(InlineKeyboardButton(text="🔙 Вернуться назад", callback_data="back_to_admin_menu"))
|
||||
await callback_query.message.edit_text(
|
||||
"Выберите метод поиска:", reply_markup=builder.as_markup()
|
||||
"👇 Выберите способ поиска пользователя:", reply_markup=builder.as_markup()
|
||||
)
|
||||
|
||||
|
||||
@@ -141,24 +141,23 @@ async def back_to_admin_menu(callback_query: CallbackQuery):
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="Статистика пользователей", callback_data="user_stats"
|
||||
text="📊 Статистика пользователей", callback_data="user_stats"
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="Редактор пользователей", callback_data="user_editor")
|
||||
InlineKeyboardButton(text="👥 Управление пользователями", callback_data="user_editor")
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="Отправить сообщение всем клиентам",
|
||||
callback_data="send_to_alls",
|
||||
text="📢 Массовая рассылка", callback_data="send_to_alls"
|
||||
)
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="Создать бэкап", callback_data="backups"))
|
||||
builder.row(InlineKeyboardButton(text="💾 Создать резервную копию", callback_data="backups"))
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="Перезапустить бота", callback_data="restart_bot")
|
||||
InlineKeyboardButton(text="🔄 Перезагрузить бота", callback_data="restart_bot")
|
||||
)
|
||||
await bot.send_message(
|
||||
tg_id, "Панель администратора", reply_markup=builder.as_markup()
|
||||
tg_id, "🤖 Панель администратора", reply_markup=builder.as_markup()
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class UserEditorState(StatesGroup):
|
||||
|
||||
@router.callback_query(F.data == "search_by_tg_id")
|
||||
async def prompt_tg_id(callback_query: CallbackQuery, state: FSMContext):
|
||||
await callback_query.message.edit_text("Введите tg_id клиента:")
|
||||
await callback_query.message.edit_text("🔍 Введите Telegram ID клиента:")
|
||||
await state.set_state(UserEditorState.waiting_for_tg_id)
|
||||
|
||||
|
||||
@@ -73,10 +73,10 @@ async def handle_tg_id_input(message: types.Message, state: FSMContext):
|
||||
)
|
||||
|
||||
user_info = (
|
||||
f"Информация о пользователе:\n"
|
||||
f"Баланс: <b>{balance}</b>\n"
|
||||
f"Количество рефералов: <b>{referral_count}</b>\n"
|
||||
f"Ключи (для редактирования нажмите на ключ):"
|
||||
f"📊 Информация о пользователе:\n"
|
||||
f"💰 Баланс: <b>{balance}</b>\n"
|
||||
f"👥 Количество рефералов: <b>{referral_count}</b>\n"
|
||||
f"🔑 Ключи (для редактирования нажмите на ключ):"
|
||||
)
|
||||
await message.reply(user_info, reply_markup=keyboard, parse_mode="HTML")
|
||||
await state.set_state(UserEditorState.displaying_user_info)
|
||||
@@ -90,7 +90,7 @@ async def process_balance_change(callback_query: CallbackQuery, state: FSMContex
|
||||
tg_id = int(callback_query.data.split("_")[2])
|
||||
await state.update_data(tg_id=tg_id)
|
||||
|
||||
await callback_query.message.edit_text("Введите новую сумму баланса:")
|
||||
await callback_query.message.edit_text("💸 Введите новую сумму баланса:")
|
||||
await callback_query.answer()
|
||||
await state.set_state(UserEditorState.waiting_for_new_balance)
|
||||
|
||||
@@ -99,7 +99,7 @@ async def process_balance_change(callback_query: CallbackQuery, state: FSMContex
|
||||
async def handle_new_balance_input(message: types.Message, state: FSMContext):
|
||||
if not message.text.isdigit() or int(message.text) < 0:
|
||||
await message.reply(
|
||||
"Пожалуйста, введите корректную сумму для изменения баланса."
|
||||
"❌ Пожалуйста, введите корректную сумму для изменения баланса."
|
||||
)
|
||||
return
|
||||
|
||||
@@ -113,7 +113,7 @@ async def handle_new_balance_input(message: types.Message, state: FSMContext):
|
||||
"UPDATE connections SET balance = $1 WHERE tg_id = $2", new_balance, tg_id
|
||||
)
|
||||
|
||||
response_message = f"Баланс успешно изменен на <b>{new_balance}</b>."
|
||||
response_message = f"✅ Баланс успешно изменен на <b>{new_balance}</b>."
|
||||
|
||||
back_button = InlineKeyboardButton(
|
||||
text="Назад в меню админа", callback_data="back_to_user_editor"
|
||||
@@ -215,7 +215,7 @@ async def process_key_edit(callback_query: CallbackQuery):
|
||||
|
||||
@router.callback_query(F.data == "search_by_key_name")
|
||||
async def prompt_key_name(callback_query: CallbackQuery, state: FSMContext):
|
||||
await callback_query.message.edit_text("Введите имя ключа:")
|
||||
await callback_query.message.edit_text("🔑 Введите имя ключа:")
|
||||
await state.set_state(UserEditorState.waiting_for_key_name)
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ async def handle_key_name_input(message: types.Message, state: FSMContext):
|
||||
)
|
||||
|
||||
if not user_records:
|
||||
await message.reply("Пользователь с указанным именем ключа не найден.")
|
||||
await message.reply("🚫 Пользователь с указанным именем ключа не найден.")
|
||||
await state.clear()
|
||||
return
|
||||
|
||||
@@ -256,10 +256,10 @@ async def handle_key_name_input(message: types.Message, state: FSMContext):
|
||||
)
|
||||
|
||||
response_messages.append(
|
||||
f"Ключ: <pre>{key}</pre>\n"
|
||||
f"Дата истечения: <b>{expiry_date}</b>\n"
|
||||
f"Баланс пользователя: <b>{balance}</b>\n"
|
||||
f"Сервер: <b>{server_name}</b>"
|
||||
f"🔑 Ключ: <pre>{key}</pre>\n"
|
||||
f"⏰ Дата истечения: <b>{expiry_date}</b>\n"
|
||||
f"💰 Баланс пользователя: <b>{balance}</b>\n"
|
||||
f"🌐 Сервер: <b>{server_name}</b>"
|
||||
)
|
||||
|
||||
change_expiry_button = InlineKeyboardButton(
|
||||
@@ -292,7 +292,7 @@ async def handle_key_name_input(message: types.Message, state: FSMContext):
|
||||
async def prompt_expiry_change(callback_query: CallbackQuery, state: FSMContext):
|
||||
email = callback_query.data.split("|")[1]
|
||||
await callback_query.message.edit_text(
|
||||
f"Введите новое время истечения для ключа <b>{email}</b> в формате <code>YYYY-MM-DD HH:MM:SS</code>:",
|
||||
f"⏳ Введите новое время истечения для ключа <b>{email}</b> в формате <code>YYYY-MM-DD HH:MM:SS</code>:",
|
||||
parse_mode="HTML",
|
||||
)
|
||||
await state.update_data(email=email)
|
||||
@@ -345,7 +345,7 @@ async def handle_expiry_time_input(message: types.Message, state: FSMContext):
|
||||
|
||||
await update_key_expiry(client_id, expiry_time)
|
||||
|
||||
response_message = f"Время истечения ключа для клиента {client_id} ({email}) успешно обновлено на всех серверах."
|
||||
response_message = f"✅ Время истечения ключа для клиента {client_id} ({email}) успешно обновлено на всех серверах."
|
||||
|
||||
back_button = InlineKeyboardButton(
|
||||
text="Назад", callback_data="back_to_user_editor"
|
||||
@@ -360,7 +360,7 @@ async def handle_expiry_time_input(message: types.Message, state: FSMContext):
|
||||
await conn.close()
|
||||
|
||||
except ValueError:
|
||||
await message.reply("Пожалуйста, используйте формат: YYYY-MM-DD HH:MM:SS.")
|
||||
await message.reply("❌ Пожалуйста, используйте формат: YYYY-MM-DD HH:MM:SS.")
|
||||
except Exception as e:
|
||||
await message.reply(f"Произошла ошибка: {e}")
|
||||
|
||||
@@ -403,7 +403,7 @@ async def process_callback_delete_key(callback_query: types.CallbackQuery):
|
||||
)
|
||||
|
||||
await bot.edit_message_text(
|
||||
"<b>Вы уверены, что хотите удалить ключ?</b>",
|
||||
"<b>❓ Вы уверены, что хотите удалить ключ?</b>",
|
||||
chat_id=tg_id,
|
||||
message_id=callback_query.message.message_id,
|
||||
reply_markup=confirmation_keyboard,
|
||||
@@ -429,7 +429,7 @@ async def process_callback_confirm_delete(callback_query: types.CallbackQuery):
|
||||
|
||||
if record:
|
||||
email = record["email"]
|
||||
response_message = "Ключ успешно удален."
|
||||
response_message = "✅ Ключ успешно удален."
|
||||
back_button = types.InlineKeyboardButton(
|
||||
text="Назад", callback_data="view_keys"
|
||||
)
|
||||
@@ -453,7 +453,7 @@ async def process_callback_confirm_delete(callback_query: types.CallbackQuery):
|
||||
reply_markup=keyboard,
|
||||
)
|
||||
else:
|
||||
response_message = "Ключ не найден или уже удален."
|
||||
response_message = "🚫 Ключ не найден или уже удален."
|
||||
back_button = types.InlineKeyboardButton(
|
||||
text="Назад", callback_data="view_keys"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user