diff --git a/syng/client.py b/syng/client.py index 4bf61b4..f8439a8 100644 --- a/syng/client.py +++ b/syng/client.py @@ -206,6 +206,7 @@ class Client: self.sio.on("request-config", self.handle_request_config) self.sio.on("msg", self.handle_msg) self.sio.on("disconnect", self.handle_disconnect) + self.sio.on("room-removed", self.handle_room_removed) async def handle_disconnect(self) -> None: self.connection_state.set_disconnected() @@ -591,6 +592,28 @@ class Client: if self.player.mpv is not None: self.player.mpv.terminate() + async def remove_room(self) -> None: + """ + Remove the room from the server. + """ + + if self.state.config["room"] is not None: + logger.info("Removing room %s from server", self.state.config["room"]) + await self.sio.emit("remove-room", {"room": self.state.config["room"]}) + + async def handle_room_removed(self, data: dict[str, Any]) -> None: + """ + Handle the "room-removed" message. + + This is called when the server removes the room, that this client is + connected to. It will disconnect from the server and terminate the player. + + :param data: A dictionary with the `room` entry. + :type data: dict[str, Any] + :rtype: None + """ + logger.info("Room removed: %s", data["room"]) + async def start_client(self, config: dict[str, Any]) -> None: """ Initialize the client and connect to the server. diff --git a/syng/server.py b/syng/server.py index 5d0a211..29e2dcd 100644 --- a/syng/server.py +++ b/syng/server.py @@ -220,6 +220,7 @@ class Server: self.sio.on("config", self.handle_config) self.sio.on("register-web", self.handle_register_web) self.sio.on("register-admin", self.handle_register_admin) + self.sio.on("remove-room", self.handle_remove_room) self.sio.on("skip-current", self.handle_skip_current) self.sio.on("move-to", self.handle_move_to) self.sio.on("move-up", self.handle_move_up) @@ -932,6 +933,36 @@ class Server: ) return True + @admin + @with_state + async def handle_remove_room(self, state: State, sid: str, data: dict[str, Any]) -> None: + """ + Handle the "remove-room" message. + + This will remove the room from the server, and delete all associated data. + This is only available on an admin connection. + + :param sid: The session id of the client sending this request + :type sid: str + :rtype: None + """ + async with self.sio.session(sid) as session: + room = cast(str, session["room"]) + if room not in self.clients: + await self.sio.emit( + "msg", + {"type": "error", "msg": f"Room {room} does not exist."}, + room=sid, + ) + return + + await self.sio.emit("room-removed", {"room": room}, room=sid) + for client, _ in self.sio.manager.get_participants("/", room): + await self.sio.leave_room(client, room) + await self.sio.disconnect(client) + del self.clients[room] + logger.info("Removed room %s", room) + async def handle_register_client(self, sid: str, data: dict[str, Any]) -> None: """ Handle the "register-client" message.