From 3b6f827ae68f049f85d025e22431b7985552bee6 Mon Sep 17 00:00:00 2001 From: akhdanre Date: Sat, 17 May 2025 16:21:49 +0700 Subject: [PATCH] fix: join and leave --- app/controllers/socket_conroller.py | 41 +++++++++++++++---- app/repositories/session_memory_repository.py | 23 +++++++---- app/services/session_service.py | 27 ++++++------ 3 files changed, 59 insertions(+), 32 deletions(-) diff --git a/app/controllers/socket_conroller.py b/app/controllers/socket_conroller.py index d0818e6..8fac996 100644 --- a/app/controllers/socket_conroller.py +++ b/app/controllers/socket_conroller.py @@ -88,7 +88,9 @@ class SocketController: emit("error", {"message": "Failed to join session or session inactive"}) return - join_room(session_code) + session_id = session["session_id"] + + join_room(session_id) if session["is_admin"]: message = "Admin has joined the room." @@ -100,7 +102,7 @@ class SocketController: { "type": "join", "message": message, - "room": session_code, + "room": session_id, "argument": "adm_update", "data": { "session_info": session["session_info"], @@ -115,13 +117,13 @@ class SocketController: { "type": "participan_join", "message": message, - "room": session_code, + "room": session_id, "argument": "adm_update", "data": { "participants": session["session_info"]["participants"], }, }, - room=session_code, + room=session_id, skip_sid=request.sid, ) @@ -206,20 +208,41 @@ class SocketController: @self.socketio.on("leave_room") def handle_leave_room(data): - session_code = data.get("session_id") + session_id = data.get("session_id") user_id = data.get("user_id") username = data.get("username", "anonymous") - leave_room(session_code) + leave_result = self.session_service.leave_session( + session_id=session_id, + user_id=user_id, + ) + leave_room(session_id) + if leave_result["is_success"]: + emit( + "room_message", + { + "type": "participan_leave", + "message": f"{username} has left the room.", + "room": session_id, + "argument": "adm_update", + "data": { + "participants": leave_result["participants"], + }, + }, + room=session_id, + skip_sid=request.sid, + ) emit( "room_message", { "type": "leave", "message": f"{username} has left the room.", - "room": session_code, - "data": user_id, + "room": session_id, + "argument": "adm_update", + "data": None, }, - room=session_code, + room=session_id, + to=request.sid, ) @self.socketio.on("send_message") diff --git a/app/repositories/session_memory_repository.py b/app/repositories/session_memory_repository.py index bc4f32d..8930842 100644 --- a/app/repositories/session_memory_repository.py +++ b/app/repositories/session_memory_repository.py @@ -41,6 +41,7 @@ class SessionMemoryRepository: :return: Session ID """ data = initial_data.model_dump() + data["id"] = data["id"] data["created_at"] = str(data["created_at"]) self.set_data(f"session:{session_id}", data) @@ -126,6 +127,14 @@ class SessionMemoryRepository: self.set_data(f"session:{session_id}", session) return True + def get_user_in_session(self, session_id: str): + session = self.get_session(session_id) + if not session: + return [] + existing_users = session.get("participants", []) + + return existing_users + def remove_user_from_session(self, session_id: str, user_id: str) -> bool: """ Remove a user from a session @@ -133,20 +142,16 @@ class SessionMemoryRepository: :param user_id: ID of the user to remove :return: True if user was removed, False if session doesn't exist or user not in session """ - session = self.get_data(f"session:{session_id}") + session = self.get_session(session_id) if not session: return False - original_users_count = len(session.get("participans", [])) - session["participans"] = [ - user for user in session.get("participans", []) if user["id"] != user_id + session["participants"] = [ + user for user in session.get("participants", []) if user["id"] != user_id ] - if len(session["participans"]) < original_users_count: - self.set_data(f"session:{session_id}", session) - return True - - return False + self.set_data(f"session:{session_id}", session) + return True def set_quiz_for_session(self, session_id: str, quiz_data: QuizEntity): """ diff --git a/app/services/session_service.py b/app/services/session_service.py index 9385f2e..82427b4 100644 --- a/app/services/session_service.py +++ b/app/services/session_service.py @@ -51,10 +51,11 @@ class SessionService: def join_session(self, session_code: str, user_id: str) -> dict: user = self.user_repository.get_user_by_id(user_id) session = self.repository_redis.find_session_by_code(session_code) - if session is None: return None + session_id = session["id"] + is_existing_user = any( u["id"] == user_id for u in session.get("participants", []) ) @@ -63,11 +64,14 @@ class SessionService: quiz_info = { "title": session_quiz.title, - "limit_duration": session_quiz.title, + "description": session_quiz.description, + "total_quiz": session_quiz.total_quiz, + "limit_duration": session_quiz.limit_duration, } if session["host_id"] == user_id: return { + "session_id": session_id, "is_admin": True, "message": "admin joined", "session_info": session, @@ -76,6 +80,7 @@ class SessionService: if is_existing_user: return { + "session_id": session_id, "is_admin": False, "user_id": str(user.id), "username": user.name, @@ -95,6 +100,7 @@ class SessionService: session = self.repository_redis.get_session(session["id"]) response = { + "session_id": session_id, "is_admin": False, "user_id": str(user.id), "username": user.name, @@ -106,20 +112,13 @@ class SessionService: return response def leave_session(self, session_id: str, user_id: str) -> dict: - session = self.repository_mongo.get_by_id(session_id) + is_success = self.repository_redis.remove_user_from_session(session_id, user_id) - if session is None: - return {"error": "Session not found"} + if is_success: + participant_left = self.repository_redis.get_user_in_session(session_id) + return {"is_success": True, "participants": participant_left} - if user_id == session.host_id: - return {"message": "Host cannot leave the session"} - - if user_id in session.participants: - session.participants.remove(user_id) - self.repository.update(session.id, {"participants": session.participants}) - return {"message": "User has left the session"} - - return {"message": "User not in session"} + return {"is_success": False} def start_session(self, session_id: str) -> bool: now = DatetimeUtil.now_iso()