コード例 #1
0
async def get_room_by_id_minimal(room_id: int, user_id: int,
                                 config: Config) -> Dict:
    """
    Get data for a room by id, redacting secret information like the room code
    """
    try:
        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            room = await room_persistence.get_room(room_id)
            if not room or not room.get("active"):
                raise err.not_found(f"No active room with id {room_id}")
            user_in_room = await is_user_in_room(user_id,
                                                 room_id,
                                                 db,
                                                 room=room)
            return {
                "room_id": room.get("room_id"),
                "owner_id": room.get("owner_id"),
                "room_name": room.get("room_name"),
                "has_code": bool(room.get("room_code")),
                "user_in_room": user_in_room
            }
    except Exception as e:
        logger.exception("Failed to retrieve minimal data for room %s: %s",
                         room_id, e)
        raise e
コード例 #2
0
async def find_room(query: Dict, config: Config) -> Dict:
    """get a room's ID using either the owner's ID or the room ID
    in the case of supplying the latter, this simply verifies that a room
    with that ID exists"""

    if "owner_id" in query:
        resource_name = "owner_id"
        query_method = rooms.RoomPersistence.get_room_by_owner
    elif "room_id" in query:
        resource_name = "room_id"
        query_method = rooms.RoomPersistence.get_room
    else:
        raise err.bad_request(
            "Supply either a room_id or an owner_id to search for")

    try:
        resource_id = int(query[resource_name])
    except ValueError:
        raise err.bad_request(
            f"'{query[resource_name]}' is not a valid {resource_name}")

    try:
        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            room = await query_method(room_persistence, resource_id)
            if not room or not room.get("active"):
                raise err.not_found(
                    f"No active rooms found for {resource_name} {resource_id}")
            else:
                return {"room_id": room["room_id"]}
    except HTTPException:
        raise
    except Exception as e:
        logger.exception("Failed to find room with query %s: %s", query, e)
        raise e
コード例 #3
0
async def deactivate_room(user_id: int, room_id: int, config: Config) -> Dict:
    """Process a request from an owner to deactivate an owned room"""
    try:
        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            room = await room_persistence.get_room(room_id)
            if not room or not room.get("active"):
                raise err.not_found(f"Active room with id {room_id} not found")

            if room["owner_id"] != user_id:
                raise err.forbidden(
                    "User is not permitted to deactivate this room")

            await room_persistence.deactivate_room(room_id)

            return {
                "success": True,
                "message": "Successfully deactivated the room"
            }
    except HTTPException:
        raise
    except Exception as e:
        logger.exception("Failed to deactivate rooms for user %s: %s", user_id,
                         e)
        raise e
コード例 #4
0
async def join_room(user_id: int, room_id: int, room_code: Optional[str],
                    config: Config) -> Dict:
    """Process a request from a user to join a room"""
    try:
        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            room = await room_persistence.get_room(room_id)
            if not room or not room.get("active"):
                raise err.not_found(f"Active room with id {room_id} not found")

            if await is_user_in_room(user_id, room_id, db, room=room):
                return {"success": True, "message": "User is already in room"}

            if room.get("room_code"):
                if room["room_code"] != room_code:
                    return {"success": False, "message": "Invalid room code"}

            await room_persistence.add_user_to_room(room_id, user_id)

            return {"success": True, "message": "Successfully joined the room"}
    except HTTPException:
        raise
    except Exception as e:
        logger.exception("Failed to get rooms for user %s: %s", user_id, e)
        raise e
コード例 #5
0
async def search(user_id: int, room_id: int, query: str,
                 config: Config) -> Dict:
    if not query:
        raise err.bad_request("No query string supplied to search for")

    try:
        async with config.get_database_connection() as db:
            room = await get_room_for_user_assertive(room_id, user_id, db)
            token_result = await spotify.get_valid_token_for_user(
                room["owner_id"], config, requested_by=user_id)
            token = _handle_token_result(token_result)

        search_results = await config.get_spotify_api().search(query, token)
        return {
            "results":
            extract_relevant_data_from_search_results(search_results)
        }
    except HTTPException:
        raise
    except ClientResponseError as e:
        logger.warning(
            "Failed to enqueue track with Spotify for user %s in room %s: %s",
            user_id, room_id, e)
        if e.status == 403:
            raise err.forbidden(
                "Unable to enqueue track: user is not a premium subscriber")
        if e.status == 404:
            raise err.not_found("The requested track could not be found")
        raise e
    except Exception as e:
        logger.exception(
            "Failed to play track for user(id=%s) in room(id=%s): %s", user_id,
            room_id, e)
        raise
コード例 #6
0
async def enqueue_song(user_id: int, room_id: int, track_uri: str,
                       config: Config) -> Dict:
    try:
        async with config.get_database_connection() as db:
            room = await get_room_for_user_assertive(room_id, user_id, db)
            token_result = await spotify.get_valid_token_for_user(
                room["owner_id"], config, requested_by=user_id)
            token = _handle_token_result(token_result)

        await config.get_spotify_api().enqueue_song(track_uri, token)

        return {"success": True}

    except HTTPException:
        raise
    except ClientResponseError as e:
        logger.warning(
            "Failed to enqueue track with Spotify for user %s in room %s: %s",
            user_id, room_id, e)
        if e.status == 403:
            raise err.forbidden(
                "Unable to enqueue track: user is not a premium subscriber")
        if e.status == 404:
            raise err.not_found("The requested track could not be found")
        raise e
    except Exception as e:
        logger.exception(
            "Failed to play track for user(id=%s) in room(id=%s): %s", user_id,
            room_id, e)
        raise
コード例 #7
0
async def get_room_for_user_assertive(room_id: int, user_id: int,
                                      db: Connection):
    """
    helper method to get a room if the room exists, is active, and the user is a member of it
    raises HTTPException if any condition fails
    """
    room_persistence = rooms.RoomPersistence(db)
    room = await room_persistence.get_room(room_id)
    if not room:
        raise err.not_found(f"No room with id {room_id}")

    user_in_room = await is_user_in_room(user_id, room_id, db, room=room)

    if not user_in_room:
        raise err.forbidden(
            f"User {user_id} is not a member of room {room_id}")
    elif not room.get("active"):
        raise err.not_found(f"No active room with id {room_id}")
    else:
        return room