144 lines
6.3 KiB
Python
144 lines
6.3 KiB
Python
from typing import get_args, get_origin
|
|
from aiogram import Router, F
|
|
from aiogram.filters import Command
|
|
from aiogram.fsm.context import FSMContext
|
|
from aiogram.fsm.state import StatesGroup, State
|
|
from aiogram.types import Message, CallbackQuery, InlineKeyboardButton
|
|
from aiogram.utils.i18n import I18n
|
|
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
|
from logging import getLogger
|
|
from sqlmodel.ext.asyncio.session import AsyncSession
|
|
|
|
from ....main import QBotApp
|
|
from ....model.bot_entity import BotEntity
|
|
from ....model.bot_enum import BotEnum
|
|
from ....model.owned_bot_entity import OwnedBotEntity
|
|
from ....model.settings import Settings
|
|
from ....model.user import UserBase
|
|
from ....model.descriptors import EntityFieldDescriptor, EntityDescriptor
|
|
from ....model import EntityPermission
|
|
from ....utils import serialize, deserialize, get_user_permissions
|
|
from ..context import ContextData, CallbackCommand, CommandContext
|
|
from ..common import (add_pagination_controls, get_local_text, get_entity_descriptor,
|
|
get_callable_str, get_send_message)
|
|
|
|
|
|
logger = getLogger(__name__)
|
|
router = Router()
|
|
|
|
|
|
@router.callback_query(ContextData.filter(F.command == CallbackCommand.ENTITY_LIST))
|
|
async def entity_list_callback(query: CallbackQuery, callback_data: ContextData, **kwargs):
|
|
|
|
if callback_data.data == "skip":
|
|
return
|
|
|
|
await clear_state(state = kwargs["state"])
|
|
stack = await save_navigation_context(callback_data = callback_data, state = kwargs["state"])
|
|
|
|
await entity_list(message = query, callback_data = callback_data, navigation_stack = stack, **kwargs)
|
|
|
|
|
|
async def entity_list(message: CallbackQuery | Message,
|
|
callback_data: ContextData,
|
|
db_session: AsyncSession,
|
|
user: UserBase,
|
|
app: QBotApp,
|
|
navigation_stack: list[ContextData],
|
|
**kwargs):
|
|
|
|
page = int(callback_data.data or "1")
|
|
|
|
entity_descriptor = get_entity_descriptor(app, callback_data)
|
|
user_permissions = get_user_permissions(user, entity_descriptor)
|
|
entity_type = entity_descriptor.type_
|
|
|
|
keyboard_builder = InlineKeyboardBuilder()
|
|
|
|
if EntityPermission.CREATE in user_permissions or EntityPermission.CREATE_ALL in user_permissions:
|
|
keyboard_builder.row(
|
|
InlineKeyboardButton(
|
|
text = (await Settings.get(Settings.APP_STRINGS_ADD_BTN)),
|
|
callback_data = ContextData(
|
|
command = CallbackCommand.FIELD_EDITOR,
|
|
context = CommandContext.ENTITY_CREATE,
|
|
entity_name = entity_descriptor.name,
|
|
field_name = entity_descriptor.field_sequence[0],
|
|
save_state = True).pack()))
|
|
|
|
page_size = await Settings.get(Settings.PAGE_SIZE)
|
|
|
|
if issubclass(entity_type, OwnedBotEntity):
|
|
if EntityPermission.READ_ALL in user_permissions or EntityPermission.LIST_ALL in user_permissions:
|
|
items = await entity_type.get_multi(
|
|
session = db_session, order_by = entity_type.name,
|
|
skip = page_size * (page - 1), limit = page_size)
|
|
items_count = await entity_type.get_count(session = db_session)
|
|
elif EntityPermission.READ in user_permissions or EntityPermission.LIST in user_permissions:
|
|
items = await entity_type.get_multi_by_user(
|
|
session = db_session, user_id = user.id, order_by = entity_type.name,
|
|
skip = page_size * (page - 1), limit = page_size)
|
|
items_count = await entity_type.get_count_by_user(session = db_session, user_id = user.id)
|
|
else:
|
|
items = list[OwnedBotEntity]()
|
|
items_count = 0
|
|
elif issubclass(entity_type, BotEntity):
|
|
if (EntityPermission.READ in user_permissions or EntityPermission.LIST in user_permissions or
|
|
EntityPermission.READ_ALL in user_permissions or EntityPermission.LIST_ALL in user_permissions):
|
|
items = await entity_type.get_multi(
|
|
session = db_session, order_by = entity_type.name,
|
|
skip = page_size * (page - 1), limit = page_size)
|
|
items_count = await entity_type.get_count(session = db_session)
|
|
else:
|
|
items = list[BotEntity]()
|
|
items_count = 0
|
|
else:
|
|
raise ValueError(f"Unsupported entity type: {entity_type}")
|
|
|
|
total_pages = items_count // page_size + (1 if items_count % page_size else 0)
|
|
|
|
for item in items:
|
|
if entity_descriptor.item_caption_btn:
|
|
caption = entity_descriptor.item_caption_btn(entity_descriptor, item)
|
|
elif entity_descriptor.fields_descriptors["name"].localizable:
|
|
caption = get_local_text(item.name, user.lang)
|
|
else:
|
|
caption = item.name
|
|
keyboard_builder.row(
|
|
InlineKeyboardButton(
|
|
text = caption,
|
|
callback_data = ContextData(
|
|
command = CallbackCommand.ENTITY_ITEM,
|
|
entity_name = entity_descriptor.name,
|
|
entity_id = str(item.id)).pack()))
|
|
|
|
add_pagination_controls(keyboard_builder = keyboard_builder,
|
|
callback_data = callback_data,
|
|
total_pages = total_pages,
|
|
command = CallbackCommand.ENTITY_LIST,
|
|
page = page)
|
|
|
|
context = pop_navigation_context(navigation_stack)
|
|
if context:
|
|
keyboard_builder.row(
|
|
InlineKeyboardButton(
|
|
text = (await Settings.get(Settings.APP_STRINGS_BACK_BTN)),
|
|
callback_data = context.pack()))
|
|
|
|
if entity_descriptor.caption_msg:
|
|
entity_text = get_callable_str(entity_descriptor.caption_msg, entity_descriptor)
|
|
else:
|
|
entity_text = entity_descriptor.name
|
|
if entity_descriptor.description:
|
|
entity_desciption = get_callable_str(entity_descriptor.description, entity_descriptor)
|
|
else:
|
|
entity_desciption = None
|
|
|
|
send_message = get_send_message(message)
|
|
|
|
await send_message(text = f"{entity_text}{f"\n{entity_desciption}" if entity_desciption else ""}",
|
|
reply_markup = keyboard_builder.as_markup())
|
|
|
|
|
|
from ..navigation import pop_navigation_context, save_navigation_context, clear_state
|