Добавлены методы для работы с настройками авто-модерации, включая получение и установку значений, а также переключение состояний авто-публикации и авто-отклонения. Обновлены соответствующие репозитории и обработчики для интеграции новых функций в админ-панели.
Some checks are pending
CI pipeline / Test & Code Quality (push) Waiting to run
Some checks are pending
CI pipeline / Test & Code Quality (push) Waiting to run
This commit is contained in:
@@ -21,6 +21,7 @@ from helper_bot.keyboards.keyboards import (
|
||||
create_keyboard_for_ban_days,
|
||||
create_keyboard_for_ban_reason,
|
||||
create_keyboard_with_pagination,
|
||||
get_auto_moderation_keyboard,
|
||||
get_reply_keyboard_admin,
|
||||
)
|
||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||
@@ -250,6 +251,268 @@ async def get_ml_stats(message: types.Message, state: FSMContext, **kwargs):
|
||||
await message.answer(f"❌ Ошибка получения статистики: {str(e)}")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# ХЕНДЛЕРЫ АВТО-МОДЕРАЦИИ
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@admin_router.message(
|
||||
ChatTypeFilter(chat_type=["private"]),
|
||||
StateFilter("ADMIN"),
|
||||
F.text == "⚙️ Авто-модерация",
|
||||
)
|
||||
@track_time("auto_moderation_menu", "admin_handlers")
|
||||
@track_errors("admin_handlers", "auto_moderation_menu")
|
||||
async def auto_moderation_menu(
|
||||
message: types.Message, state: FSMContext, bot_db: MagicData("bot_db")
|
||||
):
|
||||
"""Меню управления авто-модерацией"""
|
||||
try:
|
||||
logger.info(
|
||||
f"Открытие меню авто-модерации пользователем: {message.from_user.full_name}"
|
||||
)
|
||||
|
||||
settings = await bot_db.get_auto_moderation_settings()
|
||||
|
||||
text = _format_auto_moderation_status(settings)
|
||||
keyboard = get_auto_moderation_keyboard(settings)
|
||||
|
||||
await message.answer(text, reply_markup=keyboard, parse_mode="HTML")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка открытия меню авто-модерации: {e}")
|
||||
await message.answer(f"❌ Ошибка: {str(e)}")
|
||||
|
||||
|
||||
def _format_auto_moderation_status(settings: dict) -> str:
|
||||
"""Форматирует текст статуса авто-модерации."""
|
||||
auto_publish = settings.get("auto_publish_enabled", False)
|
||||
auto_decline = settings.get("auto_decline_enabled", False)
|
||||
publish_threshold = settings.get("auto_publish_threshold", 0.8)
|
||||
decline_threshold = settings.get("auto_decline_threshold", 0.4)
|
||||
|
||||
publish_status = "✅ Включена" if auto_publish else "❌ Выключена"
|
||||
decline_status = "✅ Включено" if auto_decline else "❌ Выключено"
|
||||
|
||||
return (
|
||||
"⚙️ <b>Авто-модерация постов</b>\n\n"
|
||||
f"🤖 <b>Авто-публикация:</b> {publish_status}\n"
|
||||
f" Порог: RAG score ≥ <b>{publish_threshold}</b>\n\n"
|
||||
f"🚫 <b>Авто-отклонение:</b> {decline_status}\n"
|
||||
f" Порог: RAG score ≤ <b>{decline_threshold}</b>"
|
||||
)
|
||||
|
||||
|
||||
@admin_router.callback_query(F.data == "auto_mod_toggle_publish")
|
||||
@track_time("toggle_auto_publish", "admin_handlers")
|
||||
@track_errors("admin_handlers", "toggle_auto_publish")
|
||||
async def toggle_auto_publish(call: types.CallbackQuery, bot_db: MagicData("bot_db")):
|
||||
"""Переключение авто-публикации"""
|
||||
try:
|
||||
new_state = await bot_db.toggle_auto_publish()
|
||||
logger.info(
|
||||
f"Авто-публикация {'включена' if new_state else 'выключена'} "
|
||||
f"пользователем {call.from_user.full_name}"
|
||||
)
|
||||
|
||||
settings = await bot_db.get_auto_moderation_settings()
|
||||
text = _format_auto_moderation_status(settings)
|
||||
keyboard = get_auto_moderation_keyboard(settings)
|
||||
|
||||
await call.message.edit_text(text, reply_markup=keyboard, parse_mode="HTML")
|
||||
await call.answer(
|
||||
f"Авто-публикация {'включена ✅' if new_state else 'выключена ❌'}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка переключения авто-публикации: {e}")
|
||||
await call.answer(f"❌ Ошибка: {str(e)}", show_alert=True)
|
||||
|
||||
|
||||
@admin_router.callback_query(F.data == "auto_mod_toggle_decline")
|
||||
@track_time("toggle_auto_decline", "admin_handlers")
|
||||
@track_errors("admin_handlers", "toggle_auto_decline")
|
||||
async def toggle_auto_decline(call: types.CallbackQuery, bot_db: MagicData("bot_db")):
|
||||
"""Переключение авто-отклонения"""
|
||||
try:
|
||||
new_state = await bot_db.toggle_auto_decline()
|
||||
logger.info(
|
||||
f"Авто-отклонение {'включено' if new_state else 'выключено'} "
|
||||
f"пользователем {call.from_user.full_name}"
|
||||
)
|
||||
|
||||
settings = await bot_db.get_auto_moderation_settings()
|
||||
text = _format_auto_moderation_status(settings)
|
||||
keyboard = get_auto_moderation_keyboard(settings)
|
||||
|
||||
await call.message.edit_text(text, reply_markup=keyboard, parse_mode="HTML")
|
||||
await call.answer(
|
||||
f"Авто-отклонение {'включено ✅' if new_state else 'выключено ❌'}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка переключения авто-отклонения: {e}")
|
||||
await call.answer(f"❌ Ошибка: {str(e)}", show_alert=True)
|
||||
|
||||
|
||||
@admin_router.callback_query(F.data == "auto_mod_refresh")
|
||||
@track_time("refresh_auto_moderation", "admin_handlers")
|
||||
@track_errors("admin_handlers", "refresh_auto_moderation")
|
||||
async def refresh_auto_moderation(
|
||||
call: types.CallbackQuery, bot_db: MagicData("bot_db")
|
||||
):
|
||||
"""Обновление статуса авто-модерации"""
|
||||
try:
|
||||
settings = await bot_db.get_auto_moderation_settings()
|
||||
text = _format_auto_moderation_status(settings)
|
||||
keyboard = get_auto_moderation_keyboard(settings)
|
||||
|
||||
try:
|
||||
await call.message.edit_text(text, reply_markup=keyboard, parse_mode="HTML")
|
||||
except Exception as edit_error:
|
||||
if "message is not modified" in str(edit_error):
|
||||
pass # Сообщение не изменилось - это нормально
|
||||
else:
|
||||
raise
|
||||
await call.answer("🔄 Обновлено")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка обновления статуса авто-модерации: {e}")
|
||||
await call.answer(f"❌ Ошибка: {str(e)}", show_alert=True)
|
||||
|
||||
|
||||
@admin_router.callback_query(F.data == "auto_mod_threshold_publish")
|
||||
@track_time("change_publish_threshold", "admin_handlers")
|
||||
@track_errors("admin_handlers", "change_publish_threshold")
|
||||
async def change_publish_threshold(
|
||||
call: types.CallbackQuery, state: FSMContext, bot_db: MagicData("bot_db")
|
||||
):
|
||||
"""Начало изменения порога авто-публикации"""
|
||||
try:
|
||||
await state.set_state("AWAIT_PUBLISH_THRESHOLD")
|
||||
await call.message.answer(
|
||||
"📈 <b>Изменение порога авто-публикации</b>\n\n"
|
||||
"Введите новое значение порога (от 0.0 до 1.0).\n"
|
||||
"Посты с RAG score ≥ этого значения будут автоматически публиковаться.\n\n"
|
||||
"Текущее рекомендуемое значение: <b>0.8</b>",
|
||||
parse_mode="HTML",
|
||||
)
|
||||
await call.answer()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка начала изменения порога публикации: {e}")
|
||||
await call.answer(f"❌ Ошибка: {str(e)}", show_alert=True)
|
||||
|
||||
|
||||
@admin_router.callback_query(F.data == "auto_mod_threshold_decline")
|
||||
@track_time("change_decline_threshold", "admin_handlers")
|
||||
@track_errors("admin_handlers", "change_decline_threshold")
|
||||
async def change_decline_threshold(
|
||||
call: types.CallbackQuery, state: FSMContext, bot_db: MagicData("bot_db")
|
||||
):
|
||||
"""Начало изменения порога авто-отклонения"""
|
||||
try:
|
||||
await state.set_state("AWAIT_DECLINE_THRESHOLD")
|
||||
await call.message.answer(
|
||||
"📉 <b>Изменение порога авто-отклонения</b>\n\n"
|
||||
"Введите новое значение порога (от 0.0 до 1.0).\n"
|
||||
"Посты с RAG score ≤ этого значения будут автоматически отклоняться.\n\n"
|
||||
"Текущее рекомендуемое значение: <b>0.4</b>",
|
||||
parse_mode="HTML",
|
||||
)
|
||||
await call.answer()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка начала изменения порога отклонения: {e}")
|
||||
await call.answer(f"❌ Ошибка: {str(e)}", show_alert=True)
|
||||
|
||||
|
||||
@admin_router.message(
|
||||
ChatTypeFilter(chat_type=["private"]),
|
||||
StateFilter("AWAIT_PUBLISH_THRESHOLD"),
|
||||
)
|
||||
@track_time("process_publish_threshold", "admin_handlers")
|
||||
@track_errors("admin_handlers", "process_publish_threshold")
|
||||
async def process_publish_threshold(
|
||||
message: types.Message, state: FSMContext, bot_db: MagicData("bot_db")
|
||||
):
|
||||
"""Обработка нового порога авто-публикации"""
|
||||
try:
|
||||
value = float(message.text.strip().replace(",", "."))
|
||||
if not 0.0 <= value <= 1.0:
|
||||
raise ValueError("Значение должно быть от 0.0 до 1.0")
|
||||
|
||||
await bot_db.set_float_setting("auto_publish_threshold", value)
|
||||
logger.info(
|
||||
f"Порог авто-публикации изменен на {value} "
|
||||
f"пользователем {message.from_user.full_name}"
|
||||
)
|
||||
|
||||
await state.set_state("ADMIN")
|
||||
await message.answer(
|
||||
f"✅ Порог авто-публикации изменен на <b>{value}</b>",
|
||||
parse_mode="HTML",
|
||||
)
|
||||
|
||||
settings = await bot_db.get_auto_moderation_settings()
|
||||
text = _format_auto_moderation_status(settings)
|
||||
keyboard = get_auto_moderation_keyboard(settings)
|
||||
await message.answer(text, reply_markup=keyboard, parse_mode="HTML")
|
||||
|
||||
except ValueError as e:
|
||||
await message.answer(
|
||||
f"❌ Неверное значение: {e}\n"
|
||||
"Введите число от 0.0 до 1.0 (например: 0.8)"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка изменения порога публикации: {e}")
|
||||
await state.set_state("ADMIN")
|
||||
await message.answer(f"❌ Ошибка: {str(e)}")
|
||||
|
||||
|
||||
@admin_router.message(
|
||||
ChatTypeFilter(chat_type=["private"]),
|
||||
StateFilter("AWAIT_DECLINE_THRESHOLD"),
|
||||
)
|
||||
@track_time("process_decline_threshold", "admin_handlers")
|
||||
@track_errors("admin_handlers", "process_decline_threshold")
|
||||
async def process_decline_threshold(
|
||||
message: types.Message, state: FSMContext, bot_db: MagicData("bot_db")
|
||||
):
|
||||
"""Обработка нового порога авто-отклонения"""
|
||||
try:
|
||||
value = float(message.text.strip().replace(",", "."))
|
||||
if not 0.0 <= value <= 1.0:
|
||||
raise ValueError("Значение должно быть от 0.0 до 1.0")
|
||||
|
||||
await bot_db.set_float_setting("auto_decline_threshold", value)
|
||||
logger.info(
|
||||
f"Порог авто-отклонения изменен на {value} "
|
||||
f"пользователем {message.from_user.full_name}"
|
||||
)
|
||||
|
||||
await state.set_state("ADMIN")
|
||||
await message.answer(
|
||||
f"✅ Порог авто-отклонения изменен на <b>{value}</b>",
|
||||
parse_mode="HTML",
|
||||
)
|
||||
|
||||
settings = await bot_db.get_auto_moderation_settings()
|
||||
text = _format_auto_moderation_status(settings)
|
||||
keyboard = get_auto_moderation_keyboard(settings)
|
||||
await message.answer(text, reply_markup=keyboard, parse_mode="HTML")
|
||||
|
||||
except ValueError as e:
|
||||
await message.answer(
|
||||
f"❌ Неверное значение: {e}\n"
|
||||
"Введите число от 0.0 до 1.0 (например: 0.4)"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка изменения порога отклонения: {e}")
|
||||
await state.set_state("ADMIN")
|
||||
await message.answer(f"❌ Ошибка: {str(e)}")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# ХЕНДЛЕРЫ ПРОЦЕССА БАНА
|
||||
# ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user