262 lines
9.4 KiB
Python
262 lines
9.4 KiB
Python
from typing import TYPE_CHECKING
|
|
from aiogram import Router, F
|
|
from aiogram.fsm.context import FSMContext
|
|
from aiogram.types import CallbackQuery, InlineKeyboardButton
|
|
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
|
from logging import getLogger
|
|
from sqlmodel.ext.asyncio.session import AsyncSession
|
|
|
|
from ....model.descriptors import FieldEditButton, CommandButton
|
|
from ....model.settings import Settings
|
|
from ....model.user import UserBase
|
|
from ....model import EntityPermission
|
|
from ....utils.main import (
|
|
check_entity_permission,
|
|
get_send_message,
|
|
clear_state,
|
|
get_value_repr,
|
|
get_callable_str,
|
|
get_entity_descriptor,
|
|
)
|
|
from ..context import ContextData, CallbackCommand, CommandContext
|
|
from ..navigation import (
|
|
pop_navigation_context,
|
|
save_navigation_context,
|
|
)
|
|
|
|
if TYPE_CHECKING:
|
|
from ....main import QBotApp
|
|
|
|
|
|
logger = getLogger(__name__)
|
|
router = Router()
|
|
|
|
|
|
@router.callback_query(ContextData.filter(F.command == CallbackCommand.ENTITY_ITEM))
|
|
async def entity_item_callback(query: CallbackQuery, **kwargs):
|
|
callback_data: ContextData = kwargs["callback_data"]
|
|
state: FSMContext = kwargs["state"]
|
|
state_data = await state.get_data()
|
|
kwargs["state_data"] = state_data
|
|
|
|
clear_state(state_data=state_data)
|
|
stack = save_navigation_context(callback_data=callback_data, state_data=state_data)
|
|
|
|
await entity_item(query=query, navigation_stack=stack, **kwargs)
|
|
|
|
|
|
async def entity_item(
|
|
query: CallbackQuery,
|
|
callback_data: ContextData,
|
|
db_session: AsyncSession,
|
|
user: UserBase,
|
|
app: "QBotApp",
|
|
navigation_stack: list[ContextData],
|
|
**kwargs,
|
|
):
|
|
entity_descriptor = get_entity_descriptor(app, callback_data)
|
|
# user_permissions = get_user_permissions(user, entity_descriptor)
|
|
entity_type = entity_descriptor.type_
|
|
|
|
keyboard_builder = InlineKeyboardBuilder()
|
|
|
|
entity_item = await entity_type.get(session=db_session, id=callback_data.entity_id)
|
|
|
|
if not entity_item:
|
|
return await query.answer(
|
|
text=(await Settings.get(Settings.APP_STRINGS_NOT_FOUND))
|
|
)
|
|
|
|
# is_owned = issubclass(entity_type, OwnedBotEntity)
|
|
|
|
if not check_entity_permission(
|
|
entity=entity_item, user=user, permission=EntityPermission.READ
|
|
):
|
|
return await query.answer(
|
|
text=(await Settings.get(Settings.APP_STRINGS_FORBIDDEN))
|
|
)
|
|
|
|
can_edit = check_entity_permission(
|
|
entity=entity_item, user=user, permission=EntityPermission.UPDATE
|
|
)
|
|
|
|
form = entity_descriptor.forms.get(
|
|
callback_data.form_params or "default", entity_descriptor.default_form
|
|
)
|
|
|
|
for edit_buttons_row in form.form_buttons:
|
|
btn_row = []
|
|
for button in edit_buttons_row:
|
|
|
|
if button.visibility and not button.visibility(entity_item):
|
|
continue
|
|
|
|
if isinstance(button, FieldEditButton) and can_edit:
|
|
|
|
field_name = button.field_name
|
|
btn_caption = button.caption
|
|
if field_name in entity_descriptor.fields_descriptors:
|
|
field_descriptor = entity_descriptor.fields_descriptors[
|
|
field_name
|
|
]
|
|
field_value = getattr(entity_item, field_descriptor.field_name)
|
|
if btn_caption:
|
|
btn_text = get_callable_str(
|
|
btn_caption, field_descriptor, entity_item, field_value
|
|
)
|
|
else:
|
|
if field_descriptor.type_base is bool:
|
|
btn_text = f"{'【✔︎】 ' if field_value else '【 】 '}{
|
|
get_callable_str(
|
|
field_descriptor.caption,
|
|
field_descriptor,
|
|
entity_item,
|
|
field_value,
|
|
)
|
|
if field_descriptor.caption
|
|
else field_name
|
|
}"
|
|
else:
|
|
btn_text = (
|
|
f"✏️ {
|
|
get_callable_str(
|
|
field_descriptor.caption,
|
|
field_descriptor,
|
|
entity_item,
|
|
field_value,
|
|
)
|
|
}"
|
|
if field_descriptor.caption
|
|
else f"✏️ {field_name}"
|
|
)
|
|
btn_row.append(
|
|
InlineKeyboardButton(
|
|
text=btn_text,
|
|
callback_data=ContextData(
|
|
command=CallbackCommand.FIELD_EDITOR,
|
|
context=CommandContext.ENTITY_FIELD_EDIT,
|
|
entity_name=entity_descriptor.name,
|
|
entity_id=str(entity_item.id),
|
|
field_name=field_name,
|
|
).pack(),
|
|
)
|
|
)
|
|
|
|
elif isinstance(button, CommandButton):
|
|
|
|
btn_caption = button.caption
|
|
if btn_caption:
|
|
btn_text = get_callable_str(
|
|
btn_caption, entity_descriptor, entity_item
|
|
)
|
|
else:
|
|
btn_text = button.command
|
|
|
|
if isinstance(button.context_data, ContextData):
|
|
btn_cdata = button.context_data
|
|
elif callable(button.context_data):
|
|
btn_cdata = button.context_data(callback_data, entity_item)
|
|
else:
|
|
btn_cdata = ContextData(
|
|
command=CallbackCommand.USER_COMMAND,
|
|
user_command=button.command,
|
|
data=str(entity_item.id),
|
|
)
|
|
|
|
btn_row.append(
|
|
InlineKeyboardButton(
|
|
text=btn_text,
|
|
callback_data=btn_cdata.pack(),
|
|
)
|
|
)
|
|
|
|
if btn_row:
|
|
keyboard_builder.row(*btn_row)
|
|
|
|
edit_delete_row = []
|
|
if can_edit and form.show_edit_button:
|
|
edit_delete_row.append(
|
|
InlineKeyboardButton(
|
|
text=(await Settings.get(Settings.APP_STRINGS_EDIT_BTN)),
|
|
callback_data=ContextData(
|
|
command=CallbackCommand.FIELD_EDITOR,
|
|
context=CommandContext.ENTITY_EDIT,
|
|
entity_name=entity_descriptor.name,
|
|
entity_id=str(entity_item.id),
|
|
form_params=callback_data.form_params,
|
|
field_name=form.edit_field_sequence[0],
|
|
).pack(),
|
|
)
|
|
)
|
|
|
|
if (
|
|
check_entity_permission(
|
|
entity=entity_item, user=user, permission=EntityPermission.DELETE
|
|
)
|
|
and form.show_delete_button
|
|
):
|
|
edit_delete_row.append(
|
|
InlineKeyboardButton(
|
|
text=(await Settings.get(Settings.APP_STRINGS_DELETE_BTN)),
|
|
callback_data=ContextData(
|
|
command=CallbackCommand.ENTITY_DELETE,
|
|
entity_name=entity_descriptor.name,
|
|
form_params=callback_data.form_params,
|
|
entity_id=str(entity_item.id),
|
|
).pack(),
|
|
)
|
|
)
|
|
|
|
if edit_delete_row:
|
|
keyboard_builder.row(*edit_delete_row)
|
|
|
|
if form.item_repr:
|
|
item_text = form.item_repr(entity_descriptor, entity_item)
|
|
else:
|
|
entity_caption = (
|
|
get_callable_str(
|
|
entity_descriptor.full_name, entity_descriptor, entity_item
|
|
)
|
|
if entity_descriptor.full_name
|
|
else entity_descriptor.name
|
|
)
|
|
|
|
entity_item_repr = (
|
|
get_callable_str(
|
|
entity_descriptor.item_repr, entity_descriptor, entity_item
|
|
)
|
|
if entity_descriptor.item_repr
|
|
else str(entity_item.id)
|
|
)
|
|
|
|
item_text = f"<b><u><i>{entity_caption or entity_descriptor.name}:</i></u></b> <b>{entity_item_repr}</b>"
|
|
|
|
for field_descriptor in entity_descriptor.fields_descriptors.values():
|
|
if field_descriptor.is_visible:
|
|
field_caption = get_callable_str(
|
|
field_descriptor.caption, field_descriptor, entity_item
|
|
)
|
|
value = get_value_repr(
|
|
value=getattr(entity_item, field_descriptor.name),
|
|
field_descriptor=field_descriptor,
|
|
locale=user.lang,
|
|
)
|
|
item_text += f"\n{field_caption or field_descriptor.name}:{f' <b>{value}</b>' if value else ''}"
|
|
|
|
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(),
|
|
)
|
|
)
|
|
|
|
state: FSMContext = kwargs["state"]
|
|
state_data = kwargs["state_data"]
|
|
await state.set_data(state_data)
|
|
|
|
send_message = get_send_message(query)
|
|
|
|
await send_message(text=item_text, reply_markup=keyboard_builder.as_markup())
|