Delete wraps
This commit is contained in:
+80
-80
@@ -15,96 +15,96 @@ from database import (
|
||||
get_tg_id_by_client_id,
|
||||
update_key_expiry,
|
||||
)
|
||||
from middlewares.admin import admin_only
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
@router.message(Command("add_balance"))
|
||||
@admin_only()
|
||||
async def cmd_add_balance(message: types.Message):
|
||||
try:
|
||||
_, client_id, amount = message.text.split()
|
||||
amount = float(amount)
|
||||
async def cmd_add_balance(message: types.Message, is_admin: bool):
|
||||
if is_admin:
|
||||
try:
|
||||
_, client_id, amount = message.text.split()
|
||||
amount = float(amount)
|
||||
|
||||
if not await check_connection_exists(int(client_id)):
|
||||
await message.reply(f"Клиент с ID {client_id} не найден.")
|
||||
return
|
||||
if not await check_connection_exists(int(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} у.е.")
|
||||
except ValueError:
|
||||
await message.reply(
|
||||
"Пожалуйста, используйте формат: /add_balance <client_id> <amount>"
|
||||
)
|
||||
except Exception as e:
|
||||
await message.reply(f"Произошла ошибка: {e}")
|
||||
await add_balance_to_client(int(client_id), amount)
|
||||
await message.reply(f"Баланс клиента {client_id} увеличен на {amount} у.е.")
|
||||
except ValueError:
|
||||
await message.reply(
|
||||
"Пожалуйста, используйте формат: /add_balance <client_id> <amount>"
|
||||
)
|
||||
except Exception as e:
|
||||
await message.reply(f"Произошла ошибка: {e}")
|
||||
|
||||
|
||||
@router.message(Command("update_key_expiry"))
|
||||
@admin_only()
|
||||
async def cmd_update_key_expiry(message: types.Message):
|
||||
try:
|
||||
parts = message.text.split(maxsplit=2)
|
||||
if len(parts) != 3:
|
||||
async def cmd_update_key_expiry(message: types.Message, is_admin: bool):
|
||||
if is_admin:
|
||||
try:
|
||||
parts = message.text.split(maxsplit=2)
|
||||
if len(parts) != 3:
|
||||
await message.reply(
|
||||
"Пожалуйста, используйте формат: /update_key_expiry <email> <expiry_time(YYYY-MM-DD HH:MM:SS)>"
|
||||
)
|
||||
return
|
||||
|
||||
_, email, expiry_time_str = parts
|
||||
expiry_time = int(
|
||||
datetime.strptime(expiry_time_str, "%Y-%m-%d %H:%M:%S").timestamp()
|
||||
* 1000
|
||||
)
|
||||
|
||||
client_id = await get_client_id_by_email(email)
|
||||
if client_id is None:
|
||||
await message.reply(f"Клиент с email {email} не найден.")
|
||||
return
|
||||
|
||||
await update_key_expiry(client_id, expiry_time)
|
||||
|
||||
conn = await asyncpg.connect(DATABASE_URL)
|
||||
try:
|
||||
record = await conn.fetchrow(
|
||||
"SELECT server_id FROM keys WHERE client_id = $1", client_id
|
||||
)
|
||||
if not record:
|
||||
await message.reply("Клиент не найден в базе данных.")
|
||||
return
|
||||
|
||||
server_id = record["server_id"]
|
||||
tg_id = await get_tg_id_by_client_id(client_id)
|
||||
|
||||
session = await login_with_credentials(
|
||||
server_id, ADMIN_USERNAME, ADMIN_PASSWORD
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Попытка обновить панель для server_id: {server_id}, tg_id: {tg_id}, client_id: {client_id}, email: {email}, expiryTime: {expiry_time}"
|
||||
)
|
||||
|
||||
success = await extend_client_key_admin(
|
||||
session, server_id, tg_id, client_id, email, expiry_time
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Статус обновления панели: {'Успешно' if success else 'Не удалось'}"
|
||||
)
|
||||
if success:
|
||||
await message.reply(
|
||||
f"Время истечения ключа для клиента {client_id} ({email}) обновлено и синхронизировано с панелью."
|
||||
)
|
||||
else:
|
||||
await message.reply(
|
||||
f"Время истечения ключа для клиента {client_id} ({email}) обновлено, но не удалось синхронизировать с панелью."
|
||||
)
|
||||
|
||||
finally:
|
||||
await conn.close()
|
||||
except ValueError:
|
||||
await message.reply(
|
||||
"Пожалуйста, используйте формат: /update_key_expiry <email> <expiry_time(YYYY-MM-DD HH:MM:SS)>"
|
||||
)
|
||||
return
|
||||
|
||||
_, email, expiry_time_str = parts
|
||||
expiry_time = int(
|
||||
datetime.strptime(expiry_time_str, "%Y-%m-%d %H:%M:%S").timestamp() * 1000
|
||||
)
|
||||
|
||||
client_id = await get_client_id_by_email(email)
|
||||
if client_id is None:
|
||||
await message.reply(f"Клиент с email {email} не найден.")
|
||||
return
|
||||
|
||||
await update_key_expiry(client_id, expiry_time)
|
||||
|
||||
conn = await asyncpg.connect(DATABASE_URL)
|
||||
try:
|
||||
record = await conn.fetchrow(
|
||||
"SELECT server_id FROM keys WHERE client_id = $1", client_id
|
||||
)
|
||||
if not record:
|
||||
await message.reply("Клиент не найден в базе данных.")
|
||||
return
|
||||
|
||||
server_id = record["server_id"]
|
||||
tg_id = await get_tg_id_by_client_id(client_id)
|
||||
|
||||
session = await login_with_credentials(
|
||||
server_id, ADMIN_USERNAME, ADMIN_PASSWORD
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Попытка обновить панель для server_id: {server_id}, tg_id: {tg_id}, client_id: {client_id}, email: {email}, expiryTime: {expiry_time}"
|
||||
)
|
||||
|
||||
success = await extend_client_key_admin(
|
||||
session, server_id, tg_id, client_id, email, expiry_time
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Статус обновления панели: {'Успешно' if success else 'Не удалось'}"
|
||||
)
|
||||
if success:
|
||||
await message.reply(
|
||||
f"Время истечения ключа для клиента {client_id} ({email}) обновлено и синхронизировано с панелью."
|
||||
)
|
||||
else:
|
||||
await message.reply(
|
||||
f"Время истечения ключа для клиента {client_id} ({email}) обновлено, но не удалось синхронизировать с панелью."
|
||||
)
|
||||
|
||||
finally:
|
||||
await conn.close()
|
||||
except ValueError:
|
||||
await message.reply(
|
||||
"Пожалуйста, используйте формат: /update_key_expiry <email> <expiry_time(YYYY-MM-DD HH:MM:SS)>"
|
||||
)
|
||||
except Exception as e:
|
||||
await message.reply(f"Произошла ошибка: {e}")
|
||||
except Exception as e:
|
||||
await message.reply(f"Произошла ошибка: {e}")
|
||||
|
||||
+104
-106
@@ -17,7 +17,6 @@ from backup import backup_database
|
||||
from bot import bot
|
||||
from config import ADMIN_ID, DATABASE_URL
|
||||
from handlers.commands import send_message_to_all_clients
|
||||
from middlewares.admin import admin_only
|
||||
|
||||
router = Router()
|
||||
|
||||
@@ -28,96 +27,100 @@ class UserEditorState(StatesGroup):
|
||||
|
||||
|
||||
@router.message(Command("admin"))
|
||||
@admin_only()
|
||||
async def handle_admin_command(message: types.Message):
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Статистика пользователей", callback_data="user_stats"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Редактор пользователей", callback_data="user_editor"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Отправить сообщение всем клиентам",
|
||||
callback_data="send_to_alls",
|
||||
)
|
||||
],
|
||||
[InlineKeyboardButton(text="Создать бэкап", callback_data="backups")],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Перезапустить бота", callback_data="restart_bot"
|
||||
)
|
||||
],
|
||||
]
|
||||
)
|
||||
await bot.send_message(
|
||||
message.chat.id, "Панель администратора", reply_markup=keyboard
|
||||
)
|
||||
async def handle_admin_command(message: types.Message, is_admin: bool):
|
||||
if is_admin:
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Статистика пользователей", callback_data="user_stats"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Редактор пользователей", callback_data="user_editor"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Отправить сообщение всем клиентам",
|
||||
callback_data="send_to_alls",
|
||||
)
|
||||
],
|
||||
[InlineKeyboardButton(text="Создать бэкап", callback_data="backups")],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Перезапустить бота", callback_data="restart_bot"
|
||||
)
|
||||
],
|
||||
]
|
||||
)
|
||||
await bot.send_message(
|
||||
message.chat.id, "Панель администратора.", reply_markup=keyboard
|
||||
)
|
||||
else:
|
||||
await bot.send_message(message.chat.id, "У вас нет доступа к этой команде.")
|
||||
|
||||
|
||||
@router.callback_query(F.data == "user_stats")
|
||||
@admin_only()
|
||||
async def user_stats_menu(callback_query: CallbackQuery):
|
||||
conn = await asyncpg.connect(DATABASE_URL)
|
||||
try:
|
||||
total_users = await conn.fetchval("SELECT COUNT(*) FROM connections")
|
||||
total_keys = await conn.fetchval("SELECT COUNT(*) FROM keys")
|
||||
total_referrals = await conn.fetchval("SELECT COUNT(*) FROM referrals")
|
||||
async def user_stats_menu(callback_query: CallbackQuery, is_admin: bool):
|
||||
if is_admin:
|
||||
conn = await asyncpg.connect(DATABASE_URL)
|
||||
try:
|
||||
total_users = await conn.fetchval("SELECT COUNT(*) FROM connections")
|
||||
total_keys = await conn.fetchval("SELECT COUNT(*) FROM keys")
|
||||
total_referrals = await conn.fetchval("SELECT COUNT(*) FROM referrals")
|
||||
|
||||
active_keys = await conn.fetchval(
|
||||
"SELECT COUNT(*) FROM keys WHERE expiry_time > $1",
|
||||
int(datetime.utcnow().timestamp() * 1000),
|
||||
)
|
||||
expired_keys = total_keys - active_keys
|
||||
active_keys = await conn.fetchval(
|
||||
"SELECT COUNT(*) FROM keys WHERE expiry_time > $1",
|
||||
int(datetime.utcnow().timestamp() * 1000),
|
||||
)
|
||||
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>"
|
||||
)
|
||||
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>"
|
||||
)
|
||||
|
||||
back_button = InlineKeyboardButton(
|
||||
text="Назад", callback_data="back_to_admin_menu"
|
||||
)
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[[back_button]])
|
||||
back_button = InlineKeyboardButton(
|
||||
text="Назад", callback_data="back_to_admin_menu"
|
||||
)
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[[back_button]])
|
||||
|
||||
await callback_query.message.edit_text(
|
||||
stats_message, reply_markup=keyboard, parse_mode="HTML"
|
||||
)
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
await callback_query.answer()
|
||||
await callback_query.message.edit_text(
|
||||
stats_message, reply_markup=keyboard, parse_mode="HTML"
|
||||
)
|
||||
finally:
|
||||
await conn.close()
|
||||
await callback_query.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "send_to_alls")
|
||||
@admin_only()
|
||||
async def handle_send_to_all(callback_query: CallbackQuery, state: FSMContext):
|
||||
await send_message_to_all_clients(callback_query.message, state, from_panel=True)
|
||||
await callback_query.answer()
|
||||
async def handle_send_to_all(
|
||||
callback_query: CallbackQuery, state: FSMContext, is_admin: bool
|
||||
):
|
||||
if is_admin:
|
||||
await send_message_to_all_clients(
|
||||
callback_query.message, state, from_panel=True
|
||||
)
|
||||
await callback_query.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "backups")
|
||||
@admin_only()
|
||||
async def handle_backup(message: Message):
|
||||
await message.answer("Запускаю бэкап базы данных...")
|
||||
await backup_database()
|
||||
await message.answer("Бэкап завершен и отправлен админу.")
|
||||
async def handle_backup(message: Message, is_admin: bool):
|
||||
if is_admin:
|
||||
await message.answer("Запускаю бэкап базы данных...")
|
||||
await backup_database()
|
||||
await message.answer("Бэкап завершен и отправлен админу.")
|
||||
|
||||
|
||||
@router.callback_query(F.data == "restart_bot")
|
||||
@admin_only()
|
||||
async def handle_restart(callback_query: CallbackQuery):
|
||||
if callback_query.from_user.id == ADMIN_ID:
|
||||
async def handle_restart(callback_query: CallbackQuery, is_admin: bool):
|
||||
if is_admin:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["sudo", "systemctl", "restart", "bot.service"],
|
||||
@@ -130,47 +133,44 @@ async def handle_restart(callback_query: CallbackQuery):
|
||||
await callback_query.message.answer(
|
||||
f"Бот будет перезапущен через 30 секунд {e.stderr}"
|
||||
)
|
||||
else:
|
||||
await callback_query.answer(
|
||||
"У вас нет доступа к этой команде.", show_alert=True
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(F.data == "user_editor")
|
||||
@admin_only()
|
||||
async def user_editor_menu(callback_query: CallbackQuery):
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Поиск по имени ключа", callback_data="search_by_key_name"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Поиск по tg_id", callback_data="search_by_tg_id"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(text="Назад", callback_data="back_to_admin_menu")
|
||||
], # Back button
|
||||
]
|
||||
)
|
||||
await callback_query.message.edit_text(
|
||||
"Выберите метод поиска:", reply_markup=keyboard
|
||||
)
|
||||
async def user_editor_menu(callback_query: CallbackQuery, is_admin: bool):
|
||||
if is_admin:
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Поиск по имени ключа", callback_data="search_by_key_name"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Поиск по tg_id", callback_data="search_by_tg_id"
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="Назад", callback_data="back_to_admin_menu"
|
||||
)
|
||||
], # Back button
|
||||
]
|
||||
)
|
||||
await callback_query.message.edit_text(
|
||||
"Выберите метод поиска:", reply_markup=keyboard
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(F.data == "back_to_admin_menu")
|
||||
@admin_only()
|
||||
async def back_to_admin_menu(callback_query: CallbackQuery):
|
||||
async def back_to_admin_menu(callback_query: CallbackQuery, is_admin: bool):
|
||||
try:
|
||||
await callback_query.message.delete()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
tg_id = callback_query.from_user.id
|
||||
if tg_id == ADMIN_ID:
|
||||
if is_admin:
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[
|
||||
@@ -198,8 +198,6 @@ async def back_to_admin_menu(callback_query: CallbackQuery):
|
||||
]
|
||||
)
|
||||
await bot.send_message(tg_id, "Панель администратора", reply_markup=keyboard)
|
||||
else:
|
||||
await bot.send_message(tg_id, "У вас нет доступа к этой команде.")
|
||||
|
||||
|
||||
async def handle_error(tg_id, callback_query, message):
|
||||
|
||||
@@ -28,30 +28,3 @@ class AdminMiddleware(BaseMiddleware):
|
||||
data["is_admin"] = True
|
||||
|
||||
return await handler(event, data)
|
||||
|
||||
|
||||
def admin_only():
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
async def wrapper(*args, **kwargs):
|
||||
# Извлекаем объект события (Message или CallbackQuery)
|
||||
event = args[0]
|
||||
|
||||
# Определяем ID пользователя
|
||||
user_id = event.from_user.id if hasattr(event, "from_user") else None
|
||||
|
||||
if user_id not in int(ADMIN_ID):
|
||||
# Можно отправить сообщение или просто return
|
||||
if isinstance(event, Message):
|
||||
await event.answer("У вас нет доступа к этой команде.")
|
||||
elif isinstance(event, CallbackQuery):
|
||||
await event.answer(
|
||||
"У вас нет доступа к этому действию.", show_alert=True
|
||||
)
|
||||
return None
|
||||
|
||||
return await func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
Reference in New Issue
Block a user