initial commit
This commit is contained in:
128
backend/app/routes/rooms.py
Normal file
128
backend/app/routes/rooms.py
Normal file
@@ -0,0 +1,128 @@
|
||||
from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import Dict, List
|
||||
from pydantic import BaseModel
|
||||
import random
|
||||
import string
|
||||
from app.database import get_db
|
||||
from app.models.models import Room, User, Song, Playlist
|
||||
from app.auth import get_current_user
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
class RoomCreate(BaseModel):
|
||||
name: str
|
||||
|
||||
class ConnectionManager:
|
||||
def __init__(self):
|
||||
self.active_connections: Dict[str, List[dict]] = {}
|
||||
|
||||
async def connect(self, websocket: WebSocket, room_code: str, username: str):
|
||||
await websocket.accept()
|
||||
if room_code not in self.active_connections:
|
||||
self.active_connections[room_code] = []
|
||||
|
||||
# Проверяем, не подключен ли уже этот пользователь
|
||||
existing = [conn for conn in self.active_connections[room_code] if conn["username"] == username]
|
||||
if not existing:
|
||||
self.active_connections[room_code].append({"ws": websocket, "username": username})
|
||||
|
||||
await self.broadcast({"type": "user_count", "count": len(self.active_connections[room_code])}, room_code)
|
||||
|
||||
def disconnect(self, websocket: WebSocket, room_code: str):
|
||||
if room_code in self.active_connections:
|
||||
self.active_connections[room_code] = [
|
||||
conn for conn in self.active_connections[room_code] if conn["ws"] != websocket
|
||||
]
|
||||
return len(self.active_connections[room_code])
|
||||
return 0
|
||||
|
||||
async def broadcast(self, message: dict, room_code: str):
|
||||
if room_code in self.active_connections:
|
||||
disconnected = []
|
||||
for connection in self.active_connections[room_code]:
|
||||
try:
|
||||
await connection["ws"].send_json(message)
|
||||
except:
|
||||
disconnected.append(connection)
|
||||
|
||||
# Удаляем отключенные соединения
|
||||
for conn in disconnected:
|
||||
if conn in self.active_connections[room_code]:
|
||||
self.active_connections[room_code].remove(conn)
|
||||
|
||||
def get_user_count(self, room_code: str):
|
||||
if room_code in self.active_connections:
|
||||
return len(self.active_connections[room_code])
|
||||
return 0
|
||||
|
||||
manager = ConnectionManager()
|
||||
|
||||
def generate_room_code():
|
||||
return ''.join(random.choices(string.ascii_uppercase + string.digits, k=6))
|
||||
|
||||
@router.post("/create")
|
||||
def create_room(
|
||||
room: RoomCreate,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
code = generate_room_code()
|
||||
db_room = Room(name=room.name, code=code, creator_id=current_user.id)
|
||||
db.add(db_room)
|
||||
db.commit()
|
||||
db.refresh(db_room)
|
||||
return db_room
|
||||
|
||||
@router.get("/{room_code}")
|
||||
def get_room(room_code: str, db: Session = Depends(get_db)):
|
||||
room = db.query(Room).filter(Room.code == room_code).first()
|
||||
if not room:
|
||||
raise HTTPException(status_code=404, detail="Room not found")
|
||||
user_count = manager.get_user_count(room_code)
|
||||
return {**room.__dict__, "user_count": user_count}
|
||||
|
||||
@router.post("/{room_code}/add-song/{song_id}")
|
||||
def add_song_to_room(
|
||||
room_code: str,
|
||||
song_id: int,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
room = db.query(Room).filter(Room.code == room_code).first()
|
||||
if not room:
|
||||
raise HTTPException(status_code=404, detail="Room not found")
|
||||
|
||||
song = db.query(Song).filter(Song.id == song_id).first()
|
||||
if not song:
|
||||
raise HTTPException(status_code=404, detail="Song not found")
|
||||
|
||||
return {"message": "Song added to queue"}
|
||||
|
||||
@router.post("/{room_code}/add-playlist/{playlist_id}")
|
||||
def add_playlist_to_room(
|
||||
room_code: str,
|
||||
playlist_id: int,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
room = db.query(Room).filter(Room.code == room_code).first()
|
||||
if not room:
|
||||
raise HTTPException(status_code=404, detail="Room not found")
|
||||
|
||||
playlist = db.query(Playlist).filter(Playlist.id == playlist_id).first()
|
||||
if not playlist:
|
||||
raise HTTPException(status_code=404, detail="Playlist not found")
|
||||
|
||||
return {"message": "Playlist added to queue", "songs": [{"id": s.id, "title": s.title, "artist": s.artist} for s in playlist.songs]}
|
||||
|
||||
@router.websocket("/ws/{room_code}")
|
||||
async def websocket_endpoint(websocket: WebSocket, room_code: str, username: str = "User"):
|
||||
await manager.connect(websocket, room_code, username)
|
||||
try:
|
||||
while True:
|
||||
data = await websocket.receive_json()
|
||||
await manager.broadcast(data, room_code)
|
||||
except WebSocketDisconnect:
|
||||
count = manager.disconnect(websocket, room_code)
|
||||
await manager.broadcast({"type": "user_count", "count": count}, room_code)
|
||||
Reference in New Issue
Block a user