fsm bugfixes
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
from aiogram.types import Message, CallbackQuery
|
from aiogram.types import Message, CallbackQuery
|
||||||
|
from aiogram.fsm.context import FSMContext
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -25,11 +26,13 @@ async def route_callback(message: Message | CallbackQuery, back: bool = True, **
|
|||||||
import quickbot.bot.handlers.user_handlers.main as user_handler
|
import quickbot.bot.handlers.user_handlers.main as user_handler
|
||||||
|
|
||||||
state_data = kwargs["state_data"]
|
state_data = kwargs["state_data"]
|
||||||
|
state: FSMContext = kwargs["state"]
|
||||||
stack, context = get_navigation_context(state_data)
|
stack, context = get_navigation_context(state_data)
|
||||||
if back:
|
if back:
|
||||||
context = pop_navigation_context(stack)
|
context = pop_navigation_context(stack)
|
||||||
stack = save_navigation_context(callback_data=context, state_data=state_data)
|
stack = save_navigation_context(callback_data=context, state_data=state_data)
|
||||||
kwargs.update({"callback_data": context, "navigation_stack": stack})
|
kwargs.update({"callback_data": context, "navigation_stack": stack})
|
||||||
|
await state.set_data(state_data)
|
||||||
if context:
|
if context:
|
||||||
if context.command == CallbackCommand.MENU_ENTRY_MAIN:
|
if context.command == CallbackCommand.MENU_ENTRY_MAIN:
|
||||||
await menu_main.main_menu(message, **kwargs)
|
await menu_main.main_menu(message, **kwargs)
|
||||||
|
|||||||
@@ -121,9 +121,7 @@ async def render_entity_picker(
|
|||||||
enum_items = (await field_descriptor.options(entity, context)) or []
|
enum_items = (await field_descriptor.options(entity, context)) or []
|
||||||
else:
|
else:
|
||||||
enum_items = field_descriptor.options(entity, context) or []
|
enum_items = field_descriptor.options(entity, context) or []
|
||||||
enum_items = enum_items[
|
enum_items = enum_items[page_size * (page - 1) : page_size * page]
|
||||||
page_size * (page - 1) : page_size * page
|
|
||||||
]
|
|
||||||
else:
|
else:
|
||||||
enum_items = list(type_.all_members.values())[
|
enum_items = list(type_.all_members.values())[
|
||||||
page_size * (page - 1) : page_size * page
|
page_size * (page - 1) : page_size * page
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ async def field_editor(message: Message | CallbackQuery, **kwargs):
|
|||||||
db_session: AsyncSession = kwargs["db_session"]
|
db_session: AsyncSession = kwargs["db_session"]
|
||||||
user: UserBase = kwargs["user"]
|
user: UserBase = kwargs["user"]
|
||||||
app: "QBotApp" = kwargs["app"]
|
app: "QBotApp" = kwargs["app"]
|
||||||
# state: FSMContext = kwargs["state"]
|
state: FSMContext = kwargs["state"]
|
||||||
|
|
||||||
state_data: dict = kwargs["state_data"]
|
state_data: dict = kwargs["state_data"]
|
||||||
entity_data = state_data.get("entity_data")
|
entity_data = state_data.get("entity_data")
|
||||||
@@ -173,6 +173,7 @@ async def field_editor(message: Message | CallbackQuery, **kwargs):
|
|||||||
|
|
||||||
stack, context_data = get_navigation_context(state_data=state_data)
|
stack, context_data = get_navigation_context(state_data=state_data)
|
||||||
kwargs.update({"callback_data": context_data})
|
kwargs.update({"callback_data": context_data})
|
||||||
|
await state.set_data(state_data)
|
||||||
|
|
||||||
return await entity_item(
|
return await entity_item(
|
||||||
query=message, navigation_stack=stack, **kwargs
|
query=message, navigation_stack=stack, **kwargs
|
||||||
|
|||||||
@@ -187,6 +187,8 @@ async def process_field_edit_callback(message: Message | CallbackQuery, **kwargs
|
|||||||
text=(await Settings.get(Settings.APP_STRINGS_FORBIDDEN))
|
text=(await Settings.get(Settings.APP_STRINGS_FORBIDDEN))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
clear_state(state_data=state_data)
|
||||||
|
|
||||||
return await route_callback(message=message, back=True, **kwargs)
|
return await route_callback(message=message, back=True, **kwargs)
|
||||||
|
|
||||||
elif callback_data.context in [
|
elif callback_data.context in [
|
||||||
@@ -359,14 +361,14 @@ async def process_field_edit_callback(message: Message | CallbackQuery, **kwargs
|
|||||||
|
|
||||||
can_create = True
|
can_create = True
|
||||||
|
|
||||||
if entity_descriptor.before_update_save:
|
if entity_descriptor.before_create_save:
|
||||||
if iscoroutinefunction(entity_descriptor.before_update_save):
|
if iscoroutinefunction(entity_descriptor.before_create_save):
|
||||||
can_create = await entity_descriptor.before_update_save(
|
can_create = await entity_descriptor.before_create_save(
|
||||||
new_entity,
|
new_entity,
|
||||||
context,
|
context,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
can_create = entity_descriptor.before_update_save(
|
can_create = entity_descriptor.before_create_save(
|
||||||
new_entity,
|
new_entity,
|
||||||
context,
|
context,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -76,7 +76,10 @@ async def wrap_editor(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if field_descriptor.is_optional and field_descriptor.show_skip_in_editor == "Auto":
|
if (
|
||||||
|
field_descriptor.is_optional
|
||||||
|
and field_descriptor.show_skip_in_editor == "Auto"
|
||||||
|
):
|
||||||
btns.append(
|
btns.append(
|
||||||
InlineKeyboardButton(
|
InlineKeyboardButton(
|
||||||
text=(await Settings.get(Settings.APP_STRINGS_SKIP_BTN)),
|
text=(await Settings.get(Settings.APP_STRINGS_SKIP_BTN)),
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ async def entity_item_callback(query: CallbackQuery, **kwargs):
|
|||||||
|
|
||||||
clear_state(state_data=state_data)
|
clear_state(state_data=state_data)
|
||||||
stack = save_navigation_context(callback_data=callback_data, state_data=state_data)
|
stack = save_navigation_context(callback_data=callback_data, state_data=state_data)
|
||||||
|
await state.set_data(state_data)
|
||||||
|
|
||||||
await entity_item(query=query, navigation_stack=stack, **kwargs)
|
await entity_item(query=query, navigation_stack=stack, **kwargs)
|
||||||
|
|
||||||
@@ -72,9 +73,9 @@ async def entity_item(
|
|||||||
|
|
||||||
entity_item = await entity_type.get(session=db_session, id=callback_data.entity_id)
|
entity_item = await entity_type.get(session=db_session, id=callback_data.entity_id)
|
||||||
|
|
||||||
state: FSMContext = kwargs["state"]
|
# state: FSMContext = kwargs["state"]
|
||||||
state_data = kwargs["state_data"]
|
state_data = kwargs["state_data"]
|
||||||
await state.set_data(state_data)
|
# await state.set_data(state_data)
|
||||||
|
|
||||||
if not entity_item and query:
|
if not entity_item and query:
|
||||||
return await query.answer(
|
return await query.answer(
|
||||||
@@ -104,7 +105,7 @@ async def entity_item(
|
|||||||
app_state=kwargs["app_state"],
|
app_state=kwargs["app_state"],
|
||||||
user=user,
|
user=user,
|
||||||
message=query,
|
message=query,
|
||||||
default_handler=item_repr
|
default_handler=item_repr,
|
||||||
)
|
)
|
||||||
|
|
||||||
if form.before_open:
|
if form.before_open:
|
||||||
@@ -306,24 +307,24 @@ async def item_repr(entity_item: BotEntity, context: BotContext[UserBase]):
|
|||||||
entity_descriptor = entity_item.bot_entity_descriptor
|
entity_descriptor = entity_item.bot_entity_descriptor
|
||||||
user = context.user
|
user = context.user
|
||||||
entity_caption = (
|
entity_caption = (
|
||||||
await get_callable_str(
|
await get_callable_str(
|
||||||
callable_str=entity_descriptor.full_name,
|
callable_str=entity_descriptor.full_name,
|
||||||
context=context,
|
context=context,
|
||||||
descriptor=entity_descriptor,
|
descriptor=entity_descriptor,
|
||||||
)
|
|
||||||
if entity_descriptor.full_name
|
|
||||||
else entity_descriptor.name
|
|
||||||
)
|
)
|
||||||
|
if entity_descriptor.full_name
|
||||||
|
else entity_descriptor.name
|
||||||
|
)
|
||||||
|
|
||||||
entity_item_repr = (
|
entity_item_repr = (
|
||||||
await get_callable_str(
|
await get_callable_str(
|
||||||
callable_str=entity_descriptor.item_repr,
|
callable_str=entity_descriptor.item_repr,
|
||||||
context=context,
|
context=context,
|
||||||
entity=entity_item,
|
entity=entity_item,
|
||||||
)
|
|
||||||
if entity_descriptor.item_repr
|
|
||||||
else str(entity_item.id)
|
|
||||||
)
|
)
|
||||||
|
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>"
|
item_text = f"<b><u><i>{entity_caption or entity_descriptor.name}:</i></u></b> <b>{entity_item_repr}</b>"
|
||||||
|
|
||||||
@@ -331,20 +332,20 @@ async def item_repr(entity_item: BotEntity, context: BotContext[UserBase]):
|
|||||||
|
|
||||||
for field_descriptor in entity_descriptor.fields_descriptors.values():
|
for field_descriptor in entity_descriptor.fields_descriptors.values():
|
||||||
if (
|
if (
|
||||||
isinstance(field_descriptor.is_visible, bool)
|
isinstance(field_descriptor.is_visible, bool)
|
||||||
and not field_descriptor.is_visible
|
and not field_descriptor.is_visible
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if callable(field_descriptor.is_visible):
|
if callable(field_descriptor.is_visible):
|
||||||
if iscoroutinefunction(field_descriptor.is_visible):
|
if iscoroutinefunction(field_descriptor.is_visible):
|
||||||
field_visible = await field_descriptor.is_visible(
|
field_visible = await field_descriptor.is_visible(
|
||||||
field_descriptor, entity_item, context
|
field_descriptor, entity_item, context
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
field_visible = field_descriptor.is_visible(
|
field_visible = field_descriptor.is_visible(
|
||||||
field_descriptor, entity_item, context
|
field_descriptor, entity_item, context
|
||||||
)
|
)
|
||||||
if not field_visible:
|
if not field_visible:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -352,11 +353,10 @@ async def item_repr(entity_item: BotEntity, context: BotContext[UserBase]):
|
|||||||
|
|
||||||
for own_field in entity_descriptor.ownership_fields.items():
|
for own_field in entity_descriptor.ownership_fields.items():
|
||||||
if (
|
if (
|
||||||
own_field[1].rstrip("_id")
|
own_field[1].rstrip("_id") == field_descriptor.field_name.rstrip("_id")
|
||||||
== field_descriptor.field_name.rstrip("_id")
|
and own_field[0] in user.roles
|
||||||
and own_field[0] in user.roles
|
and EntityPermission.READ_ALL not in user_permissions
|
||||||
and EntityPermission.READ_ALL not in user_permissions
|
):
|
||||||
):
|
|
||||||
skip = True
|
skip = True
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -365,28 +365,28 @@ async def item_repr(entity_item: BotEntity, context: BotContext[UserBase]):
|
|||||||
|
|
||||||
if field_descriptor.caption_value:
|
if field_descriptor.caption_value:
|
||||||
item_text += f"\n{
|
item_text += f"\n{
|
||||||
await get_callable_str(
|
await get_callable_str(
|
||||||
callable_str=field_descriptor.caption_value,
|
callable_str=field_descriptor.caption_value,
|
||||||
context=context,
|
context=context,
|
||||||
descriptor=field_descriptor,
|
descriptor=field_descriptor,
|
||||||
entity=entity_item,
|
entity=entity_item,
|
||||||
)
|
)
|
||||||
}"
|
}"
|
||||||
else:
|
else:
|
||||||
field_caption = (
|
field_caption = (
|
||||||
await get_callable_str(
|
await get_callable_str(
|
||||||
callable_str=field_descriptor.caption,
|
callable_str=field_descriptor.caption,
|
||||||
context=context,
|
|
||||||
descriptor=field_descriptor,
|
|
||||||
)
|
|
||||||
if field_descriptor.caption
|
|
||||||
else field_descriptor.field_name
|
|
||||||
)
|
|
||||||
value = await get_value_repr(
|
|
||||||
value=getattr(entity_item, field_descriptor.field_name),
|
|
||||||
field_descriptor=field_descriptor,
|
|
||||||
context=context,
|
context=context,
|
||||||
locale=user.lang,
|
descriptor=field_descriptor,
|
||||||
)
|
)
|
||||||
|
if field_descriptor.caption
|
||||||
|
else field_descriptor.field_name
|
||||||
|
)
|
||||||
|
value = await get_value_repr(
|
||||||
|
value=getattr(entity_item, field_descriptor.field_name),
|
||||||
|
field_descriptor=field_descriptor,
|
||||||
|
context=context,
|
||||||
|
locale=user.lang,
|
||||||
|
)
|
||||||
item_text += f"\n{field_caption or field_descriptor.name}:{f' <b>{value}</b>' if value else ''}"
|
item_text += f"\n{field_caption or field_descriptor.name}:{f' <b>{value}</b>' if value else ''}"
|
||||||
return item_text
|
return item_text
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ async def entity_list_callback(query: CallbackQuery, **kwargs):
|
|||||||
|
|
||||||
clear_state(state_data=state_data)
|
clear_state(state_data=state_data)
|
||||||
stack = save_navigation_context(callback_data=callback_data, state_data=state_data)
|
stack = save_navigation_context(callback_data=callback_data, state_data=state_data)
|
||||||
|
await state.set_data(state_data)
|
||||||
|
|
||||||
await entity_list(message=query, navigation_stack=stack, **kwargs)
|
await entity_list(message=query, navigation_stack=stack, **kwargs)
|
||||||
|
|
||||||
@@ -273,9 +274,9 @@ async def entity_list(
|
|||||||
)
|
)
|
||||||
}"
|
}"
|
||||||
|
|
||||||
state: FSMContext = kwargs["state"]
|
# state: FSMContext = kwargs["state"]
|
||||||
state_data = kwargs["state_data"]
|
# state_data = kwargs["state_data"]
|
||||||
await state.set_data(state_data)
|
# await state.set_data(state_data)
|
||||||
|
|
||||||
send_message = get_send_message(message)
|
send_message = get_send_message(message)
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ async def default_start_handler[UserType: UserBase](
|
|||||||
state: FSMContext,
|
state: FSMContext,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> tuple[UserType, bool]:
|
) -> tuple[UserType, bool]:
|
||||||
|
|
||||||
User = app.user_class
|
User = app.user_class
|
||||||
|
|
||||||
user = await User.get(session=db_session, id=message.from_user.id)
|
user = await User.get(session=db_session, id=message.from_user.id)
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ class QBotApp(Generic[UserType, ConfigType], FastAPI):
|
|||||||
stack = save_navigation_context(
|
stack = save_navigation_context(
|
||||||
callback_data=callback_data, state_data=state_data
|
callback_data=callback_data, state_data=state_data
|
||||||
)
|
)
|
||||||
|
await state.set_data(state_data)
|
||||||
|
|
||||||
if not db_session:
|
if not db_session:
|
||||||
db_session = await get_db()
|
db_session = await get_db()
|
||||||
|
|||||||
Reference in New Issue
Block a user