import logging from fastapi import APIRouter, Depends, HTTPException from ...db_engine import db, StratPlay, StratGame, model_to_dict, chunked from ...dependencies import ( oauth2_scheme, valid_token, PRIVATE_IN_SCHEMA, handle_db_errors, ) from .models import PlayModel, PlayList router = APIRouter() logger = logging.getLogger("discord_app") @router.get("/{play_id}") @handle_db_errors async def get_one_play(play_id: int): if StratPlay.get_or_none(StratPlay.id == play_id) is None: db.close() raise HTTPException(status_code=404, detail=f"Play ID {play_id} not found") r_play = model_to_dict(StratPlay.get_by_id(play_id)) db.close() return r_play @router.patch("/{play_id}", include_in_schema=PRIVATE_IN_SCHEMA) @handle_db_errors async def patch_play( play_id: int, new_play: PlayModel, token: str = Depends(oauth2_scheme) ): if not valid_token(token): logger.warning(f"patch_play - Bad Token: {token}") raise HTTPException(status_code=401, detail="Unauthorized") if StratPlay.get_or_none(StratPlay.id == play_id) is None: db.close() raise HTTPException(status_code=404, detail=f"Play ID {play_id} not found") StratPlay.update(**new_play.dict()).where(StratPlay.id == play_id).execute() r_play = model_to_dict(StratPlay.get_by_id(play_id)) db.close() return r_play @router.post("/", include_in_schema=PRIVATE_IN_SCHEMA) @handle_db_errors async def post_plays(p_list: PlayList, token: str = Depends(oauth2_scheme)): if not valid_token(token): logger.warning(f"post_plays - Bad Token: {token}") raise HTTPException(status_code=401, detail="Unauthorized") new_plays = [] this_game = StratGame.get_or_none(StratGame.id == p_list.plays[0].game_id) if this_game is None: raise HTTPException( status_code=404, detail=f"Game ID {p_list.plays[0].game_id} not found" ) for play in p_list.plays: this_play = play this_play.inning_half = this_play.inning_half.lower() top_half = this_play.inning_half == "top" if this_play.batter_team_id is None and this_play.batter_id is not None: this_play.batter_team_id = ( this_game.away_team.id if top_half else this_game.home_team.id ) if this_play.pitcher_team_id is None: this_play.pitcher_team_id = ( this_game.home_team.id if top_half else this_game.away_team.id ) if this_play.catcher_id is not None: this_play.catcher_team_id = ( this_game.home_team.id if top_half else this_game.away_team.id ) if this_play.defender_id is not None: this_play.defender_team_id = ( this_game.home_team.id if top_half else this_game.away_team.id ) if this_play.runner_id is not None: this_play.runner_team_id = ( this_game.away_team.id if top_half else this_game.home_team.id ) if this_play.pa == 0: this_play.batter_final = None new_plays.append(this_play.dict()) with db.atomic(): for batch in chunked(new_plays, 20): StratPlay.insert_many(batch).on_conflict_ignore().execute() db.close() return f"Inserted {len(new_plays)} plays" @router.delete("/{play_id}", include_in_schema=PRIVATE_IN_SCHEMA) @handle_db_errors async def delete_play(play_id: int, token: str = Depends(oauth2_scheme)): if not valid_token(token): logger.warning(f"delete_play - Bad Token: {token}") raise HTTPException(status_code=401, detail="Unauthorized") this_play = StratPlay.get_or_none(StratPlay.id == play_id) if not this_play: db.close() raise HTTPException(status_code=404, detail=f"Play ID {play_id} not found") count = this_play.delete_instance() db.close() if count == 1: return f"Play {play_id} has been deleted" else: raise HTTPException( status_code=500, detail=f"Play {play_id} could not be deleted" ) @router.delete("/game/{game_id}", include_in_schema=PRIVATE_IN_SCHEMA) @handle_db_errors async def delete_plays_game(game_id: int, token: str = Depends(oauth2_scheme)): if not valid_token(token): logger.warning(f"delete_plays_game - Bad Token: {token}") raise HTTPException(status_code=401, detail="Unauthorized") this_game = StratGame.get_or_none(StratGame.id == game_id) if not this_game: db.close() raise HTTPException(status_code=404, detail=f"Game ID {game_id} not found") count = StratPlay.delete().where(StratPlay.game == this_game).execute() db.close() if count > 0: return f"Deleted {count} plays matching Game ID {game_id}" else: raise HTTPException( status_code=500, detail=f"No plays matching Game ID {game_id} were deleted" ) @router.post("/erun-check", include_in_schema=PRIVATE_IN_SCHEMA) @handle_db_errors async def post_erun_check(token: str = Depends(oauth2_scheme)): if not valid_token(token): logger.warning(f"post_erun_check - Bad Token: {token}") raise HTTPException(status_code=401, detail="Unauthorized") all_plays = StratPlay.update(run=1).where( (StratPlay.e_run == 1) & (StratPlay.run == 0) ) count = all_plays.execute() db.close() return count