add voice_rooms
This commit is contained in:
28
app/api/voice_rooms.py
Normal file
28
app/api/voice_rooms.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from fastapi import APIRouter, Body
|
||||||
|
from app.services.voice_rooms import VoiceRoomService
|
||||||
|
from app.realtime.voice_hub import voice_hub
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/api/voice")
|
||||||
|
service = VoiceRoomService()
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/rooms")
|
||||||
|
async def list_rooms():
|
||||||
|
rooms = await service.list_public_rooms()
|
||||||
|
for r in rooms:
|
||||||
|
r["users"] = len(voice_hub.rooms.get(r["id"], {}))
|
||||||
|
return rooms
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/rooms")
|
||||||
|
async def create_room(
|
||||||
|
name: str = Body(...),
|
||||||
|
public: bool = Body(True),
|
||||||
|
owner: str = Body(...),
|
||||||
|
):
|
||||||
|
return await service.create_room(name, owner, public)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/rooms/join")
|
||||||
|
async def join_private(code: str = Body(...)):
|
||||||
|
return await service.join_by_code(code)
|
||||||
@ -1,5 +1,6 @@
|
|||||||
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Query
|
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Query
|
||||||
from app.realtime.voice_hub import voice_hub
|
from app.realtime.voice_hub import voice_hub
|
||||||
|
from app.services.voice_rooms import voice_rooms_collection
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@ -9,9 +10,17 @@ async def voice_ws(
|
|||||||
room_id: str = Query(...),
|
room_id: str = Query(...),
|
||||||
username: str = Query(...)
|
username: str = Query(...)
|
||||||
):
|
):
|
||||||
|
room = await voice_rooms_collection.find_one({"id": room_id})
|
||||||
|
if not room:
|
||||||
|
await ws.close(code=4004)
|
||||||
|
return
|
||||||
if username in voice_hub.rooms.get(room_id, {}):
|
if username in voice_hub.rooms.get(room_id, {}):
|
||||||
await ws.close(code=4001)
|
await ws.close(code=4001)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if len(voice_hub.rooms.get(room_id, {})) >= room.get("max_users", 5):
|
||||||
|
await ws.close(code=4003)
|
||||||
|
return
|
||||||
|
|
||||||
await voice_hub.connect(room_id, username, ws)
|
await voice_hub.connect(room_id, username, ws)
|
||||||
|
|
||||||
|
|||||||
67
app/services/voice_rooms.py
Normal file
67
app/services/voice_rooms.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
from datetime import datetime, timedelta
|
||||||
|
from uuid import uuid4
|
||||||
|
from fastapi import HTTPException
|
||||||
|
from app.db.database import db
|
||||||
|
|
||||||
|
voice_rooms_collection = db.voice_rooms
|
||||||
|
|
||||||
|
|
||||||
|
def _serialize(doc):
|
||||||
|
if not doc:
|
||||||
|
return None
|
||||||
|
doc["_id"] = str(doc["_id"])
|
||||||
|
if "created_at" in doc:
|
||||||
|
doc["created_at"] = doc["created_at"].isoformat()
|
||||||
|
if "expires_at" in doc and doc["expires_at"]:
|
||||||
|
doc["expires_at"] = doc["expires_at"].isoformat()
|
||||||
|
return doc
|
||||||
|
|
||||||
|
|
||||||
|
class VoiceRoomService:
|
||||||
|
|
||||||
|
async def list_public_rooms(self):
|
||||||
|
rooms = await voice_rooms_collection.find(
|
||||||
|
{"public": True}
|
||||||
|
).sort("created_at", -1).to_list(100)
|
||||||
|
|
||||||
|
return [_serialize(r) for r in rooms]
|
||||||
|
|
||||||
|
async def create_room(
|
||||||
|
self,
|
||||||
|
name: str,
|
||||||
|
owner: str,
|
||||||
|
public: bool,
|
||||||
|
max_users: int = 5,
|
||||||
|
ttl_minutes: int | None = None,
|
||||||
|
):
|
||||||
|
room_id = str(uuid4())
|
||||||
|
invite_code = None if public else uuid4().hex[:6]
|
||||||
|
|
||||||
|
room = {
|
||||||
|
"id": room_id,
|
||||||
|
"name": name,
|
||||||
|
"public": public,
|
||||||
|
"invite_code": invite_code,
|
||||||
|
"owner": owner,
|
||||||
|
"max_users": max_users,
|
||||||
|
"created_at": datetime.utcnow(),
|
||||||
|
"expires_at": (
|
||||||
|
datetime.utcnow() + timedelta(minutes=ttl_minutes)
|
||||||
|
if ttl_minutes else None
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
await voice_rooms_collection.insert_one(room)
|
||||||
|
return _serialize(room)
|
||||||
|
|
||||||
|
async def get_room(self, room_id: str):
|
||||||
|
room = await voice_rooms_collection.find_one({"id": room_id})
|
||||||
|
if not room:
|
||||||
|
raise HTTPException(404, "Room not found")
|
||||||
|
return room
|
||||||
|
|
||||||
|
async def join_by_code(self, code: str):
|
||||||
|
room = await voice_rooms_collection.find_one({"invite_code": code})
|
||||||
|
if not room:
|
||||||
|
raise HTTPException(404, "Invalid invite code")
|
||||||
|
return _serialize(room)
|
||||||
Reference in New Issue
Block a user