import uuid from sqlalchemy.ext.asyncio import AsyncSession from db.redis import ( acquire_speaker, release_speaker, get_active_speaker ) from domains.groups.repo import get_group_by_id from integrations.livekit.token_service import generate_join_token async def request_speak( db: AsyncSession, group_id: str | uuid.UUID, user_id: str | uuid.UUID ): group_id_uuid = group_id if isinstance(group_id, uuid.UUID) else uuid.UUID(group_id) group_id_str = str(group_id_uuid) user_id_str = str(user_id) group = await get_group_by_id(db, group_id_uuid) if not group: return None # private chat → no speaker lock if str(group.type) == "private": token = generate_join_token( user_id=user_id_str, group_id=group_id_str, can_publish=True ) return token # group chat → push-to-talk granted = await acquire_speaker(group_id_str, user_id_str) if not granted: return None token = generate_join_token( user_id=user_id_str, group_id=group_id_str, can_publish=True ) return token async def stop_speaking( db: AsyncSession, group_id: str | uuid.UUID, user_id: str | uuid.UUID ): group_id_uuid = group_id if isinstance(group_id, uuid.UUID) else uuid.UUID(group_id) group_id_str = str(group_id_uuid) user_id_str = str(user_id) group = await get_group_by_id(db, group_id_uuid) if not group: return False # private chat → nothing to release if str(group.type) == "private": return True return await release_speaker(group_id_str, user_id_str) async def current_speaker( db: AsyncSession, group_id: str | uuid.UUID ): group_id_uuid = group_id if isinstance(group_id, uuid.UUID) else uuid.UUID(group_id) group_id_str = str(group_id_uuid) group = await get_group_by_id(db, group_id_uuid) if not group: return None if str(group.type) == "private": return None return await get_active_speaker(group_id_str)