- Added methods to delete audio moderation records and retrieve all audio records in async_db.py. - Enhanced AudioRepository with functionality to delete audio records by file name and retrieve all audio message records. - Improved logging for audio record operations to enhance monitoring and debugging capabilities. - Updated related handlers to ensure proper integration of new audio management features.
176 lines
7.9 KiB
Python
176 lines
7.9 KiB
Python
from typing import List, Optional
|
|
from datetime import datetime
|
|
|
|
from helper_bot.utils.helper_func import add_days_to_date, get_banned_users_buttons, get_banned_users_list
|
|
from helper_bot.handlers.admin.exceptions import UserAlreadyBannedError, InvalidInputError
|
|
from logs.custom_logger import logger
|
|
|
|
# Local imports - metrics
|
|
from helper_bot.utils.metrics import (
|
|
track_time,
|
|
track_errors
|
|
)
|
|
|
|
|
|
class User:
|
|
"""Модель пользователя"""
|
|
def __init__(self, user_id: int, username: str, full_name: str):
|
|
self.user_id = user_id
|
|
self.username = username
|
|
self.full_name = full_name
|
|
|
|
|
|
class BannedUser:
|
|
"""Модель заблокированного пользователя"""
|
|
def __init__(self, user_id: int, username: str, reason: str, unban_date: Optional[datetime]):
|
|
self.user_id = user_id
|
|
self.username = username
|
|
self.reason = reason
|
|
self.unban_date = unban_date
|
|
|
|
|
|
class AdminService:
|
|
"""Сервис для административных операций"""
|
|
|
|
def __init__(self, bot_db):
|
|
self.bot_db = bot_db
|
|
|
|
@track_time("get_last_users", "admin_service")
|
|
@track_errors("admin_service", "get_last_users")
|
|
async def get_last_users(self) -> List[User]:
|
|
"""Получить список последних пользователей"""
|
|
try:
|
|
users_data = await self.bot_db.get_last_users(30)
|
|
return [
|
|
User(
|
|
user_id=user[1],
|
|
username='Неизвестно',
|
|
full_name=user[0]
|
|
)
|
|
for user in users_data
|
|
]
|
|
except Exception as e:
|
|
logger.error(f"Ошибка при получении списка последних пользователей: {e}")
|
|
raise
|
|
|
|
@track_time("get_banned_users", "admin_service")
|
|
@track_errors("admin_service", "get_banned_users")
|
|
async def get_banned_users(self) -> List[BannedUser]:
|
|
"""Получить список заблокированных пользователей"""
|
|
try:
|
|
banned_users_data = await self.bot_db.get_banned_users_from_db()
|
|
banned_users = []
|
|
for user_data in banned_users_data:
|
|
user_id, reason, unban_date = user_data
|
|
# Получаем username и full_name из таблицы users
|
|
username = await self.bot_db.get_username(user_id)
|
|
full_name = await self.bot_db.get_full_name_by_id(user_id)
|
|
user_name = username or full_name or f"User_{user_id}"
|
|
|
|
banned_users.append(BannedUser(
|
|
user_id=user_id,
|
|
username=user_name,
|
|
reason=reason,
|
|
unban_date=unban_date
|
|
))
|
|
return banned_users
|
|
except Exception as e:
|
|
logger.error(f"Ошибка при получении списка заблокированных пользователей: {e}")
|
|
raise
|
|
|
|
@track_time("get_user_by_username", "admin_service")
|
|
@track_errors("admin_service", "get_user_by_username")
|
|
async def get_user_by_username(self, username: str) -> Optional[User]:
|
|
"""Получить пользователя по username"""
|
|
try:
|
|
user_id = await self.bot_db.get_user_id_by_username(username)
|
|
if not user_id:
|
|
return None
|
|
|
|
full_name = await self.bot_db.get_full_name_by_id(user_id)
|
|
return User(
|
|
user_id=user_id,
|
|
username=username,
|
|
full_name=full_name or 'Неизвестно'
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Ошибка при поиске пользователя по username {username}: {e}")
|
|
raise
|
|
|
|
@track_time("get_user_by_id", "admin_service")
|
|
@track_errors("admin_service", "get_user_by_id")
|
|
async def get_user_by_id(self, user_id: int) -> Optional[User]:
|
|
"""Получить пользователя по ID"""
|
|
try:
|
|
user_info = await self.bot_db.get_user_by_id(user_id)
|
|
if not user_info:
|
|
return None
|
|
|
|
return User(
|
|
user_id=user_id,
|
|
username=user_info.username or 'Неизвестно',
|
|
full_name=user_info.full_name or 'Неизвестно'
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Ошибка при поиске пользователя по ID {user_id}: {e}")
|
|
raise
|
|
|
|
@track_time("ban_user", "admin_service")
|
|
@track_errors("admin_service", "ban_user")
|
|
async def ban_user(self, user_id: int, username: str, reason: str, ban_days: Optional[int]) -> None:
|
|
"""Заблокировать пользователя"""
|
|
try:
|
|
# Проверяем, не заблокирован ли уже пользователь
|
|
if await self.bot_db.check_user_in_blacklist(user_id):
|
|
raise UserAlreadyBannedError(f"Пользователь {user_id} уже заблокирован")
|
|
|
|
# Рассчитываем дату разблокировки
|
|
date_to_unban = None
|
|
if ban_days is not None:
|
|
date_to_unban = add_days_to_date(ban_days)
|
|
|
|
# Сохраняем в БД (username больше не передается, так как не используется в новой схеме)
|
|
await self.bot_db.set_user_blacklist(user_id, None, reason, date_to_unban)
|
|
|
|
logger.info(f"Пользователь {user_id} ({username}) заблокирован. Причина: {reason}, срок: {ban_days} дней")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Ошибка при блокировке пользователя {user_id}: {e}")
|
|
raise
|
|
|
|
@track_time("unban_user", "admin_service")
|
|
@track_errors("admin_service", "unban_user")
|
|
async def unban_user(self, user_id: int) -> None:
|
|
"""Разблокировать пользователя"""
|
|
try:
|
|
await self.bot_db.delete_user_blacklist(user_id)
|
|
logger.info(f"Пользователь {user_id} разблокирован")
|
|
except Exception as e:
|
|
logger.error(f"Ошибка при разблокировке пользователя {user_id}: {e}")
|
|
raise
|
|
|
|
@track_time("validate_user_input", "admin_service")
|
|
@track_errors("admin_service", "validate_user_input")
|
|
async def validate_user_input(self, input_text: str) -> int:
|
|
"""Валидация введенного ID пользователя"""
|
|
try:
|
|
user_id = int(input_text.strip())
|
|
if user_id <= 0:
|
|
raise InvalidInputError("ID пользователя должен быть положительным числом")
|
|
return user_id
|
|
except ValueError:
|
|
raise InvalidInputError("ID пользователя должен быть числом")
|
|
|
|
@track_time("get_banned_users_for_display", "admin_service")
|
|
@track_errors("admin_service", "get_banned_users_for_display")
|
|
async def get_banned_users_for_display(self, page: int = 0) -> tuple[str, list]:
|
|
"""Получить данные заблокированных пользователей для отображения"""
|
|
try:
|
|
message_text = await get_banned_users_list(page, self.bot_db)
|
|
|
|
buttons_list = await get_banned_users_buttons(self.bot_db)
|
|
return message_text, buttons_list
|
|
except Exception as e:
|
|
logger.error(f"Ошибка при получении данных заблокированных пользователей: {e}")
|
|
raise
|