paper-dynasty-database/app/routers_v2/pitchingcards.py
2023-09-25 00:19:41 -05:00

219 lines
7.4 KiB
Python

import random
from fastapi import APIRouter, Depends, HTTPException, Query
from typing import Literal, Optional, List
import logging
import pydantic
from ..db_engine import db, PitchingCard, model_to_dict, chunked, Player, fn, MlbPlayer
from ..dependencies import oauth2_scheme, valid_token, LOG_DATA
logging.basicConfig(
filename=LOG_DATA['filename'],
format=LOG_DATA['format'],
level=LOG_DATA['log_level']
)
router = APIRouter(
prefix='/api/v2/pitchingcards',
tags=['pitchingcards']
)
class PitchingCardModel(pydantic.BaseModel):
player_id: int
variant: int = 0
balk: int = 0
wild_pitch: int = 0
hold: int = 0
starter_rating: int = 1
relief_rating: int = 0
closer_rating: int = None
batting: str = "#1WR-C"
offense_col: int = None
hand: Literal['R', 'L', 'S'] = 'R'
class PitchingCardList(pydantic.BaseModel):
cards: List[PitchingCardModel]
@router.get('')
async def get_pitching_cards(
player_id: list = Query(default=None), player_name: list = Query(default=None),
cardset_id: list = Query(default=None), short_output: bool = False, limit: Optional[int] = None):
all_cards = PitchingCard.select()
if player_id is not None:
all_cards = all_cards.where(PitchingCard.player_id << player_id)
if cardset_id is not None:
all_players = Player.select().where(Player.cardset_id << cardset_id)
all_cards = all_cards.where(PitchingCard.player << all_players)
if player_name is not None:
name_list = [x.lower() for x in player_name]
all_players = Player.select().where(fn.lower(Player.p_name) << name_list)
all_cards = all_cards.where(PitchingCard.player << all_players)
if limit is not None:
all_cards = all_cards.limit(limit)
return_val = {'count': all_cards.count(), 'cards': [
model_to_dict(x, recurse=not short_output) for x in all_cards
]}
db.close()
return return_val
@router.get('/{card_id}')
async def get_one_card(card_id: int):
this_card = PitchingCard.get_or_none(PitchingCard.id == card_id)
if this_card is None:
db.close()
raise HTTPException(status_code=404, detail=f'PitchingCard id {card_id} not found')
r_card = model_to_dict(this_card)
db.close()
return r_card
@router.get('/player/{player_id}')
async def get_player_cards(player_id: int, variant: list = Query(default=None), short_output: bool = False):
all_cards = PitchingCard.select().where(PitchingCard.player_id == player_id).order_by(PitchingCard.variant)
if variant is not None:
all_cards = all_cards.where(PitchingCard.variant << variant)
return_val = {'count': all_cards.count(), 'cards': [
model_to_dict(x, recurse=not short_output) for x in all_cards
]}
db.close()
return return_val
@router.put('')
async def put_cards(cards: PitchingCardList, token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
db.close()
raise HTTPException(
status_code=401,
detail='You are not authorized to post pitching cards. This event has been logged.'
)
new_cards = []
updates = 0
for x in cards.cards:
try:
old = PitchingCard.get(
(PitchingCard.player_id == x.player_id) & (PitchingCard.variant == x.variant)
)
if x.offense_col is None:
x.offense_col = old.offense_col
updates += PitchingCard.update(x.dict()).where(
(PitchingCard.player_id == x.player_id) & (PitchingCard.variant == x.variant)
).execute()
except PitchingCard.DoesNotExist:
if x.offense_col is None:
this_player = Player.get_or_none(Player.player_id == x.player_id)
mlb_player = MlbPlayer.get_or_none(MlbPlayer.key_bbref == this_player.bbref_id)
if mlb_player is not None:
logging.info(f'setting offense_col to {mlb_player.offense_col} for {this_player.p_name}')
x.offense_col = mlb_player.offense_col
else:
logging.info(f'randomly setting offense_col for {this_player.p_name}')
x.offense_col = random.randint(1, 3)
logging.debug(f'x.dict(): {x.dict()}')
new_cards.append(x.dict())
with db.atomic():
for batch in chunked(new_cards, 30):
PitchingCard.insert_many(batch).on_conflict_replace().execute()
db.close()
return f'Updated cards: {updates}; new cards: {len(new_cards)}'
@router.patch('/{card_id}')
async def patch_card(
card_id: int, balk: Optional[int] = None, wild_pitch: Optional[int] = None, hold: Optional[int] = None,
starter_rating: Optional[int] = None, relief_rating: Optional[int] = None, closer_rating: Optional[int] = None,
batting: Optional[int] = None, token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
db.close()
raise HTTPException(
status_code=401,
detail='You are not authorized to patch pitching cards. This event has been logged.'
)
this_card = PitchingCard.get_or_none(PitchingCard.id == card_id)
if this_card is None:
db.close()
raise HTTPException(status_code=404, detail=f'PitchingCard id {card_id} not found')
if balk is not None:
this_card.balk = balk
if wild_pitch is not None:
this_card.wild_pitch = wild_pitch
if hold is not None:
this_card.hold = hold
if starter_rating is not None:
this_card.starter_rating = starter_rating
if relief_rating is not None:
this_card.relief_rating = relief_rating
if closer_rating is not None:
this_card.closer_rating = closer_rating
if batting is not None:
this_card.batting = batting
if this_card.save() == 1:
return_val = model_to_dict(this_card)
db.close()
return return_val
else:
db.close()
raise HTTPException(
status_code=418,
detail='Well slap my ass and call me a teapot; I could not save that card'
)
@router.delete('/{card_id}')
async def delete_card(card_id: int, token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
db.close()
raise HTTPException(
status_code=401,
detail='You are not authorized to delete pitching cards. This event has been logged.'
)
this_card = PitchingCard.get_or_none(PitchingCard.id == card_id)
if this_card is None:
db.close()
raise HTTPException(status_code=404, detail=f'Pitching id {card_id} not found')
count = this_card.delete_instance()
db.close()
if count == 1:
return f'Card {this_card} has been deleted'
else:
raise HTTPException(status_code=500, detail=f'Card {this_card} could not be deleted')
@router.delete('')
async def delete_all_cards(token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
db.close()
raise HTTPException(
status_code=401,
detail='You are not authorized to delete pitching cards. This event has been logged.'
)
d_query = PitchingCard.delete()
d_query.execute()
return f'Deleted {d_query.count()} pitching cards'