This commit is contained in:
Alexander Kalinovsky
2025-01-04 12:00:12 +01:00
commit 6dbe0536ca
94 changed files with 3467 additions and 0 deletions

View File

@@ -0,0 +1,143 @@
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