Skip to content

Commit

Permalink
feat: add dialog for creating a room
Browse files Browse the repository at this point in the history
  • Loading branch information
Makcal committed Mar 24, 2024
1 parent 53fb683 commit d023f2a
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 39 deletions.
45 changes: 11 additions & 34 deletions src/api/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ async def _post(self, path: str, user_id: int = None, **data: any) -> any:
data["user_id"] = user_id
async with aiohttp.ClientSession() as session:
r: aiohttp.ClientResponse
async with session.post(
self.url + path, json=data, headers={"X-Token": self.secret}
) as r:
async with session.post(self.url + path, json=data, headers={"X-Token": self.secret}) as r:
if r.status != 200:
if r.status in (400, 422):
json = await r.json()
Expand All @@ -47,14 +45,10 @@ async def create_room(self, name: str, user_id: int) -> int:
return await self._post("/bot/room/create", user_id, room={"name": name})

async def invite_person(self, alias: str, user_id: int) -> int:
return await self._post(
"/bot/invitation/create", user_id, addressee={"alias": alias}
)
return await self._post("/bot/invitation/create", user_id, addressee={"alias": alias})

async def accept_invitation(self, id_: int, user_id: int) -> int:
return await self._post(
"/bot/invitation/accept", user_id, invitation={"id": id_}
)
return await self._post("/bot/invitation/accept", user_id, invitation={"id": id_})

async def create_order(self, users: list[int], user_id: int) -> int:
return await self._post("/bot/order/create", user_id, order={"users": users})
Expand All @@ -66,38 +60,25 @@ async def modify_task(self, body: ModifyTaskBody, user_id: int) -> bool:
return await self._post("/bot/task/modify", user_id, task=body.model_dump())

async def get_daily_info(self, user_id: int) -> DailyInfoResponse:
return DailyInfoResponse.model_validate(
await self._post("/bot/room/daily_info", user_id)
)
return DailyInfoResponse.model_validate(await self._post("/bot/room/daily_info", user_id))

async def get_incoming_invitations(
self, alias: str, user_id: int
) -> list[IncomingInvitationInfo]:
async def get_incoming_invitations(self, alias: str, user_id: int) -> list[IncomingInvitationInfo]:
return [
IncomingInvitationInfo.model_validate(obj)
for obj in await self._post("/bot/invitation/inbox", user_id, alias=alias)[
"invitations"
]
for obj in await self._post("/bot/invitation/inbox", user_id, alias=alias)["invitations"]
]

async def get_room_info(self, user_id: int) -> RoomInfoResponse:
return RoomInfoResponse.model_validate(
await self._post("/bot/room/info", user_id)
)
return RoomInfoResponse.model_validate(await self._post("/bot/room/info", user_id))

async def leave_room(self, user_id: int) -> bool:
return await self._post("/bot/room/leave", user_id)

async def get_tasks(self, user_id: int) -> list[Task]:
return [
Task.model_validate(obj)
for obj in await self._post("/bot/task/list", user_id)["tasks"]
]
return [Task.model_validate(obj) for obj in await self._post("/bot/task/list", user_id)["tasks"]]

async def get_task_info(self, id_: int, user_id: int) -> TaskInfoResponse:
return TaskInfoResponse.model_validate(
await self._post("/bot/task/info", user_id, task={"id": id_})
)
return TaskInfoResponse.model_validate(await self._post("/bot/task/info", user_id, task={"id": id_}))

async def get_sent_invitations(self, user_id: int) -> list[SentInvitationInfo]:
return [
Expand All @@ -106,14 +87,10 @@ async def get_sent_invitations(self, user_id: int) -> list[SentInvitationInfo]:
]

async def delete_invitation(self, id_: int, user_id: int) -> bool:
return await self._post(
"/bot/invitation/delete", user_id, invitation={"id": id_}
)
return await self._post("/bot/invitation/delete", user_id, invitation={"id": id_})

async def reject_invitation(self, id_: int, user_id: int) -> bool:
return await self._post(
"/bot/invitation/reject", user_id, invitation={"id": id_}
)
return await self._post("/bot/invitation/reject", user_id, invitation={"id": id_})

async def get_order_info(self, id_: int, user_id: int) -> list[int]:
return await self._post("/bot/order/info", user_id, order={"id": id_})["users"]
3 changes: 3 additions & 0 deletions src/bot/dialogs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from src.bot.dialogs.roomless import roomless_dialog

__all__ = ["roomless_dialog"]
16 changes: 16 additions & 0 deletions src/bot/dialogs/communication.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from dataclasses import dataclass


@dataclass
class CreateRoomDialogResult:
name: str | None
ok: bool = True


@dataclass
class RoomDialogStartData:
id: int
name: str


__all__ = ["CreateRoomDialogResult", "RoomDialogStartData"]
25 changes: 25 additions & 0 deletions src/bot/dialogs/create_room.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from aiogram.types import Message
from aiogram_dialog import Dialog, Window, DialogManager, ShowMode
from aiogram_dialog.widgets.input import TextInput
from aiogram_dialog.widgets.kbd import Cancel
from aiogram_dialog.widgets.text import Const

from src.bot.dialogs.communication import CreateRoomDialogResult
from src.bot.dialogs.states import CreateRoomSG


