129 lines
4.2 KiB
Python
129 lines
4.2 KiB
Python
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 |