ORM update and lots of improvements
This commit is contained in:
@@ -1,59 +1,57 @@
|
||||
from typing import Any
|
||||
|
||||
from aiogram import F, Router
|
||||
from aiogram.types import BufferedInputFile, CallbackQuery
|
||||
|
||||
from database import delete_user_data
|
||||
from filters.admin import IsAdminFilter
|
||||
|
||||
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
|
||||
from .keyboard import build_bans_kb
|
||||
import csv
|
||||
import io
|
||||
|
||||
from aiogram import F, Router
|
||||
from aiogram.types import BufferedInputFile, CallbackQuery
|
||||
from sqlalchemy import delete, text
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from database import delete_user_data
|
||||
from database.models import ManualBan
|
||||
from filters.admin import IsAdminFilter
|
||||
from logger import logger
|
||||
|
||||
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
|
||||
from .keyboard import build_bans_kb
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
@router.callback_query(AdminPanelCallback.filter(F.action == "bans"), IsAdminFilter())
|
||||
async def handle_bans(callback_query: CallbackQuery):
|
||||
text = (
|
||||
text_ = (
|
||||
"🚫 <b>Управление банами</b>\n\n"
|
||||
"📛 <b>Забанившие бота</b> — пользователи, которые заблокировали бота вручную.\n"
|
||||
"🔒 <b>Ручной бан</b> — пользователи, которых вы забанили через админку.\n\n"
|
||||
"⬇ Выберите нужный раздел:"
|
||||
)
|
||||
|
||||
await callback_query.message.edit_text(
|
||||
text=text,
|
||||
reply_markup=build_bans_kb(),
|
||||
)
|
||||
await callback_query.message.edit_text(text=text_, reply_markup=build_bans_kb())
|
||||
|
||||
|
||||
@router.callback_query(
|
||||
AdminPanelCallback.filter(F.action == "bans_export"),
|
||||
IsAdminFilter(),
|
||||
AdminPanelCallback.filter(F.action == "bans_export"), IsAdminFilter()
|
||||
)
|
||||
async def handle_bans_export(callback_query: CallbackQuery, session: Any):
|
||||
async def handle_bans_export(callback_query: CallbackQuery, session: AsyncSession):
|
||||
kb = build_admin_back_kb("management")
|
||||
|
||||
try:
|
||||
banned_users = await session.fetch("SELECT tg_id, blocked_at FROM blocked_users")
|
||||
result = await session.execute(text("SELECT tg_id FROM blocked_users"))
|
||||
banned_users = result.all()
|
||||
|
||||
csv_output = io.StringIO()
|
||||
writer = csv.writer(csv_output)
|
||||
writer.writerow(["tg_id", "blocked_at"])
|
||||
writer.writerow(["tg_id"])
|
||||
|
||||
for user in banned_users:
|
||||
writer.writerow([user["tg_id"], user["blocked_at"]])
|
||||
writer.writerow([user.tg_id])
|
||||
|
||||
csv_output.seek(0)
|
||||
|
||||
document = BufferedInputFile(file=csv_output.getvalue().encode("utf-8"), filename="banned_users.csv")
|
||||
document = BufferedInputFile(
|
||||
file=csv_output.getvalue().encode("utf-8"), filename="banned_users.csv"
|
||||
)
|
||||
|
||||
await callback_query.message.answer_document(
|
||||
document=document,
|
||||
caption="📥 Экспорт пользователей, заблокировавших бота в CSV",
|
||||
caption="📥 Экспорт пользователей, заблокировавших бота (CSV)",
|
||||
)
|
||||
except Exception as e:
|
||||
await callback_query.message.answer(
|
||||
@@ -63,15 +61,16 @@ async def handle_bans_export(callback_query: CallbackQuery, session: Any):
|
||||
|
||||
|
||||
@router.callback_query(
|
||||
AdminPanelCallback.filter(F.action == "bans_delete_banned"),
|
||||
IsAdminFilter(),
|
||||
AdminPanelCallback.filter(F.action == "bans_delete_banned"), IsAdminFilter()
|
||||
)
|
||||
async def handle_bans_delete_banned(callback_query: CallbackQuery, session: Any):
|
||||
async def handle_bans_delete_banned(
|
||||
callback_query: CallbackQuery, session: AsyncSession
|
||||
):
|
||||
kb = build_admin_back_kb("bans")
|
||||
|
||||
try:
|
||||
blocked_users = await session.fetch("SELECT tg_id FROM blocked_users")
|
||||
blocked_ids = [record["tg_id"] for record in blocked_users]
|
||||
result = await session.execute(text("SELECT tg_id FROM blocked_users"))
|
||||
blocked_users = result.all()
|
||||
blocked_ids = [user.tg_id for user in blocked_users]
|
||||
|
||||
if not blocked_ids:
|
||||
await callback_query.message.answer(
|
||||
@@ -83,7 +82,11 @@ async def handle_bans_delete_banned(callback_query: CallbackQuery, session: Any)
|
||||
for tg_id in blocked_ids:
|
||||
await delete_user_data(session, tg_id)
|
||||
|
||||
await session.execute("DELETE FROM blocked_users WHERE tg_id = ANY($1)", blocked_ids)
|
||||
await session.execute(
|
||||
text("DELETE FROM blocked_users WHERE tg_id = ANY(:blocked_ids)"),
|
||||
{"blocked_ids": blocked_ids},
|
||||
)
|
||||
await session.commit()
|
||||
|
||||
await callback_query.message.answer(
|
||||
text=f"🗑️ Удалены данные о {len(blocked_ids)} пользователях и связанных записях.",
|
||||
@@ -96,23 +99,30 @@ async def handle_bans_delete_banned(callback_query: CallbackQuery, session: Any)
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(AdminPanelCallback.filter(F.action == "manual_bans_export"), IsAdminFilter())
|
||||
async def handle_manual_bans_export(callback_query: CallbackQuery, session: Any):
|
||||
@router.callback_query(
|
||||
AdminPanelCallback.filter(F.action == "manual_bans_export"), IsAdminFilter()
|
||||
)
|
||||
async def handle_manual_bans_export(
|
||||
callback_query: CallbackQuery, session: AsyncSession
|
||||
):
|
||||
build_admin_back_kb("bans")
|
||||
try:
|
||||
rows = await session.fetch("SELECT tg_id, banned_at, reason, until FROM manual_bans")
|
||||
|
||||
import csv
|
||||
import io
|
||||
result = await session.execute(
|
||||
text("SELECT tg_id, banned_at, reason, until FROM manual_bans")
|
||||
)
|
||||
rows = result.all()
|
||||
|
||||
csv_output = io.StringIO()
|
||||
writer = csv.writer(csv_output)
|
||||
writer.writerow(["tg_id", "banned_at", "reason", "until"])
|
||||
|
||||
for user in rows:
|
||||
writer.writerow([user["tg_id"], user["banned_at"], user["reason"], user["until"]])
|
||||
writer.writerow([user.tg_id, user.banned_at, user.reason, user.until])
|
||||
|
||||
csv_output.seek(0)
|
||||
|
||||
document = BufferedInputFile(file=csv_output.getvalue().encode("utf-8"), filename="manual_bans.csv")
|
||||
document = BufferedInputFile(
|
||||
file=csv_output.getvalue().encode("utf-8"), filename="manual_bans.csv"
|
||||
)
|
||||
|
||||
await callback_query.message.answer_document(
|
||||
document=document,
|
||||
@@ -125,10 +135,15 @@ async def handle_manual_bans_export(callback_query: CallbackQuery, session: Any)
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(AdminPanelCallback.filter(F.action == "bans_delete_manual"), IsAdminFilter())
|
||||
async def handle_delete_manual_banned(callback_query: CallbackQuery, session):
|
||||
@router.callback_query(
|
||||
AdminPanelCallback.filter(F.action == "bans_delete_manual"), IsAdminFilter()
|
||||
)
|
||||
async def handle_delete_manual_banned(
|
||||
callback_query: CallbackQuery, session: AsyncSession
|
||||
):
|
||||
try:
|
||||
await session.execute("DELETE FROM manual_bans")
|
||||
await session.execute(delete(ManualBan))
|
||||
await session.commit()
|
||||
await callback_query.message.edit_text(
|
||||
"🗑️ Вручную забаненные пользователи удалены.",
|
||||
reply_markup=build_bans_kb(),
|
||||
@@ -136,4 +151,6 @@ async def handle_delete_manual_banned(callback_query: CallbackQuery, session):
|
||||
logger.info("[BANS] Очищены записи из manual_bans")
|
||||
except Exception as e:
|
||||
logger.error(f"[BANS] Ошибка при очистке manual_bans: {e}")
|
||||
await callback_query.message.edit_text("❌ Ошибка при удалении вручную забаненных пользователей.")
|
||||
await callback_query.message.edit_text(
|
||||
"❌ Ошибка при удалении вручную забаненных пользователей."
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user