Files
DutyLog/src/dutylog/application/bot/creator_dialogs/admins_management.py
T
2026-03-17 21:06:49 +03:00

375 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from aiogram.types import CallbackQuery
from aiogram_dialog import Window, DialogManager
from aiogram_dialog.widgets.text import Format, Const
from aiogram_dialog.widgets.kbd import SwitchTo, Button, Select, ScrollingGroup, Row
from dishka import FromDishka
from dishka.integrations.aiogram_dialog import inject
from dutylog.application.bot.user_dialogs.states import AdminMenuSG
from dutylog.infrastructure.database.repositories.users_repository import UsersRepository
@inject
async def get_admins_list_data(
users_repository: FromDishka[UsersRepository],
**kwargs,
) -> dict[str, str | list[tuple[str, int]]]:
all_users = await users_repository.get_all_users()
admins = [u for u in all_users if u.is_admin]
if not admins:
content = """
<blockquote>👨‍💼 <b>Администраторы</b></blockquote>
⚠️ Нет администраторов в системе.
"""
admins_list = []
else:
content = f"""
<blockquote>👨‍💼 <b>Администраторы</b></blockquote>
Всего администраторов: <code>{len(admins)}</code>
Выберите администратора для просмотра информации:
"""
admins_list = []
for admin in admins:
display_name = f"@{admin.username}" if admin.username else f"ID: {admin.id}"
if admin.first_name:
display_name = f"{admin.first_name} ({display_name})"
admins_list.append((display_name, admin.id))
return {
"content": content,
"admins": admins_list,
}
async def on_admin_selected(
callback: CallbackQuery,
widget,
dialog_manager: DialogManager,
item_id: str,
) -> None:
dialog_manager.dialog_data["selected_admin_id"] = int(item_id)
await dialog_manager.switch_to(AdminMenuSG.admin_info)
async def on_add_admin_click(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
) -> None:
await dialog_manager.switch_to(AdminMenuSG.add_admin_select_user)
@inject
async def get_admin_info_data(
users_repository: FromDishka[UsersRepository],
dialog_manager: DialogManager,
**kwargs,
) -> dict[str, str]:
admin_id = dialog_manager.dialog_data.get("selected_admin_id")
if not admin_id:
return {"content": "⚠️ Администратор не выбран"}
admin = await users_repository.get_user_by_id(int(admin_id))
if not admin:
return {"content": "⚠️ Администратор не найден"}
username = f"@{admin.username}" if admin.username else ""
first_name = admin.first_name or ""
last_name = admin.last_name or ""
content = f"""
<blockquote>👨‍💼 <b>Информация об администраторе</b></blockquote>
<b>ID:</b> <code>{admin.id}</code>
<b>Username:</b> {username}
<b>Имя:</b> <code>{first_name}</code>
<b>Фамилия:</b> <code>{last_name}</code>
<b>Дата добавления:</b> <code>{admin.created_at.strftime('%d.%m.%Y %H:%M')}</code>
"""
return {"content": content}
async def on_remove_admin_click(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
) -> None:
await dialog_manager.switch_to(AdminMenuSG.remove_admin_confirm)
@inject
async def get_remove_admin_confirm_data(
users_repository: FromDishka[UsersRepository],
dialog_manager: DialogManager,
**kwargs,
) -> dict[str, str]:
admin_id = dialog_manager.dialog_data.get("selected_admin_id")
if not admin_id:
return {"content": "⚠️ Администратор не выбран"}
admin = await users_repository.get_user_by_id(int(admin_id))
if not admin:
return {"content": "⚠️ Администратор не найден"}
username = f"@{admin.username}" if admin.username else f"ID: {admin.id}"
display_name = admin.first_name or username
content = f"""
<blockquote>⚠️ <b>Подтверждение удаления</b></blockquote>
Вы уверены, что хотите удалить администратора <b>{display_name}</b>?
Пользователь потеряет права администратора.
"""
return {"content": content}
@inject
async def on_remove_admin_confirm(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
users_repository: FromDishka[UsersRepository],
) -> None:
admin_id = dialog_manager.dialog_data.get("selected_admin_id")
if not admin_id:
await callback.answer("⚠️ Администратор не выбран", show_alert=True)
return
await users_repository.update_user(int(admin_id), is_admin=False)
await callback.answer("✅ Администратор удалён!")
await dialog_manager.switch_to(AdminMenuSG.admins_list)
async def on_remove_admin_cancel(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
) -> None:
await dialog_manager.switch_to(AdminMenuSG.admin_info)
@inject
async def get_add_admin_select_user_data(
users_repository: FromDishka[UsersRepository],
**kwargs,
) -> dict[str, str | list[tuple[str, int]]]:
all_users = await users_repository.get_all_users()
non_admin_users = [u for u in all_users if not u.is_admin]
if not non_admin_users:
content = """
<blockquote> <b>Добавить администратора</b></blockquote>
⚠️ Нет пользователей, которых можно сделать администраторами.
Все пользователи уже являются администраторами.
"""
users_list = []
else:
content = f"""
<blockquote> <b>Добавить администратора</b></blockquote>
Всего пользователей: <code>{len(non_admin_users)}</code>
Выберите пользователя для назначения администратором:
"""
users_list = []
for user in non_admin_users:
display_name = f"@{user.username}" if user.username else f"ID: {user.id}"
if user.first_name:
display_name = f"{user.first_name} ({display_name})"
users_list.append((display_name, user.id))
return {
"content": content,
"users": users_list,
}
async def on_user_selected(
callback: CallbackQuery,
widget,
dialog_manager: DialogManager,
item_id: str,
) -> None:
dialog_manager.dialog_data["selected_user_id"] = int(item_id)
await dialog_manager.switch_to(AdminMenuSG.add_admin_confirm)
@inject
async def get_add_admin_confirm_data(
users_repository: FromDishka[UsersRepository],
dialog_manager: DialogManager,
**kwargs,
) -> dict[str, str]:
user_id = dialog_manager.dialog_data.get("selected_user_id")
if not user_id:
return {"content": "⚠️ Пользователь не выбран"}
user = await users_repository.get_user_by_id(int(user_id))
if not user:
return {"content": "⚠️ Пользователь не найден"}
username = f"@{user.username}" if user.username else f"ID: {user.id}"
display_name = user.first_name or username
content = f"""
<blockquote>⚠️ <b>Подтверждение</b></blockquote>
Вы уверены, что хотите назначить <b>{display_name}</b> администратором?
Пользователь получит доступ к панели управления.
"""
return {"content": content}
@inject
async def on_add_admin_confirm(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
users_repository: FromDishka[UsersRepository],
) -> None:
user_id = dialog_manager.dialog_data.get("selected_user_id")
if not user_id:
await callback.answer("⚠️ Пользователь не выбран", show_alert=True)
return
await users_repository.update_user(int(user_id), is_admin=True)
await callback.answer("✅ Администратор добавлен!")
await dialog_manager.switch_to(AdminMenuSG.admins_list)
async def on_add_admin_cancel(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
) -> None:
await dialog_manager.switch_to(AdminMenuSG.add_admin_select_user)
async def on_back_to_main(
callback: CallbackQuery,
button: Button,
dialog_manager: DialogManager,
) -> None:
await dialog_manager.switch_to(AdminMenuSG.main)
admins_list_window = Window(
Format("{content}"),
ScrollingGroup(
Select(
Format("{item[0]}"),
id="admin_select",
item_id_getter=lambda x: x[1],
items="admins",
on_click=on_admin_selected,
),
id="admins_scroll",
width=1,
height=8,
),
Button(
Const("➕ Добавить администратора"),
id="add_admin_btn",
on_click=on_add_admin_click,
),
Button(
Const("◀️ Назад"),
id="back_to_main_from_admins",
on_click=on_back_to_main,
),
state=AdminMenuSG.admins_list,
getter=get_admins_list_data,
)
admin_info_window = Window(
Format("{content}"),
Button(
Const("🗑 Удалить администратора"),
id="remove_admin_btn",
on_click=on_remove_admin_click,
),
SwitchTo(
Const("◀️ Назад"),
id="back_to_admins_list",
state=AdminMenuSG.admins_list,
),
state=AdminMenuSG.admin_info,
getter=get_admin_info_data,
)
remove_admin_confirm_window = Window(
Format("{content}"),
Row(
Button(
Const("✅ Да"),
id="confirm_remove_admin",
on_click=on_remove_admin_confirm,
),
Button(
Const("❌ Нет"),
id="cancel_remove_admin",
on_click=on_remove_admin_cancel,
),
),
state=AdminMenuSG.remove_admin_confirm,
getter=get_remove_admin_confirm_data,
)
add_admin_select_user_window = Window(
Format("{content}"),
ScrollingGroup(
Select(
Format("{item[0]}"),
id="user_select",
item_id_getter=lambda x: x[1],
items="users",
on_click=on_user_selected,
),
id="users_scroll",
width=1,
height=8,
),
SwitchTo(
Const("◀️ Назад"),
id="back_to_admins_from_add",
state=AdminMenuSG.admins_list,
),
state=AdminMenuSG.add_admin_select_user,
getter=get_add_admin_select_user_data,
)
add_admin_confirm_window = Window(
Format("{content}"),
Row(
Button(
Const("✅ Да"),
id="confirm_add_admin",
on_click=on_add_admin_confirm,
),
Button(
Const("❌ Нет"),
id="cancel_add_admin",
on_click=on_add_admin_cancel,
),
),
state=AdminMenuSG.add_admin_confirm,
getter=get_add_admin_confirm_data,
)