from datetime import datetime, timedelta, timezone from aiogram import F, Router from aiogram.fsm.context import FSMContext from aiogram.types import CallbackQuery, Message from aiogram.utils.keyboard import InlineKeyboardBuilder from sqlalchemy import delete from sqlalchemy.dialects.postgresql import insert as pg_insert from sqlalchemy.ext.asyncio import AsyncSession from handlers.buttons import BACK from database.models import ManualBan from filters.admin import IsAdminFilter from .keyboard import AdminUserEditorCallback, build_editor_btn, build_editor_kb, build_user_ban_type_kb from .users_states import BanUserStates router = Router() @router.callback_query( AdminUserEditorCallback.filter(F.action == "users_ban"), IsAdminFilter(), ) async def handle_user_ban(callback: CallbackQuery, callback_data: AdminUserEditorCallback, state: FSMContext): await state.clear() await state.update_data(tg_id=callback_data.tg_id) await callback.message.edit_text( text="🚫 Π’Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ Ρ‚ΠΈΠΏ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ:", reply_markup=build_user_ban_type_kb(callback_data.tg_id), ) @router.callback_query( AdminUserEditorCallback.filter(F.action == "users_ban_forever"), IsAdminFilter(), ) async def handle_ban_forever_start(callback: CallbackQuery, callback_data: AdminUserEditorCallback, state: FSMContext): await state.set_state(BanUserStates.waiting_for_forever_reason) await state.update_data(tg_id=callback_data.tg_id) kb = InlineKeyboardBuilder() kb.row(build_editor_btn(BACK, tg_id=callback_data.tg_id, edit=True)) await callback.message.edit_text( text="✏️ Π’Π²Π΅Π΄ΠΈΡ‚Π΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ постоянной Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ (ΠΈΠ»ΠΈ -, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ):", reply_markup=kb.as_markup(), ) @router.message(BanUserStates.waiting_for_forever_reason, IsAdminFilter()) async def handle_ban_forever_reason_input(message: Message, state: FSMContext, session: AsyncSession): reason = message.text.strip() if reason == "-": reason = None user_data = await state.get_data() tg_id = user_data.get("tg_id") stmt = ( pg_insert(ManualBan) .values( tg_id=tg_id, reason=reason, banned_by=message.from_user.id, until=None, banned_at=datetime.now(timezone.utc), ) .on_conflict_do_update( index_elements=[ManualBan.tg_id], set_={ "reason": reason, "until": None, "banned_by": message.from_user.id, "banned_at": datetime.now(timezone.utc), }, ) ) await session.execute(stmt) await session.commit() await state.clear() await message.answer( text=(f"βœ… ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ {tg_id} Π·Π°Π±Π°Π½Π΅Π½ навсСгда.{f'\nπŸ“„ ΠŸΡ€ΠΈΡ‡ΠΈΠ½Π°: {reason}' if reason else ''}"), reply_markup=build_editor_kb(tg_id, edit=True), ) @router.callback_query( AdminUserEditorCallback.filter(F.action == "users_ban_temporary"), IsAdminFilter(), ) async def handle_ban_temporary(callback: CallbackQuery, callback_data: AdminUserEditorCallback, state: FSMContext): await state.set_state(BanUserStates.waiting_for_reason) await state.update_data(tg_id=callback_data.tg_id) kb = InlineKeyboardBuilder() kb.row(build_editor_btn(BACK, tg_id=callback_data.tg_id, edit=True)) await callback.message.edit_text( text="✏️ Π’Π²Π΅Π΄ΠΈΡ‚Π΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ (ΠΈΠ»ΠΈ -, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ):", reply_markup=kb.as_markup(), ) @router.message(BanUserStates.waiting_for_reason, IsAdminFilter()) async def handle_ban_reason_input(message: Message, state: FSMContext): await state.update_data(reason=message.text.strip()) await state.set_state(BanUserStates.waiting_for_ban_duration) user_data = await state.get_data() tg_id = user_data.get("tg_id") kb = InlineKeyboardBuilder() kb.row(build_editor_btn(BACK, tg_id=tg_id, edit=True)) await message.answer( "⏳ Π’Π²Π΅Π΄ΠΈΡ‚Π΅ срок Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π² днях (0 β€” навсСгда):", reply_markup=kb.as_markup(), ) @router.message(BanUserStates.waiting_for_ban_duration, IsAdminFilter()) async def handle_ban_duration_input(message: Message, state: FSMContext, session: AsyncSession): user_data = await state.get_data() tg_id = user_data.get("tg_id") reason = user_data.get("reason") if reason == "-": reason = None try: days = int(message.text.strip()) if days < 1: await message.answer("❗ Π£ΠΊΠ°ΠΆΠΈΡ‚Π΅ срок ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ Π² 1 дСнь.") return until = datetime.now(timezone.utc) + timedelta(days=days) stmt = ( pg_insert(ManualBan) .values( tg_id=tg_id, reason=reason, banned_by=message.from_user.id, until=until, banned_at=datetime.now(timezone.utc), ) .on_conflict_do_update( index_elements=[ManualBan.tg_id], set_={ "reason": reason, "until": until, "banned_at": datetime.now(timezone.utc), "banned_by": message.from_user.id, }, ) ) await session.execute(stmt) await session.commit() text = ( f"βœ… ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ {tg_id} Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π·Π°Π±Π°Π½Π΅Π½ Π΄ΠΎ {until:%Y-%m-%d %H:%M} ΠΏΠΎ UTC." f"{f'\nπŸ“„ ΠŸΡ€ΠΈΡ‡ΠΈΠ½Π°: {reason}' if reason else ''}" ) await message.answer(text=text, reply_markup=build_editor_kb(tg_id, edit=True)) except ValueError: await message.answer("❗ Π’Π²Π΅Π΄ΠΈΡ‚Π΅ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ΅ число Π΄Π½Π΅ΠΉ.") finally: await state.clear() @router.callback_query( AdminUserEditorCallback.filter(F.action == "users_ban_shadow"), IsAdminFilter(), ) async def handle_ban_shadow(callback: CallbackQuery, callback_data: AdminUserEditorCallback, session: AsyncSession): stmt = ( pg_insert(ManualBan) .values( tg_id=callback_data.tg_id, reason="shadow", banned_by=callback.from_user.id, until=None, banned_at=datetime.now(timezone.utc), ) .on_conflict_do_update( index_elements=[ManualBan.tg_id], set_={ "reason": "shadow", "until": None, "banned_by": callback.from_user.id, "banned_at": datetime.now(timezone.utc), }, ) ) await session.execute(stmt) await session.commit() await callback.message.edit_text( text=f"πŸ‘» ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ {callback_data.tg_id} ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» Ρ‚Π΅Π½Π΅Π²ΠΎΠΉ Π±Π°Π½.", reply_markup=build_editor_kb(callback_data.tg_id, edit=True), ) @router.callback_query( AdminUserEditorCallback.filter(F.action == "users_unban"), IsAdminFilter(), ) async def handle_user_unban( callback: CallbackQuery, callback_data: AdminUserEditorCallback, session: AsyncSession, ): await session.execute(delete(ManualBan).where(ManualBan.tg_id == callback_data.tg_id)) await session.commit() text = ( f"βœ… ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ {callback_data.tg_id} Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½. НаТмитС ΠΊΠ½ΠΎΠΏΠΊΡƒ Π½ΠΈΠΆΠ΅ для Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° Π² ΠΏΡ€ΠΎΡ„ΠΈΠ»ΡŒ." ) await callback.message.edit_text(text=text, reply_markup=build_editor_kb(callback_data.tg_id, edit=True))