|
| 1 | +from typing import List, Set |
| 2 | +import uuid |
| 3 | +from api.db.models.room_model import RoomModel |
| 4 | +from api.db.models.user_model import UserModel |
| 5 | +from api.libs.errors import NotFoundException |
| 6 | +from api.web.ws.rooms.room import Room |
| 7 | +from api.web.ws.rooms.send.schemas import SendContent, SendJoinRoomBody |
| 8 | +from api.web.ws.rooms.user import User |
| 9 | +from fastapi import WebSocket |
| 10 | + |
| 11 | + |
| 12 | +class ConnectionManager: |
| 13 | + def __init__(self): |
| 14 | + self.rooms: List[Room] = [] |
| 15 | + |
| 16 | + async def connect( |
| 17 | + self, |
| 18 | + username: str, |
| 19 | + websocket: WebSocket, |
| 20 | + user_model: UserModel, |
| 21 | + room_model: RoomModel, |
| 22 | + ): |
| 23 | + room = self.get_room_or_none(room_model.id) |
| 24 | + if room is None: |
| 25 | + room = self.create_room(room_model.id, room_model) |
| 26 | + |
| 27 | + user = room.get_user_or_none(user_model.id) |
| 28 | + if user is None: |
| 29 | + user = self.create_user( |
| 30 | + username, |
| 31 | + websocket, |
| 32 | + user_model, |
| 33 | + add_room=room, |
| 34 | + ) |
| 35 | + else: |
| 36 | + user.websocket = websocket |
| 37 | + |
| 38 | + try: |
| 39 | + message_content = SendContent( |
| 40 | + type="join_room", |
| 41 | + body=SendJoinRoomBody( |
| 42 | + user_id=user_model.id, |
| 43 | + username=user.username, |
| 44 | + ).model_dump(), |
| 45 | + ) |
| 46 | + await room.send_json(message_content.model_dump(), exclude_users=[user]) |
| 47 | + except: |
| 48 | + pass |
| 49 | + |
| 50 | + async def disconnect(self, room_model: RoomModel, user_model: UserModel): |
| 51 | + room = self.get_room_or_none(room_model.id) |
| 52 | + if room is not None: |
| 53 | + user = room.get_user_or_none(user_model.id) |
| 54 | + if user is not None: |
| 55 | + room.leave_user(user) |
| 56 | + |
| 57 | + def create_room(self, room_id: uuid.UUID, room_model: RoomModel) -> Room: |
| 58 | + room = Room(room_id, room_model) |
| 59 | + self.add_room(room) |
| 60 | + return room |
| 61 | + |
| 62 | + def create_user(self, username: str, websocket: WebSocket, user_model: UserModel, add_room: Room | None = None) -> User: |
| 63 | + user = User( |
| 64 | + id=user_model.id, |
| 65 | + username=username, |
| 66 | + websocket=websocket, |
| 67 | + user_model=user_model, |
| 68 | + ) |
| 69 | + |
| 70 | + if add_room is not None: |
| 71 | + add_room.add_user(user) |
| 72 | + |
| 73 | + return user |
| 74 | + |
| 75 | + def get_room(self, room_id: uuid.UUID) -> Room: |
| 76 | + for room in self.rooms: |
| 77 | + if room.id == room_id: |
| 78 | + return room |
| 79 | + raise NotFoundException("Not found room from room_id.") |
| 80 | + |
| 81 | + def get_room_or_none( |
| 82 | + self, room_uuid: uuid.UUID |
| 83 | + ) -> Room | None: |
| 84 | + try: |
| 85 | + return self.get_room(room_uuid) |
| 86 | + except NotFoundException: |
| 87 | + return None |
| 88 | + |
| 89 | + def add_room(self, room: Room) -> None: |
| 90 | + self.rooms.append(room) |
| 91 | + |
| 92 | + def delete_room(self, room: Room) -> None: |
| 93 | + if room in self.rooms: |
| 94 | + self.rooms.discard(room) |
| 95 | + |
| 96 | + def delete_room_by_id(self, room_id: uuid.UUID) -> None: |
| 97 | + room = self.get_room_by_idI(room_id) |
| 98 | + self.delete_room(room) |
| 99 | + |
| 100 | + def get_room_by_id(self, uuid: uuid.UUID) -> Room | None: |
| 101 | + for room in self.rooms: |
| 102 | + if room.id == uuid: |
| 103 | + return room |
| 104 | + return None |
0 commit comments