File size: 8,891 Bytes
d60934b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
from fastapi import APIRouter, HTTPException, Query
from typing import List, Optional
import json
from pathlib import Path
from app.core.logging import get_logger
from app.services.session_service import SessionService
from app.utils.file_management import FileManager
router = APIRouter(tags=["players"])
logger = get_logger("players")
def load_json_file(file_path: str) -> dict:
try:
with open(file_path, "r") as f:
logger.debug(f"Loading JSON file: {file_path}")
return json.load(f)
except FileNotFoundError:
logger.error(f"File not found: {file_path}")
return {}
except json.JSONDecodeError as e:
logger.error(f"JSON decode error in {file_path}: {str(e)}")
return {}
@router.get("/api/players/{session_id}/{wagon_id}/{player_id}")
async def get_player_info(
session_id: str,
wagon_id: str,
player_id: str,
properties: Optional[List[str]] = Query(None, description="Filter specific properties")
):
logger.info(
f"Getting player info | session_id: {session_id} | wagon_id: {wagon_id} | player_id: {player_id} | requested_properties: {properties}"
)
try:
session = SessionService.get_session(session_id)
if not session:
logger.error(f"Session not found: {session_id}")
raise HTTPException(status_code=404, detail="Session not found")
logger.debug(
f"Loading session data | session_id: {session_id} | default_game: {session.default_game}"
)
# Load data based on default_game flag
names, player_details, _ = FileManager.load_session_data(session_id, session.default_game)
# try to convert the wagon_id to an integer if it is not already an integer
try:
wagon_index = int(wagon_id.split("-")[1])
except ValueError:
logger.error(f"Invalid wagon_id: {wagon_id}")
raise HTTPException(status_code=404, detail="Invalid wagon_id")
try:
# First check if player_details is contained in the loaded data
if len(player_details) == 0:
logger.error("Missing 'player_details' key in loaded data")
raise HTTPException(status_code=404, detail="Player details not found")
# players is a list of dictionaries, so we need to filter the list for the player_id
player_info = next((player for player in player_details[wagon_index]["players"] if player["playerId"] == player_id), None)
# check if player_info is found
if player_info is None:
logger.error(f"Player info not found | wagon: {wagon_id} | player: {player_id}")
raise HTTPException(status_code=404, detail="Player info not found")
logger.debug(
f"Found player info | wagon: {wagon_id} | player: {player_id} | profile_exists: {'profile' in player_info}"
)
# first check if names is contained in the loaded data
if len(names) == 0:
logger.error("Missing 'names' key in loaded data")
raise HTTPException(status_code=404, detail="Names not found")
# "players" is a list of dictionaries, so we need to filter the list for the player_id
name_info = next((player for player in names[wagon_index]["players"] if player["playerId"] == player_id), None)
# check if name_info is found
if name_info is None:
logger.error(f"Name info not found | wagon: {wagon_id} | player: {player_id}")
raise HTTPException(status_code=404, detail="Name info not found")
logger.debug(
f"Found name info | wagon: {wagon_id} | player: {player_id}"
)
# Combine information
player_in_current_wagon_info = {
"id": player_id,
"name_info": name_info,
"profile": player_info.get("profile", {})
}
# Filter properties if specified
if properties:
logger.info(
f"Filtering player info | requested_properties: {properties} | available_properties: {list(player_in_current_wagon_info.keys())}"
)
logger.info("Successfully retrieved complete player info")
return player_in_current_wagon_info
except KeyError as e:
logger.error(
f"Failed to find player data | error: {str(e)} | wagon_id: {wagon_id} | player_id: {player_id}"
)
raise HTTPException(status_code=404, detail="Player not found")
except FileNotFoundError as e:
logger.error(
f"Failed to load session data | error: {str(e)} | session_id: {session_id}"
)
raise HTTPException(status_code=404, detail="Session not found")
@router.get("/api/players/{session_id}/{wagon_id}")
async def get_wagon_players(
session_id: str,
wagon_id: str,
properties: Optional[List[str]] = Query(
None,
description="Filter specific properties (name_info, profile, traits, inventory, dialogue)",
),
):
session = SessionService.get_session(session_id)
# check if session is found
if not session:
logger.error(f"Session not found: {session_id}")
raise HTTPException(status_code=404, detail="Session not found")
logger.info(f"Getting all players for wagon_id={wagon_id} | session_id={session_id}")
if properties:
logger.info(f"Requested properties: {properties}")
logger.debug(
f"Loading session data | session_id={session_id} | default_game={session.default_game}"
)
# try catch for wagon_index
try:
wagon_index = int(wagon_id.split("-")[1])
except ValueError:
logger.error(f"Invalid wagon_id: {wagon_id}")
raise HTTPException(status_code=404, detail="Invalid wagon_id")
wagon_index = int(wagon_id.split("-")[1])
try:
# Load data based on default_game flag
names, player_details, _ = FileManager.load_session_data(session_id, session.default_game)
if len(player_details) == 0:
# check if player_details is contained in the loaded data
logger.error("player_details is empty")
raise HTTPException(status_code=404, detail="Player details not found")
# Check if player details exists for the wagon_index
# should check whether None or empty list
if not player_details[wagon_index]["players"]:
logger.error(f"Player details not found for wagon_index={wagon_index}")
raise HTTPException(status_code=404, detail="Player details not found")
players_in_current_wagon = player_details[wagon_index]["players"]
logger.debug(f"Found player info | wagon={wagon_id} | player_count={len(players_in_current_wagon)}")
# check if names is contained in the loaded data
if len(names) == 0:
logger.error("names is empty")
raise HTTPException(status_code=404, detail="Names not found")
names_in_current_wagon = names[wagon_index]
logger.debug(f"Found name info | wagon={wagon_id} | name_count={len(names_in_current_wagon)}")
# Create dictionaries for quick lookup by player ID
name_info = {
player["playerId"]: player
for player in names_in_current_wagon["players"]
}
player_info = {
player["playerId"]: player
for player in players_in_current_wagon
}
# Combine information for all players in the wagon
players_in_current_wagon_info = []
for player_id in player_info:
logger.debug(f"Processing player | wagon={wagon_id} | player={player_id}")
complete_info = {
"id": player_id,
"name_info": name_info.get(player_id, {}),
"profile": player_info[player_id].get("profile", {})
}
players_in_current_wagon_info.append(complete_info)
logger.info(f"Successfully retrieved all players | wagon={wagon_id} | player_count={len(players_in_current_wagon_info)}")
return {"players": players_in_current_wagon_info}
except FileNotFoundError as e:
logger.error(f"Failed to load session data | error={str(e)} | session_id={session_id}")
raise HTTPException(status_code=404, detail="Session data not found")
except Exception as e:
logger.error(f"Unexpected error | error={str(e)} | wagon_id={wagon_id}")
raise HTTPException(status_code=500, detail="Internal server error")
|