NAME_INPUT_ID = "name_input"


async def text_handler(message: Message, widget, dialog_manager: DialogManager, _):
await dialog_manager.done(CreateRoomDialogResult(name=message.text), show_mode=ShowMode.SEND)


create_room_dialog = Dialog(
Window(
Const("Enter a room's name"),
Cancel(result=CreateRoomDialogResult(name=None, ok=False)),
TextInput(NAME_INPUT_ID, on_success=text_handler),
state=CreateRoomSG.enter_name,
)
)
27 changes: 27 additions & 0 deletions src/bot/dialogs/room.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from aiogram_dialog import Dialog, Window, DialogManager
from aiogram_dialog.widgets.text import Format

from src.bot.dialogs.communication import RoomDialogStartData
from src.bot.dialogs.states import RoomSG


async def getter(dialog_manager: DialogManager):
room_info: RoomDialogStartData = dialog_manager.dialog_data["room_info"]
return {
"room_id": room_info.id,
"room_name": room_info.name,
}


async def on_start(start_data: RoomDialogStartData, dialog_manager: DialogManager):
dialog_manager.dialog_data["room_info"] = start_data


room_dialog = Dialog(
Window(
Format("Your room: {room_name}\nID: {room_id}"),
getter=getter,
state=RoomSG.main,
),
on_start=on_start,
)
47 changes: 47 additions & 0 deletions src/bot/dialogs/roomless.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from aiogram.types import CallbackQuery
from aiogram_dialog import Window, Dialog, DialogManager, Data, ShowMode, StartMode
from aiogram_dialog.widgets.text import Const
from aiogram_dialog.widgets.kbd import Row, Button

from src.api import client
from src.bot.dialogs.communication import CreateRoomDialogResult, RoomDialogStartData
from src.bot.dialogs.states import RoomlessSG, CreateRoomSG, RoomSG

WELCOME_MESSAGE = """This is a welcome message
You can:
- Accept an invitation to a room
- Create a new room"""

INVITATIONS_BUTTON_ID = "invitations_button"
CREATE_ROOM_BUTTON_ID = "create_room_button"


async def process_result(start_data: Data, result: CreateRoomDialogResult, dialog_manager: DialogManager):
if result.ok:
room_id = await client.create_room(result.name, dialog_manager.event.from_user.id)
# noinspection PyTypeChecker
await dialog_manager.start(
RoomSG.main, data=RoomDialogStartData(room_id, result.name), mode=StartMode.RESET_STACK
)


async def start_creating_room(event: CallbackQuery, button: Button, dialog_manager: DialogManager):
await dialog_manager.start(CreateRoomSG.enter_name, show_mode=ShowMode.SEND)


roomless_dialog = Dialog(
Window(
Const(WELCOME_MESSAGE),
Row(
Button(Const("Invitations"), INVITATIONS_BUTTON_ID),
Button(
Const("Create"),
CREATE_ROOM_BUTTON_ID,
on_click=start_creating_room,
),
),
state=RoomlessSG.welcome,
),
on_process_result=process_result,
)
14 changes: 14 additions & 0 deletions src/bot/dialogs/states.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from aiogram.fsm.state import StatesGroup, State


class CreateRoomSG(StatesGroup):
enter_name = State()


class RoomlessSG(StatesGroup):
welcome = State()
invitations = State()


class RoomSG(StatesGroup):
main = State()
16 changes: 11 additions & 5 deletions src/bot/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@

import dotenv
from aiogram import Bot, Dispatcher
from aiogram.filters import CommandStart
from aiogram_dialog import setup_dialogs


dotenv.load_dotenv(".env")

bot = Bot(token=os.getenv("BOT_TOKEN"))
dp = Dispatcher()
from src.bot.dialogs.create_room import create_room_dialog
from src.bot.dialogs import roomless_dialog
from src.bot.dialogs.room import room_dialog
from src.bot.start_message import start_message_handler


async def main():
dotenv.load_dotenv(".env")
logging.basicConfig(level=logging.INFO)

bot = Bot(token=os.getenv("BOT_TOKEN"))
dp = Dispatcher()
dp.message.register(start_message_handler, CommandStart())
dp.include_routers(roomless_dialog, create_room_dialog, room_dialog)

setup_dialogs(dp)
await dp.start_polling(bot)

Expand Down
25 changes: 25 additions & 0 deletions src/bot/start_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from aiogram.types import Message
from aiogram_dialog import DialogManager, StartMode

from src.api import client
from src.bot.dialogs.communication import RoomDialogStartData
from src.bot.dialogs.states import RoomlessSG, RoomSG


async def start_message_handler(message: Message, dialog_manager: DialogManager):
user_id = message.from_user.id
try:
await client.create_user(user_id)
except RuntimeError:
pass

try:
room_info = await client.get_room_info(user_id)
# noinspection PyTypeChecker
await dialog_manager.start(
RoomSG.main,
data=RoomDialogStartData(room_info.id, room_info.name),
mode=StartMode.RESET_STACK,
)
except RuntimeError:
await dialog_manager.start(RoomlessSG.welcome, mode=StartMode.RESET_STACK)

0 comments on commit d023f2a

Please sign in to comment.