From cbe191934302721250d7f9e22357ef481b9c4812 Mon Sep 17 00:00:00 2001 From: DaShMore Date: Thu, 25 Sep 2025 20:48:39 +0300 Subject: [PATCH] add profile dialog --- app/bot/bot.py | 7 +++- app/bot/dialogs/flows/admin/start/dialogs.py | 14 +++++++ app/bot/dialogs/flows/admin/start/states.py | 5 +++ app/bot/dialogs/flows/user/__init__.py | 8 ++-- app/bot/dialogs/flows/user/profile/dialogs.py | 38 +++++++++++++++++++ app/bot/dialogs/flows/user/profile/states.py | 9 +++++ app/bot/dialogs/flows/user/start/dialogs.py | 12 ++++-- app/bot/dialogs/flows/user/start/states.py | 2 +- app/bot/handlers/commands.py | 15 ++++++-- app/bot/middlewares/__init__.py | 3 ++ app/bot/middlewares/get_user.py | 15 ++++++++ app/infrastructure/database/database.py | 3 +- 12 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 app/bot/dialogs/flows/admin/start/dialogs.py create mode 100644 app/bot/dialogs/flows/admin/start/states.py create mode 100644 app/bot/dialogs/flows/user/profile/dialogs.py create mode 100644 app/bot/dialogs/flows/user/profile/states.py create mode 100644 app/bot/middlewares/__init__.py create mode 100644 app/bot/middlewares/get_user.py diff --git a/app/bot/bot.py b/app/bot/bot.py index bafd6ba..18cd636 100644 --- a/app/bot/bot.py +++ b/app/bot/bot.py @@ -1,13 +1,16 @@ import asyncio from aiogram import Bot, Dispatcher +from aiogram.client.default import DefaultBotProperties +from aiogram.enums import ParseMode from aiogram_dialog import setup_dialogs from app.bot.dialogs.flows import dialogs_router from app.bot.handlers.commands import commands_router +from app.bot.middlewares import GetUserMiddleware from config.config import settings -bot = Bot(token=settings.bot_token) +bot = Bot(token=settings.bot_token, default=DefaultBotProperties(parse_mode=ParseMode.MARKDOWN_V2)) dp = Dispatcher() @@ -15,6 +18,8 @@ async def main(): setup_dialogs(dp) dp.include_router(commands_router) dp.include_router(dialogs_router) + + dp.update.outer_middleware(GetUserMiddleware()) await dp.start_polling(bot) diff --git a/app/bot/dialogs/flows/admin/start/dialogs.py b/app/bot/dialogs/flows/admin/start/dialogs.py new file mode 100644 index 0000000..3f6cd0d --- /dev/null +++ b/app/bot/dialogs/flows/admin/start/dialogs.py @@ -0,0 +1,14 @@ +from aiogram_dialog import Dialog, Window +from aiogram_dialog.widgets.text import Format + +from app.bot.dialogs.widgets.getters import username_getter + +from .states import AdminStartSG + +admin_start_dialog = Dialog( + Window( + Format("Hello, {username}"), + getter=username_getter, + state=AdminStartSG.start, + ) +) diff --git a/app/bot/dialogs/flows/admin/start/states.py b/app/bot/dialogs/flows/admin/start/states.py new file mode 100644 index 0000000..21c9106 --- /dev/null +++ b/app/bot/dialogs/flows/admin/start/states.py @@ -0,0 +1,5 @@ +from aiogram.fsm.state import State, StatesGroup + + +class AdminStartSG(StatesGroup): + start = State() \ No newline at end of file diff --git a/app/bot/dialogs/flows/user/__init__.py b/app/bot/dialogs/flows/user/__init__.py index 64aed02..88ab126 100644 --- a/app/bot/dialogs/flows/user/__init__.py +++ b/app/bot/dialogs/flows/user/__init__.py @@ -1,6 +1,8 @@ from aiogram import Router -from .start.dialogs import start_dialog +from .profile.dialogs import user_profile_dialog +from .start.dialogs import user_start_dialog -user_router = Router(name="user") -user_router.include_router(start_dialog) +user_router = Router(name="user dialogs") +user_router.include_router(user_start_dialog) +user_router.include_router(user_profile_dialog) diff --git a/app/bot/dialogs/flows/user/profile/dialogs.py b/app/bot/dialogs/flows/user/profile/dialogs.py new file mode 100644 index 0000000..f9dc23d --- /dev/null +++ b/app/bot/dialogs/flows/user/profile/dialogs.py @@ -0,0 +1,38 @@ +from aiogram_dialog import Dialog, Window +from aiogram_dialog.widgets.input import TextInput +from aiogram_dialog.widgets.kbd import Back, Cancel, SwitchTo +from aiogram_dialog.widgets.text import Const, Format + +from .states import UserProfileSG + +user_profile_dialog = Dialog( + Window( + Const("*Профиль*"), + Format("Имя:"), + Format("Телефон:"), + SwitchTo( + Const("изменить имя"), + id="change_name", + state=UserProfileSG.change_name, + ), + SwitchTo( + Const("изменить телефон"), + id="change_phone", + state=UserProfileSG.change_phone, + ), + Cancel(Const("назад")), + state=UserProfileSG.profile, + ), + Window( + Const("Введите имя"), + SwitchTo(Const("отмена"), id="go_profile", state=UserProfileSG.profile), + TextInput(id="name_input"), + state=UserProfileSG.change_name, + ), + Window( + Const("Введите телефон"), + SwitchTo(Const("отмена"), id="go_profile", state=UserProfileSG.profile), + TextInput(id="phone_input"), + state=UserProfileSG.change_phone, + ), +) diff --git a/app/bot/dialogs/flows/user/profile/states.py b/app/bot/dialogs/flows/user/profile/states.py new file mode 100644 index 0000000..3d69640 --- /dev/null +++ b/app/bot/dialogs/flows/user/profile/states.py @@ -0,0 +1,9 @@ +from aiogram.fsm.state import State, StatesGroup + + +class UserProfileSG(StatesGroup): + profile = State() + change_name = State() + input_name = State() + change_phone = State() + change_phone = State() \ No newline at end of file diff --git a/app/bot/dialogs/flows/user/start/dialogs.py b/app/bot/dialogs/flows/user/start/dialogs.py index 7a5f971..029e6d0 100644 --- a/app/bot/dialogs/flows/user/start/dialogs.py +++ b/app/bot/dialogs/flows/user/start/dialogs.py @@ -1,14 +1,18 @@ from aiogram_dialog import Dialog, Window -from aiogram_dialog.widgets.text import Format +from aiogram_dialog.widgets.kbd import Button, Start +from aiogram_dialog.widgets.text import Const, Format +from app.bot.dialogs.flows.user.profile.dialogs import UserProfileSG from app.bot.dialogs.widgets.getters import username_getter -from .states import StartSG +from .states import UserStartSG -start_dialog = Dialog( +user_start_dialog = Dialog( Window( Format("Hello, {username}"), + Button(Const("События"), id="events"), + Start(Const("Профиль"), id="profile", state=UserProfileSG.profile), getter=username_getter, - state=StartSG.start, + state=UserStartSG.start, ) ) diff --git a/app/bot/dialogs/flows/user/start/states.py b/app/bot/dialogs/flows/user/start/states.py index b93478a..f1eef56 100644 --- a/app/bot/dialogs/flows/user/start/states.py +++ b/app/bot/dialogs/flows/user/start/states.py @@ -1,5 +1,5 @@ from aiogram.fsm.state import State, StatesGroup -class StartSG(StatesGroup): +class UserStartSG(StatesGroup): start = State() \ No newline at end of file diff --git a/app/bot/handlers/commands.py b/app/bot/handlers/commands.py index ec7700a..df15975 100644 --- a/app/bot/handlers/commands.py +++ b/app/bot/handlers/commands.py @@ -1,12 +1,19 @@ from aiogram import Router from aiogram.filters import CommandStart from aiogram.types import Message -from aiogram_dialog import DialogManager +from aiogram_dialog import DialogManager, StartMode -from app.bot.dialogs.flows.user.start.states import StartSG +from app.bot.dialogs.flows.admin.start.states import AdminStartSG +from app.bot.dialogs.flows.user.start.states import UserStartSG commands_router = Router(name="commands_router") + @commands_router.message(CommandStart()) -async def command_start_process(message: Message, dialog_manager: DialogManager): - await dialog_manager.start(state=StartSG.start) +async def command_start_process( + message: Message, dialog_manager: DialogManager, user: dict +): + if user["is_admin"]: + await dialog_manager.start(state=AdminStartSG.start, mode=StartMode.RESET_STACK) + else: + await dialog_manager.start(state=UserStartSG.start, mode=StartMode.RESET_STACK) diff --git a/app/bot/middlewares/__init__.py b/app/bot/middlewares/__init__.py new file mode 100644 index 0000000..fdfa9b8 --- /dev/null +++ b/app/bot/middlewares/__init__.py @@ -0,0 +1,3 @@ +from .get_user import GetUserMiddleware + +__all__ = ["GetUserMiddleware"] \ No newline at end of file diff --git a/app/bot/middlewares/get_user.py b/app/bot/middlewares/get_user.py new file mode 100644 index 0000000..b5462b0 --- /dev/null +++ b/app/bot/middlewares/get_user.py @@ -0,0 +1,15 @@ +from typing import Any, Awaitable, Callable + +from aiogram import BaseMiddleware +from aiogram.types import Update + + +class GetUserMiddleware(BaseMiddleware): + async def __call__( + self, + handler: Callable[[Update, dict[str, Any]], Awaitable[Any]], + event: Update, + data: dict[str, Any], + ): + data.update(user={"is_admin": False}) + return await handler(event, data) \ No newline at end of file diff --git a/app/infrastructure/database/database.py b/app/infrastructure/database/database.py index 44a4551..7024f09 100644 --- a/app/infrastructure/database/database.py +++ b/app/infrastructure/database/database.py @@ -1,7 +1,8 @@ -from config import DATABASE_URL from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine from sqlalchemy.orm import declarative_base, sessionmaker +from config.config import DATABASE_URL + engine = create_async_engine(DATABASE_URL, echo=True) Base = declarative_base() async_session = sessionmaker(bind=engine, expire_on_commit=False, class_=AsyncSession)