Added battingcards and ratings
This commit is contained in:
parent
88b723d9f2
commit
22cc01d200
@ -28,9 +28,6 @@ logging.basicConfig(
|
||||
|
||||
|
||||
def model_csv_headers(this_obj, exclude=None) -> List:
|
||||
if this_obj is None:
|
||||
return ['None']
|
||||
|
||||
data = model_to_dict(this_obj, recurse=False, exclude=exclude)
|
||||
return [x for x in data.keys()]
|
||||
|
||||
@ -41,9 +38,47 @@ def model_to_csv(this_obj, exclude=None) -> List:
|
||||
|
||||
|
||||
def query_to_csv(all_items: ModelSelect, exclude=None):
|
||||
data_list = [model_csv_headers(all_items[0], exclude=exclude)]
|
||||
for x in all_items:
|
||||
data_list.append(model_to_csv(x, exclude=exclude))
|
||||
if all_items.count() == 0:
|
||||
data_list = [['No data found']]
|
||||
else:
|
||||
data_list = [model_csv_headers(all_items[0], exclude=exclude)]
|
||||
for x in all_items:
|
||||
data_list.append(model_to_csv(x, exclude=exclude))
|
||||
|
||||
return DataFrame(data_list).to_csv(header=False, index=False)
|
||||
|
||||
|
||||
def complex_data_to_csv(complex_data: List):
|
||||
if len(complex_data) == 0:
|
||||
data_list = [['No data found']]
|
||||
else:
|
||||
data_list = [[x for x in complex_data[0].keys()]]
|
||||
for line in complex_data:
|
||||
logging.info(f'line: {line}')
|
||||
this_row = []
|
||||
for key in line:
|
||||
logging.info(f'key: {key}')
|
||||
if line[key] is None:
|
||||
this_row.append('')
|
||||
|
||||
elif isinstance(line[key], dict):
|
||||
if 'name' in line[key]:
|
||||
this_row.append(line[key]['name'])
|
||||
elif 'abbrev' in line[key]:
|
||||
this_row.append(line[key]['abbrev'])
|
||||
else:
|
||||
this_row.append(line[key]['id'])
|
||||
|
||||
elif isinstance(line[key], int) and line[key] > 100000000:
|
||||
this_row.append(f"'{line[key]}")
|
||||
|
||||
elif isinstance(line[key], str) and ',' in line[key]:
|
||||
this_row.append(line[key].replace(",", "-_-"))
|
||||
|
||||
else:
|
||||
this_row.append(line[key])
|
||||
|
||||
data_list.append(this_row)
|
||||
|
||||
return DataFrame(data_list).to_csv(header=False, index=False)
|
||||
|
||||
@ -526,7 +561,7 @@ BattingCard.add_index(BattingCard.player, BattingCard.variant)
|
||||
|
||||
class BattingCardRatings(BaseModel):
|
||||
battingcard = ForeignKeyField(BattingCard)
|
||||
vs_hand = FloatField()
|
||||
vs_hand = CharField(default='R')
|
||||
homerun = FloatField()
|
||||
bp_homerun = FloatField()
|
||||
triple = FloatField()
|
||||
@ -554,8 +589,12 @@ class BattingCardRatings(BaseModel):
|
||||
slg = FloatField(null=True)
|
||||
|
||||
|
||||
BattingCardRatings.add_index(BattingCardRatings.battingcard, BattingCardRatings.vs_hand)
|
||||
|
||||
|
||||
class PitchingCard(BaseModel):
|
||||
player = ForeignKeyField(Player)
|
||||
variant = IntegerField()
|
||||
balk = IntegerField()
|
||||
wild_pitch = IntegerField(null=True)
|
||||
hold = CharField()
|
||||
@ -565,9 +604,12 @@ class PitchingCard(BaseModel):
|
||||
batting = CharField(null=True)
|
||||
|
||||
|
||||
PitchingCard.add_index(PitchingCard.player, PitchingCard.variant)
|
||||
|
||||
|
||||
class PitchingCardRatings(BaseModel):
|
||||
pitchingcard = ForeignKeyField(PitchingCard)
|
||||
vs_hand = CharField()
|
||||
vs_hand = CharField(default='R')
|
||||
homerun = FloatField()
|
||||
bp_homerun = FloatField()
|
||||
triple = FloatField()
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
from fastapi import FastAPI
|
||||
|
||||
from.routers_v2 import current, teams, rarity, cardsets, players, packtypes, packs, cards, events, results, rewards, \
|
||||
batstats, pitstats, notifications, paperdex, gamerewards, gauntletrewards, gauntletruns, battingcard
|
||||
from.routers_v2 import (
|
||||
current, teams, rarity, cardsets, players, packtypes, packs, cards, events, results, rewards,
|
||||
batstats, pitstats, notifications, paperdex, gamerewards, gauntletrewards, gauntletruns, battingcards,
|
||||
battingcardratings)
|
||||
|
||||
app = FastAPI(
|
||||
responses={404: {'description': 'Not found'}}
|
||||
@ -25,4 +27,5 @@ app.include_router(paperdex.router)
|
||||
app.include_router(gamerewards.router)
|
||||
app.include_router(gauntletrewards.router)
|
||||
app.include_router(gauntletruns.router)
|
||||
app.include_router(battingcard.router)
|
||||
app.include_router(battingcards.router)
|
||||
app.include_router(battingcardratings.router)
|
||||
|
||||
182
app/routers_v2/battingcardratings.py
Normal file
182
app/routers_v2/battingcardratings.py
Normal file
@ -0,0 +1,182 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from typing import Literal, Optional, List
|
||||
import logging
|
||||
import pydantic
|
||||
from pydantic import validator, root_validator
|
||||
|
||||
from ..db_engine import db, BattingCardRatings, model_to_dict, chunked, BattingCard
|
||||
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/battingcardratings',
|
||||
tags=['battingcardratings']
|
||||
)
|
||||
|
||||
|
||||
class BattingCardRatingsModel(pydantic.BaseModel):
|
||||
battingcard_id: int
|
||||
vs_hand: Literal['R', 'L', 'vR', 'vL']
|
||||
homerun: float = 0.0
|
||||
bp_homerun: float = 0.0
|
||||
triple: float = 0.0
|
||||
double_three: float = 0.0
|
||||
double_two: float = 0.0
|
||||
double_pull: float = 0.0
|
||||
single_two: float = 0.0
|
||||
single_one: float = 0.0
|
||||
single_center: float = 0.0
|
||||
bp_single: float = 0.0
|
||||
hbp: float = 0.0
|
||||
walk: float = 0.0
|
||||
strikeout: float = 0.0
|
||||
lineout: float = 0.0
|
||||
popout: float = 0.0
|
||||
flyout_a: float = 0.0
|
||||
flyout_bq: float = 0.0
|
||||
flyout_lf_b: float = 0.0
|
||||
flyout_rf_b: float = 0.0
|
||||
groundout_a: float = 0.0
|
||||
groundout_b: float = 0.0
|
||||
groundout_c: float = 0.0
|
||||
avg: float = 0.0
|
||||
obp: float = 0.0
|
||||
slg: float = 0.0
|
||||
|
||||
@validator("avg", always=True)
|
||||
def avg_validator(cls, v, values, **kwargs):
|
||||
return (values['homerun'] + values['bp_homerun'] / 2 + values['triple'] + values['double_three'] +
|
||||
values['double_two'] + values['double_pull'] + values['single_two'] + values['single_one'] +
|
||||
values['single_center'] + values['bp_single'] / 2) / 108
|
||||
|
||||
@validator("obp", always=True)
|
||||
def obp_validator(cls, v, values, **kwargs):
|
||||
return ((values['hbp'] + values['walk']) / 108) + values['avg']
|
||||
|
||||
@validator("slg", always=True)
|
||||
def slg_validator(cls, v, values, **kwargs):
|
||||
return (values['homerun'] * 4 + values['bp_homerun'] * 2 + values['triple'] * 3 + values['double_three'] * 2 +
|
||||
values['double_two'] * 2 + values['double_pull'] * 2 + values['single_two'] + values['single_one'] +
|
||||
values['single_center'] + values['bp_single'] / 2) / 108
|
||||
|
||||
@root_validator
|
||||
def validate_chance_total(cls, values):
|
||||
total_chances = (
|
||||
values['homerun'] + values['bp_homerun'] + values['triple'] + values['double_three'] +
|
||||
values['double_two'] + values['double_pull'] + values['single_two'] + values['single_one'] +
|
||||
values['single_center'] + values['bp_single'] + values['hbp'] + values['walk'] +
|
||||
values['strikeout'] + values['lineout'] + values['popout'] + values['flyout_a'] +
|
||||
values['flyout_bq'] + values['flyout_lf_b'] + values['flyout_rf_b'] + values['groundout_a'] +
|
||||
values['groundout_b'] + values['groundout_c'])
|
||||
|
||||
if total_chances != 108:
|
||||
raise ValueError("Must have exactly 108 chances on the card")
|
||||
return values
|
||||
|
||||
|
||||
class RatingsList(pydantic.BaseModel):
|
||||
ratings: List[BattingCardRatingsModel]
|
||||
|
||||
|
||||
@router.get('')
|
||||
async def get_card_ratings(
|
||||
battingcard_id: list = Query(default=None), vs_hand: Literal['R', 'L', 'vR', 'vL'] = None,
|
||||
short_output: bool = False, 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 pull card ratings.'
|
||||
)
|
||||
|
||||
all_ratings = BattingCardRatings.select()
|
||||
|
||||
if battingcard_id is not None:
|
||||
all_ratings = all_ratings.where(BattingCardRatings.battingcard_id << battingcard_id)
|
||||
if vs_hand is not None:
|
||||
all_ratings = all_ratings.where(BattingCardRatings.vs_hand << vs_hand[-1])
|
||||
|
||||
return_val = {'count': all_ratings.count(), 'ratings': [
|
||||
model_to_dict(x, recurse=not short_output) for x in all_ratings
|
||||
]}
|
||||
db.close()
|
||||
return return_val
|
||||
|
||||
|
||||
@router.get('/{ratings_id}')
|
||||
async def get_one_rating(ratings_id: int):
|
||||
this_rating = BattingCardRatings.get_or_none(BattingCardRatings.id == ratings_id)
|
||||
if this_rating is None:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'BattingCardRating id {ratings_id} not found')
|
||||
|
||||
r_data = model_to_dict(this_rating)
|
||||
db.close()
|
||||
return r_data
|
||||
|
||||
|
||||
@router.get('')
|
||||
async def get_player_ratings(player_id: int, variant: list = Query(default=None), short_output: bool = False):
|
||||
all_cards = BattingCard.select().where(BattingCard.player_id == player_id).order_by(BattingCard.variant)
|
||||
if variant is not None:
|
||||
all_cards = all_cards.where(BattingCard.variant << variant)
|
||||
|
||||
all_ratings = BattingCardRatings.select().where(BattingCardRatings.battingcard << all_cards)
|
||||
|
||||
return_val = {'count': all_ratings.count(), 'ratings': [
|
||||
model_to_dict(x, recurse=not short_output) for x in all_ratings
|
||||
]}
|
||||
db.close()
|
||||
return return_val
|
||||
|
||||
|
||||
@router.put('')
|
||||
async def put_ratings(ratings: RatingsList, 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 card ratings.'
|
||||
)
|
||||
|
||||
new_ratings = [x.dict() for x in ratings.ratings]
|
||||
with db.atomic():
|
||||
for batch in chunked(new_ratings, 30):
|
||||
BattingCardRatings.insert_many(batch).on_conflict_replace().execute()
|
||||
|
||||
db.close()
|
||||
return f'Inserted {len(new_ratings)} batting ratings'
|
||||
|
||||
|
||||
@router.delete('/{ratings_id}')
|
||||
async def put_one_rating(
|
||||
ratings_id: int, this_rating: BattingCardRatingsModel, 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 card ratings.'
|
||||
)
|
||||
|
||||
this_rating = BattingCardRatings.get_or_none(BattingCardRatings.id == ratings_id)
|
||||
if this_rating is None:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'BattingCardRating id {ratings_id} not found')
|
||||
|
||||
count = this_rating.delete_instance()
|
||||
db.close()
|
||||
|
||||
if count == 1:
|
||||
return f'Rating {this_rating} has been deleted'
|
||||
else:
|
||||
raise HTTPException(status_code=500, detail=f'Rating {this_rating} could not be deleted')
|
||||
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Response, Query
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from typing import Literal, Optional, List
|
||||
import logging
|
||||
import pydantic
|
||||
from pandas import DataFrame
|
||||
|
||||
from ..db_engine import db, BattingCard, model_to_dict, fn, chunked
|
||||
from ..db_engine import db, BattingCard, model_to_dict, chunked, Player
|
||||
from ..dependencies import oauth2_scheme, valid_token, LOG_DATA
|
||||
|
||||
logging.basicConfig(
|
||||
@ -14,13 +13,14 @@ logging.basicConfig(
|
||||
)
|
||||
|
||||
router = APIRouter(
|
||||
prefix='/api/v2/battingcard',
|
||||
tags=['battingcard']
|
||||
prefix='/api/v2/battingcards',
|
||||
tags=['battingcards']
|
||||
)
|
||||
|
||||
|
||||
class BattingCardModel(pydantic.BaseModel):
|
||||
player_id: int
|
||||
variant: int = 0
|
||||
steal_low: int = 3
|
||||
steal_high: int = 20
|
||||
steal_auto: bool = False
|
||||
@ -29,7 +29,7 @@ class BattingCardModel(pydantic.BaseModel):
|
||||
hit_and_run: str = 'C'
|
||||
running: int = 10
|
||||
offense_col: int
|
||||
hand: Literal['R', 'L', 'S']
|
||||
hand: Literal['R', 'L', 'S'] = 'R'
|
||||
|
||||
|
||||
class BattingCardList(pydantic.BaseModel):
|
||||
@ -37,13 +37,17 @@ class BattingCardList(pydantic.BaseModel):
|
||||
|
||||
|
||||
@router.get('')
|
||||
async def get_batting_cards(player_id: list = Query(default=None), short_output: bool = False):
|
||||
async def get_batting_cards(
|
||||
player_id: list = Query(default=None), cardset_id: list = Query(default=None), short_output: bool = False):
|
||||
all_cards = BattingCard.select()
|
||||
if player_id is not None:
|
||||
all_cards = all_cards.where(BattingCard.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(BattingCard.player << all_players)
|
||||
|
||||
return_val = {'count': all_cards.count(), 'cards': [
|
||||
{model_to_dict(x, recurse=not short_output)} for x in all_cards
|
||||
model_to_dict(x, recurse=not short_output) for x in all_cards
|
||||
]}
|
||||
db.close()
|
||||
return return_val
|
||||
@ -68,7 +72,7 @@ async def get_player_cards(player_id: int, variant: list = Query(default=None),
|
||||
all_cards = all_cards.where(BattingCard.variant << variant)
|
||||
|
||||
return_val = {'count': all_cards.count(), 'cards': [
|
||||
{model_to_dict(x, recurse=not short_output) for x in all_cards}
|
||||
model_to_dict(x, recurse=not short_output) for x in all_cards
|
||||
]}
|
||||
db.close()
|
||||
return return_val
|
||||
@ -6,7 +6,7 @@ import pydantic
|
||||
from pandas import DataFrame
|
||||
|
||||
from ..db_engine import db, Team, model_to_dict, fn, Pack, Card, Player, Paperdex, Notification, PackType, \
|
||||
Rarity, Current, query_to_csv
|
||||
Rarity, Current, query_to_csv, complex_data_to_csv
|
||||
from ..dependencies import oauth2_scheme, valid_token, LOG_DATA, int_timestamp
|
||||
|
||||
logging.basicConfig(
|
||||
@ -116,22 +116,7 @@ async def get_teams(
|
||||
if limit is not None:
|
||||
all_teams = all_teams.limit(limit)
|
||||
|
||||
# if all_teams.count() == 0:
|
||||
# db.close()
|
||||
# raise HTTPException(status_code=404, detail=f'No teams found')
|
||||
|
||||
if csv:
|
||||
# data_list = [[
|
||||
# 'id', 'abbrev', 'sname', 'lname', 'gmid', 'gmname', 'wallet', 'gsheet', 'team_value',
|
||||
# 'collection_value', 'logo', 'color', 'season', 'ranking'
|
||||
# ]]
|
||||
# for line in all_teams:
|
||||
# data_list.append(
|
||||
# [
|
||||
# line.id, line.abbrev, line.sname, line.lname, line.gmid, line.gmname, line.wallet, line.gsheet,
|
||||
# line.team_value, line.collection_value, line.logo, f'\'{line.color}', line.season, line.ranking
|
||||
# ]
|
||||
# )
|
||||
return_val = query_to_csv(all_teams, exclude=[Team.career])
|
||||
db.close()
|
||||
return Response(content=return_val, media_type='text/csv')
|
||||
@ -153,23 +138,17 @@ async def get_one_team(team_id, csv: Optional[bool] = False):
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'No team found with id {team_id}')
|
||||
|
||||
p_query = Pack.select().where((Pack.team == this_team) & (Pack.open_time.is_null(True)))
|
||||
if csv:
|
||||
team_packs = Pack.select().where((Pack.team == this_team) & (Pack.open_time.is_null(True)))
|
||||
data_list = [
|
||||
['id', 'abbrev', 'sname', 'lname', 'gmid', 'gmname', 'wallet', 'ranking', 'gsheet', 'sealed_packs',
|
||||
'collection_value', 'logo', 'color', 'season'],
|
||||
[this_team.id, this_team.abbrev, this_team.sname, this_team.lname, this_team.gmid, this_team.gmname,
|
||||
this_team.wallet, this_team.ranking, this_team.gsheet, team_packs.count(), this_team.collection_value,
|
||||
this_team.logo, this_team.color, this_team.season]
|
||||
]
|
||||
return_val = DataFrame(data_list).to_csv(header=False, index=False)
|
||||
|
||||
db.close()
|
||||
return Response(content=return_val, media_type='text/csv')
|
||||
data = model_to_dict(this_team)
|
||||
data['sealed_packs'] = p_query.count()
|
||||
return_val = complex_data_to_csv([data])
|
||||
else:
|
||||
return_val = model_to_dict(this_team)
|
||||
db.close()
|
||||
return return_val
|
||||
return_val['sealed_packs'] = [model_to_dict(x) for x in p_query]
|
||||
|
||||
db.close()
|
||||
return return_val
|
||||
|
||||
|
||||
@router.get('/{team_id}/buy/players')
|
||||
|
||||
Loading…
Reference in New Issue
Block a user