import uuid from typing import Dict, List, Optional from sqlalchemy.orm import Session from ..models.shareplay import SharePlayRoom, SharePlayCue as SharePlayCueModel from ..models.song import Song class SharePlayManager: def __init__(self): self.rooms: Dict[str, Dict] = {} self.connections: Dict[str, set] = {} def create_room(self, db: Session, creator: str = "user") -> Dict: room_id = str(uuid.uuid4())[:8] room = SharePlayRoom( id=room_id, creator_user=creator, active_connections=1, ) db.add(room) db.commit() db.refresh(room) self.rooms[room_id] = { "song_id": None, "position": 0, "is_playing": False, "shuffle": False, "volume": 0.8, } self.connections[room_id] = set() return { "id": room_id, "creator_user": creator, "active_connections": 1, } def join_room(self, db: Session, room_id: str) -> Optional[Dict]: room = db.query(SharePlayRoom).filter(SharePlayRoom.id == room_id).first() if not room: return None room.active_connections += 1 db.commit() if room_id not in self.rooms: self.rooms[room_id] = { "song_id": room.current_song_id, "position": room.position_sec, "is_playing": room.is_playing, "shuffle": room.shuffle_mode, "volume": 0.8, } return { "id": room_id, "active_connections": room.active_connections, "state": self.rooms[room_id], } def leave_room(self, db: Session, room_id: str) -> bool: room = db.query(SharePlayRoom).filter(SharePlayRoom.id == room_id).first() if not room: return False room.active_connections = max(0, room.active_connections - 1) db.commit() if room.active_connections <= 0: self.rooms.pop(room_id, None) self.connections.pop(room_id, None) return True def get_state(self, room_id: str) -> Optional[Dict]: return self.rooms.get(room_id) def update_state(self, room_id: str, **kwargs) -> Optional[Dict]: if room_id not in self.rooms: return None self.rooms[room_id].update(kwargs) return self.rooms[room_id] def get_cue(self, db: Session, room_id: str) -> List[Dict]: cues = db.query(SharePlayCueModel).filter(SharePlayCueModel.room_id == room_id).order_by(SharePlayCueModel.position).all() result = [] for cue in cues: song = db.query(Song).filter(Song.id == cue.song_id).first() if song: result.append({ "song": { "id": song.id, "title": song.title, "artist": song.artist, "album": song.album, "duration_sec": song.duration_sec, }, "position": cue.position, "added_by": cue.added_by, }) return result def add_to_cue(self, db: Session, room_id: str, song_id: str, added_by: str = "user") -> bool: song = db.query(Song).filter(Song.id == song_id).first() if not song: return False max_pos = db.query(SharePlayCueModel).filter(SharePlayCueModel.room_id == room_id).count() cue = SharePlayCueModel( id=str(uuid.uuid4()), room_id=room_id, song_id=song_id, position=max_pos, added_by=added_by, ) db.add(cue) db.commit() return True def next_cue(self, db: Session, room_id: str) -> Optional[str]: cue = db.query(SharePlayCueModel).filter(SharePlayCueModel.room_id == room_id).order_by(SharePlayCueModel.position).first() if cue: db.delete(cue) db.commit() return cue.song_id return None