Add divisions, update standings
This commit is contained in:
parent
474448556e
commit
505d0a1a8a
205
app/db_engine.py
205
app/db_engine.py
@ -69,7 +69,7 @@ def games_back(leader, chaser):
|
|||||||
|
|
||||||
|
|
||||||
def e_number(leader, chaser):
|
def e_number(leader, chaser):
|
||||||
e_num = 89 - leader.wins - chaser.losses
|
e_num = 73 - leader.wins - chaser.losses
|
||||||
return e_num if e_num > 0 else 0
|
return e_num if e_num > 0 else 0
|
||||||
|
|
||||||
|
|
||||||
@ -1219,9 +1219,11 @@ class Standings(BaseModel):
|
|||||||
all_teams = Team.select_season(season).where(Team.division)
|
all_teams = Team.select_season(season).where(Team.division)
|
||||||
if full_wipe:
|
if full_wipe:
|
||||||
# Wipe existing data
|
# Wipe existing data
|
||||||
delete_lines = Standings.select_season(season)
|
s_teams = Team.select().where(Team.season == season)
|
||||||
for line in delete_lines:
|
Standings.delete().where(Standings.team << s_teams).execute()
|
||||||
line.delete_instance()
|
# delete_lines = Standings.select_season(season)
|
||||||
|
# for line in delete_lines:
|
||||||
|
# line.delete_instance()
|
||||||
|
|
||||||
# Recreate current season Standings objects
|
# Recreate current season Standings objects
|
||||||
create_teams = [Standings(team=team) for team in all_teams]
|
create_teams = [Standings(team=team) for team in all_teams]
|
||||||
@ -1229,7 +1231,9 @@ class Standings(BaseModel):
|
|||||||
Standings.bulk_create(create_teams)
|
Standings.bulk_create(create_teams)
|
||||||
|
|
||||||
# Iterate through each individual result
|
# Iterate through each individual result
|
||||||
for game in Result.select_season(season).where(Result.week <= 22):
|
# for game in Result.select_season(season).where(Result.week <= 22):
|
||||||
|
for game in StratGame.select().where(
|
||||||
|
(StratGame.season == season) & (StratGame.week <= 18) & (StratGame.game_num.is_null(False))):
|
||||||
# tally win and loss for each standings object
|
# tally win and loss for each standings object
|
||||||
game.update_standings()
|
game.update_standings()
|
||||||
|
|
||||||
@ -1244,11 +1248,11 @@ class Standings(BaseModel):
|
|||||||
# Pull each league (filter by not null wc_gb) and sort by win pct
|
# Pull each league (filter by not null wc_gb) and sort by win pct
|
||||||
|
|
||||||
# # For one league:
|
# # For one league:
|
||||||
# Division.sort_wildcard(season, 'SBa')
|
Division.sort_wildcard(season, 'SBa')
|
||||||
|
|
||||||
# For two leagues
|
# For two leagues
|
||||||
Division.sort_wildcard(season, 'AL')
|
# Division.sort_wildcard(season, 'AL')
|
||||||
Division.sort_wildcard(season, 'NL')
|
# Division.sort_wildcard(season, 'NL')
|
||||||
|
|
||||||
|
|
||||||
class BattingCareer(BaseModel):
|
class BattingCareer(BaseModel):
|
||||||
@ -1849,6 +1853,190 @@ class StratGame(BaseModel):
|
|||||||
away_manager = ForeignKeyField(Manager, null=True)
|
away_manager = ForeignKeyField(Manager, null=True)
|
||||||
home_manager = ForeignKeyField(Manager, null=True)
|
home_manager = ForeignKeyField(Manager, null=True)
|
||||||
|
|
||||||
|
def update_standings(self):
|
||||||
|
away_stan = Standings.get_season(self.away_team)
|
||||||
|
home_stan = Standings.get_season(self.home_team)
|
||||||
|
away_div = Division.get_by_id(self.away_team.division.id)
|
||||||
|
home_div = Division.get_by_id(self.home_team.division.id)
|
||||||
|
|
||||||
|
if self.home_score > self.away_score:
|
||||||
|
# - generic w/l & home/away w/l
|
||||||
|
home_stan.wins += 1
|
||||||
|
home_stan.home_wins += 1
|
||||||
|
away_stan.losses += 1
|
||||||
|
away_stan.away_losses += 1
|
||||||
|
|
||||||
|
# - update streak wl and num
|
||||||
|
if home_stan.streak_wl == 'w':
|
||||||
|
home_stan.streak_num += 1
|
||||||
|
else:
|
||||||
|
home_stan.streak_wl = 'w'
|
||||||
|
home_stan.streak_num = 1
|
||||||
|
|
||||||
|
if away_stan.streak_wl == 'l':
|
||||||
|
away_stan.streak_num += 1
|
||||||
|
else:
|
||||||
|
away_stan.streak_wl = 'l'
|
||||||
|
away_stan.streak_num = 1
|
||||||
|
|
||||||
|
# - if 1-run, tally accordingly
|
||||||
|
if self.home_score == self.away_score + 1:
|
||||||
|
home_stan.one_run_wins += 1
|
||||||
|
away_stan.one_run_losses += 1
|
||||||
|
|
||||||
|
# Used for one league with 3 divisions
|
||||||
|
# - update record v division
|
||||||
|
# if away_div.division_abbrev == 'BE':
|
||||||
|
# home_stan.div1_wins += 1
|
||||||
|
# elif away_div.division_abbrev == 'DO':
|
||||||
|
# home_stan.div2_wins += 1
|
||||||
|
# else:
|
||||||
|
# home_stan.div3_wins += 1
|
||||||
|
#
|
||||||
|
# if home_div.division_abbrev == 'BE':
|
||||||
|
# away_stan.div1_losses += 1
|
||||||
|
# elif home_div.division_abbrev == 'DO':
|
||||||
|
# away_stan.div2_losses += 1
|
||||||
|
# else:
|
||||||
|
# away_stan.div3_losses += 1
|
||||||
|
|
||||||
|
# Used for one league with 3 divisions
|
||||||
|
# - update record v division
|
||||||
|
if away_div.division_abbrev == 'FD':
|
||||||
|
home_stan.div1_wins += 1
|
||||||
|
elif away_div.division_abbrev == 'NLW':
|
||||||
|
home_stan.div2_wins += 1
|
||||||
|
elif away_div.division_abbrev == 'IWGP':
|
||||||
|
home_stan.div3_wins += 1
|
||||||
|
else:
|
||||||
|
home_stan.div4_wins += 1
|
||||||
|
|
||||||
|
if home_div.division_abbrev == 'FD':
|
||||||
|
away_stan.div1_losses += 1
|
||||||
|
elif home_div.division_abbrev == 'NLW':
|
||||||
|
away_stan.div2_losses += 1
|
||||||
|
elif away_div.division_abbrev == 'IWGP':
|
||||||
|
away_stan.div3_losses += 1
|
||||||
|
else:
|
||||||
|
away_stan.div4_losses += 1
|
||||||
|
|
||||||
|
# Used for two league plus divisions
|
||||||
|
# if away_div.league_abbrev == 'AL':
|
||||||
|
# if away_div.division_abbrev == 'E':
|
||||||
|
# home_stan.div1_wins += 1
|
||||||
|
# else:
|
||||||
|
# home_stan.div2_wins += 1
|
||||||
|
# else:
|
||||||
|
# if away_div.division_abbrev == 'E':
|
||||||
|
# home_stan.div3_wins += 1
|
||||||
|
# else:
|
||||||
|
# home_stan.div4_wins += 1
|
||||||
|
#
|
||||||
|
# if home_div.league_abbrev == 'AL':
|
||||||
|
# if home_div.division_abbrev == 'E':
|
||||||
|
# away_stan.div1_losses += 1
|
||||||
|
# else:
|
||||||
|
# away_stan.div2_losses += 1
|
||||||
|
# else:
|
||||||
|
# if home_div.division_abbrev == 'E':
|
||||||
|
# away_stan.div3_losses += 1
|
||||||
|
# else:
|
||||||
|
# away_stan.div4_losses += 1
|
||||||
|
|
||||||
|
# - adjust run_diff
|
||||||
|
home_stan.run_diff += self.home_score - self.away_score
|
||||||
|
away_stan.run_diff -= self.home_score - self.away_score
|
||||||
|
else:
|
||||||
|
# - generic w/l & home/away w/l
|
||||||
|
home_stan.losses += 1
|
||||||
|
home_stan.home_losses += 1
|
||||||
|
away_stan.wins += 1
|
||||||
|
away_stan.away_wins += 1
|
||||||
|
|
||||||
|
# - update streak wl and num
|
||||||
|
if home_stan.streak_wl == 'l':
|
||||||
|
home_stan.streak_num += 1
|
||||||
|
else:
|
||||||
|
home_stan.streak_wl = 'l'
|
||||||
|
home_stan.streak_num = 1
|
||||||
|
|
||||||
|
if away_stan.streak_wl == 'w':
|
||||||
|
away_stan.streak_num += 1
|
||||||
|
else:
|
||||||
|
away_stan.streak_wl = 'w'
|
||||||
|
away_stan.streak_num = 1
|
||||||
|
|
||||||
|
# - if 1-run, tally accordingly
|
||||||
|
if self.away_score == self.home_score + 1:
|
||||||
|
home_stan.one_run_losses += 1
|
||||||
|
away_stan.one_run_wins += 1
|
||||||
|
|
||||||
|
# Used for one league with 3 divisions
|
||||||
|
# - update record v division
|
||||||
|
# if away_div.division_abbrev == 'BE':
|
||||||
|
# home_stan.div1_losses += 1
|
||||||
|
# elif away_div.division_abbrev == 'DO':
|
||||||
|
# home_stan.div2_losses += 1
|
||||||
|
# else:
|
||||||
|
# home_stan.div3_losses += 1
|
||||||
|
#
|
||||||
|
# if home_div.division_abbrev == 'BE':
|
||||||
|
# away_stan.div1_wins += 1
|
||||||
|
# elif home_div.division_abbrev == 'DO':
|
||||||
|
# away_stan.div2_wins += 1
|
||||||
|
# else:
|
||||||
|
# away_stan.div3_wins += 1
|
||||||
|
|
||||||
|
# Used for one league with 4 divisions
|
||||||
|
# - update record v division
|
||||||
|
if away_div.division_abbrev == 'FD':
|
||||||
|
home_stan.div1_losses += 1
|
||||||
|
elif away_div.division_abbrev == 'NLW':
|
||||||
|
home_stan.div2_losses += 1
|
||||||
|
elif away_div.division_abbrev == 'IWGP':
|
||||||
|
home_stan.div3_losses += 1
|
||||||
|
else:
|
||||||
|
home_stan.div4_losses += 1
|
||||||
|
|
||||||
|
if home_div.division_abbrev == 'FD':
|
||||||
|
away_stan.div1_wins += 1
|
||||||
|
elif home_div.division_abbrev == 'NLW':
|
||||||
|
away_stan.div2_wins += 1
|
||||||
|
elif away_div.division_abbrev == 'IWGP':
|
||||||
|
away_stan.div3_wins += 1
|
||||||
|
else:
|
||||||
|
away_stan.div4_wins += 1
|
||||||
|
|
||||||
|
# Used for two league plus divisions
|
||||||
|
# if away_div.league_abbrev == 'AL':
|
||||||
|
# if away_div.division_abbrev == 'E':
|
||||||
|
# home_stan.div1_losses += 1
|
||||||
|
# else:
|
||||||
|
# home_stan.div2_losses += 1
|
||||||
|
# else:
|
||||||
|
# if away_div.division_abbrev == 'E':
|
||||||
|
# home_stan.div3_losses += 1
|
||||||
|
# else:
|
||||||
|
# home_stan.div4_losses += 1
|
||||||
|
#
|
||||||
|
# if home_div.league_abbrev == 'AL':
|
||||||
|
# if home_div.division_abbrev == 'E':
|
||||||
|
# away_stan.div1_wins += 1
|
||||||
|
# else:
|
||||||
|
# away_stan.div2_wins += 1
|
||||||
|
# else:
|
||||||
|
# if home_div.division_abbrev == 'E':
|
||||||
|
# away_stan.div3_wins += 1
|
||||||
|
# else:
|
||||||
|
# away_stan.div4_wins += 1
|
||||||
|
|
||||||
|
# - adjust run_diff
|
||||||
|
home_stan.run_diff -= self.away_score - self.home_score
|
||||||
|
away_stan.run_diff += self.away_score - self.home_score
|
||||||
|
|
||||||
|
home_stan.save()
|
||||||
|
away_stan.save()
|
||||||
|
|
||||||
|
|
||||||
class StratPlay(BaseModel):
|
class StratPlay(BaseModel):
|
||||||
game = ForeignKeyField(StratGame)
|
game = ForeignKeyField(StratGame)
|
||||||
@ -1877,6 +2065,7 @@ class StratPlay(BaseModel):
|
|||||||
|
|
||||||
pa = IntegerField(default=0)
|
pa = IntegerField(default=0)
|
||||||
ab = IntegerField(default=0)
|
ab = IntegerField(default=0)
|
||||||
|
e_run = IntegerField(default=0)
|
||||||
run = IntegerField(default=0)
|
run = IntegerField(default=0)
|
||||||
hit = IntegerField(default=0)
|
hit = IntegerField(default=0)
|
||||||
rbi = IntegerField(default=0)
|
rbi = IntegerField(default=0)
|
||||||
|
|||||||
@ -8,7 +8,7 @@ from fastapi import Depends, FastAPI, Request
|
|||||||
|
|
||||||
from .routers_v3 import current, players, results, schedules, standings, teams, transactions, battingstats, \
|
from .routers_v3 import current, players, results, schedules, standings, teams, transactions, battingstats, \
|
||||||
pitchingstats, fieldingstats, draftpicks, draftlist, managers, awards, draftdata, keepers, stratgame, stratplay, \
|
pitchingstats, fieldingstats, draftpicks, draftlist, managers, awards, draftdata, keepers, stratgame, stratplay, \
|
||||||
injuries, decisions
|
injuries, decisions, divisions
|
||||||
|
|
||||||
date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
|
date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
|
||||||
log_level = logging.INFO if os.environ.get('LOG_LEVEL') == 'INFO' else 'WARN'
|
log_level = logging.INFO if os.environ.get('LOG_LEVEL') == 'INFO' else 'WARN'
|
||||||
@ -46,6 +46,7 @@ app.include_router(stratgame.router)
|
|||||||
app.include_router(stratplay.router)
|
app.include_router(stratplay.router)
|
||||||
app.include_router(injuries.router)
|
app.include_router(injuries.router)
|
||||||
app.include_router(decisions.router)
|
app.include_router(decisions.router)
|
||||||
|
app.include_router(divisions.router)
|
||||||
|
|
||||||
logging.info(f'Loaded all routers.')
|
logging.info(f'Loaded all routers.')
|
||||||
|
|
||||||
|
|||||||
@ -44,12 +44,13 @@ class DecisionList(pydantic.BaseModel):
|
|||||||
@router.get('')
|
@router.get('')
|
||||||
async def get_decisions(
|
async def get_decisions(
|
||||||
season: list = Query(default=None), week: list = Query(default=None), game_num: list = Query(default=None),
|
season: list = Query(default=None), week: list = Query(default=None), game_num: list = Query(default=None),
|
||||||
season_type: Literal['regular', 'post', 'all', None] = None, team_id: list = Query(default=None),
|
s_type: Literal['regular', 'post', 'all', None] = None, team_id: list = Query(default=None),
|
||||||
week_start: Optional[int] = None, week_end: Optional[int] = None, win: Optional[int] = None,
|
week_start: Optional[int] = None, week_end: Optional[int] = None, win: Optional[int] = None,
|
||||||
loss: Optional[int] = None, hold: Optional[int] = None, save: Optional[int] = None,
|
loss: Optional[int] = None, hold: Optional[int] = None, save: Optional[int] = None,
|
||||||
b_save: Optional[int] = None, irunners: list = Query(default=None), irunners_scored: list = Query(default=None),
|
b_save: Optional[int] = None, irunners: list = Query(default=None), irunners_scored: list = Query(default=None),
|
||||||
game_id: list = Query(default=None), short_output: Optional[bool] = False):
|
game_id: list = Query(default=None), player_id: list = Query(default=None),
|
||||||
all_dec = Decision.select()
|
limit: Optional[int] = None, short_output: Optional[bool] = False):
|
||||||
|
all_dec = Decision.select().order_by(-Decision.season, -Decision.week, -Decision.game_num)
|
||||||
|
|
||||||
if season is not None:
|
if season is not None:
|
||||||
all_dec = all_dec.where(Decision.season << season)
|
all_dec = all_dec.where(Decision.season << season)
|
||||||
@ -59,12 +60,17 @@ async def get_decisions(
|
|||||||
all_dec = all_dec.where(Decision.game_num << game_num)
|
all_dec = all_dec.where(Decision.game_num << game_num)
|
||||||
if game_id is not None:
|
if game_id is not None:
|
||||||
all_dec = all_dec.where(Decision.game_id << game_id)
|
all_dec = all_dec.where(Decision.game_id << game_id)
|
||||||
if season_type is not None:
|
if player_id is not None:
|
||||||
all_games = StratGame.select().where(StratGame.season_type == season_type)
|
all_dec = all_dec.where(Decision.pitcher << player_id)
|
||||||
all_dec = all_dec.where(Decision.game << all_games)
|
if team_id is not None:
|
||||||
if season_type is not None:
|
|
||||||
all_players = Player.select().where(Player.team_id << team_id)
|
all_players = Player.select().where(Player.team_id << team_id)
|
||||||
all_dec = all_dec.where(Decision.pitcher << all_players)
|
all_dec = all_dec.where(Decision.pitcher << all_players)
|
||||||
|
if s_type is not None:
|
||||||
|
all_games = StratGame.select().where(StratGame.season_type == s_type)
|
||||||
|
all_dec = all_dec.where(Decision.game << all_games)
|
||||||
|
# if team_id is not None:
|
||||||
|
# all_players = Player.select().where(Player.team_id << team_id)
|
||||||
|
# all_dec = all_dec.where(Decision.pitcher << all_players)
|
||||||
if week_start is not None:
|
if week_start is not None:
|
||||||
all_dec = all_dec.where(Decision.week >= week_start)
|
all_dec = all_dec.where(Decision.week >= week_start)
|
||||||
if week_end is not None:
|
if week_end is not None:
|
||||||
@ -84,6 +90,11 @@ async def get_decisions(
|
|||||||
if irunners_scored is not None:
|
if irunners_scored is not None:
|
||||||
all_dec = all_dec.where(Decision.irunners_scored << irunners_scored)
|
all_dec = all_dec.where(Decision.irunners_scored << irunners_scored)
|
||||||
|
|
||||||
|
if limit is not None:
|
||||||
|
if limit < 1:
|
||||||
|
limit = 1
|
||||||
|
all_dec = all_dec.limit(limit)
|
||||||
|
|
||||||
return_dec = {
|
return_dec = {
|
||||||
'count': all_dec.count(),
|
'count': all_dec.count(),
|
||||||
'decisions': [model_to_dict(x, recurse=not short_output) for x in all_dec]
|
'decisions': [model_to_dict(x, recurse=not short_output) for x in all_dec]
|
||||||
|
|||||||
131
app/routers_v3/divisions.py
Normal file
131
app/routers_v3/divisions.py
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
from fastapi import APIRouter, Depends, HTTPException, Query, Response
|
||||||
|
from typing import List, Optional
|
||||||
|
import logging
|
||||||
|
import pydantic
|
||||||
|
|
||||||
|
from ..db_engine import db, Division, Team, model_to_dict, chunked, fn
|
||||||
|
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/v3/divisions',
|
||||||
|
tags=['divisions']
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DivisionModel(pydantic.BaseModel):
|
||||||
|
division_name: str
|
||||||
|
division_abbrev: str
|
||||||
|
league_name: Optional[str]
|
||||||
|
league_abbrev: Optional[str]
|
||||||
|
season: int = 0
|
||||||
|
|
||||||
|
|
||||||
|
@router.get('')
|
||||||
|
async def get_divisions(
|
||||||
|
season: int, div_name: Optional[str] = None, div_abbrev: Optional[str] = None, lg_name: Optional[str] = None,
|
||||||
|
lg_abbrev: Optional[str] = None):
|
||||||
|
all_divisions = Division.select().where(Division.season == season)
|
||||||
|
|
||||||
|
if div_name is not None:
|
||||||
|
all_divisions = all_divisions.where(Division.division_name == div_name)
|
||||||
|
if div_abbrev is not None:
|
||||||
|
all_divisions = all_divisions.where(Division.division_abbrev == div_abbrev)
|
||||||
|
if lg_name is not None:
|
||||||
|
all_divisions = all_divisions.where(Division.league_name == lg_name)
|
||||||
|
if lg_abbrev is not None:
|
||||||
|
all_divisions = all_divisions.where(Division.league_abbrev == lg_abbrev)
|
||||||
|
|
||||||
|
return_div = {
|
||||||
|
'count': all_divisions.count(),
|
||||||
|
'divisions': [model_to_dict(x) for x in all_divisions]
|
||||||
|
}
|
||||||
|
db.close()
|
||||||
|
return return_div
|
||||||
|
|
||||||
|
|
||||||
|
@router.get('/{division_id}')
|
||||||
|
async def get_one_division(division_id: int):
|
||||||
|
this_div = Division.get_or_none(Division.id == division_id)
|
||||||
|
if this_div is None:
|
||||||
|
db.close()
|
||||||
|
raise HTTPException(status_code=404, detail=f'Division ID {division_id} not found')
|
||||||
|
|
||||||
|
r_div = model_to_dict(this_div)
|
||||||
|
db.close()
|
||||||
|
return r_div
|
||||||
|
|
||||||
|
|
||||||
|
@router.patch('/{division_id}')
|
||||||
|
async def patch_division(
|
||||||
|
division_id: int, div_name: Optional[str] = None, div_abbrev: Optional[str] = None,
|
||||||
|
lg_name: Optional[str] = None, lg_abbrev: Optional[str] = None, token: str = Depends(oauth2_scheme)):
|
||||||
|
if not valid_token(token):
|
||||||
|
logging.warning(f'patch_division - Bad Token: {token}')
|
||||||
|
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||||
|
|
||||||
|
this_div = Division.get_or_none(Division.id == division_id)
|
||||||
|
if this_div is None:
|
||||||
|
db.close()
|
||||||
|
raise HTTPException(status_code=404, detail=f'Division ID {division_id} not found')
|
||||||
|
|
||||||
|
if div_name is not None:
|
||||||
|
this_div.division_name = div_name
|
||||||
|
if div_abbrev is not None:
|
||||||
|
this_div.division_abbrev = div_abbrev
|
||||||
|
if lg_name is not None:
|
||||||
|
this_div.league_name = lg_name
|
||||||
|
if lg_abbrev is not None:
|
||||||
|
this_div.league_abbrev = lg_abbrev
|
||||||
|
|
||||||
|
if this_div.save() == 1:
|
||||||
|
r_division = model_to_dict(this_div)
|
||||||
|
db.close()
|
||||||
|
return r_division
|
||||||
|
else:
|
||||||
|
db.close()
|
||||||
|
raise HTTPException(status_code=500, detail=f'Unable to patch division {division_id}')
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('')
|
||||||
|
async def post_division(new_division: DivisionModel, token: str = Depends(oauth2_scheme)):
|
||||||
|
if not valid_token(token):
|
||||||
|
logging.warning(f'post_division - Bad Token: {token}')
|
||||||
|
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||||
|
|
||||||
|
this_division = Division(**new_division.dict())
|
||||||
|
|
||||||
|
if this_division.save() == 1:
|
||||||
|
r_division = model_to_dict(this_division)
|
||||||
|
db.close()
|
||||||
|
return r_division
|
||||||
|
else:
|
||||||
|
db.close()
|
||||||
|
raise HTTPException(status_code=500, detail=f'Unable to post division')
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete('/{division_id}')
|
||||||
|
async def delete_division(division_id: int, token: str = Depends(oauth2_scheme)):
|
||||||
|
if not valid_token(token):
|
||||||
|
logging.warning(f'delete_division - Bad Token: {token}')
|
||||||
|
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||||
|
|
||||||
|
this_div = Division.get_or_none(Division.id == division_id)
|
||||||
|
if this_div is None:
|
||||||
|
db.close()
|
||||||
|
raise HTTPException(status_code=404, detail=f'Division ID {division_id} not found')
|
||||||
|
|
||||||
|
count = this_div.delete_instance()
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
if count == 1:
|
||||||
|
return f'Division {division_id} has been deleted'
|
||||||
|
else:
|
||||||
|
raise HTTPException(status_code=500, detail=f'Division {division_id} could not be deleted')
|
||||||
|
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ router = APIRouter(
|
|||||||
|
|
||||||
@router.get('')
|
@router.get('')
|
||||||
async def get_standings(
|
async def get_standings(
|
||||||
season: int, team_abbrev: list = Query(default=None), league_abbrev: Optional[str] = None,
|
season: int, team_id: list = Query(default=None), league_abbrev: Optional[str] = None,
|
||||||
division_abbrev: Optional[str] = None, short_output: Optional[bool] = False):
|
division_abbrev: Optional[str] = None, short_output: Optional[bool] = False):
|
||||||
standings = Standings.select_season(season)
|
standings = Standings.select_season(season)
|
||||||
|
|
||||||
@ -28,8 +28,8 @@ async def get_standings(
|
|||||||
# db.close()
|
# db.close()
|
||||||
# raise HTTPException(status_code=404, detail=f'No output for season {season}')
|
# raise HTTPException(status_code=404, detail=f'No output for season {season}')
|
||||||
|
|
||||||
if team_abbrev is not None:
|
if team_id is not None:
|
||||||
t_query = Team.select().where(fn.Lower(Team.abbrev) << [x.lower() for x in team_abbrev])
|
t_query = Team.select().where(Team.id << team_id)
|
||||||
standings = standings.where(Standings.team << t_query)
|
standings = standings.where(Standings.team << t_query)
|
||||||
|
|
||||||
if league_abbrev is not None:
|
if league_abbrev is not None:
|
||||||
|
|||||||
@ -44,7 +44,7 @@ async def get_games(
|
|||||||
team1_id: list = Query(default=None), team2_id: list = Query(default=None), played: Optional[bool] = None,
|
team1_id: list = Query(default=None), team2_id: list = Query(default=None), played: Optional[bool] = None,
|
||||||
away_manager_id: list = Query(default=None), home_manager_id: list = Query(default=None),
|
away_manager_id: list = Query(default=None), home_manager_id: list = Query(default=None),
|
||||||
manager1_id: list = Query(default=None), manager2_id: list = Query(default=None),
|
manager1_id: list = Query(default=None), manager2_id: list = Query(default=None),
|
||||||
short_output: Optional[bool] = False):
|
division_id: Optional[int] = None, short_output: Optional[bool] = False):
|
||||||
all_games = StratGame.select()
|
all_games = StratGame.select()
|
||||||
|
|
||||||
if season is not None:
|
if season is not None:
|
||||||
@ -71,6 +71,11 @@ async def get_games(
|
|||||||
all_games = all_games.where(
|
all_games = all_games.where(
|
||||||
(StratGame.away_team_id << team2_id) | (StratGame.home_team_id << team2_id)
|
(StratGame.away_team_id << team2_id) | (StratGame.home_team_id << team2_id)
|
||||||
)
|
)
|
||||||
|
if division_id is not None:
|
||||||
|
all_teams = Team.select().where(Team.division == division_id)
|
||||||
|
all_games = all_games.where(
|
||||||
|
(StratGame.away_team << all_teams) | (StratGame.home_team << all_teams)
|
||||||
|
)
|
||||||
if away_manager_id is not None:
|
if away_manager_id is not None:
|
||||||
all_games = all_games.where(StratGame.away_manager_id << away_manager_id)
|
all_games = all_games.where(StratGame.away_manager_id << away_manager_id)
|
||||||
if home_manager_id is not None:
|
if home_manager_id is not None:
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import copy
|
|||||||
import logging
|
import logging
|
||||||
from pydantic import BaseModel, validator
|
from pydantic import BaseModel, validator
|
||||||
|
|
||||||
from ..db_engine import db, StratPlay, StratGame, Team, Player, model_to_dict, chunked, fn
|
from ..db_engine import db, StratPlay, StratGame, Team, Player, Decision, model_to_dict, chunked, fn, SQL
|
||||||
from ..dependencies import oauth2_scheme, valid_token, LOG_DATA
|
from ..dependencies import oauth2_scheme, valid_token, LOG_DATA
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
@ -47,6 +47,7 @@ class PlayModel(BaseModel):
|
|||||||
|
|
||||||
pa: int = 0
|
pa: int = 0
|
||||||
ab: int = 0
|
ab: int = 0
|
||||||
|
e_run: int = 0
|
||||||
run: int = 0
|
run: int = 0
|
||||||
hit: int = 0
|
hit: int = 0
|
||||||
rbi: int = 0
|
rbi: int = 0
|
||||||
@ -124,6 +125,7 @@ async def get_plays(
|
|||||||
offense_team_id: list = Query(default=None), defense_team_id: list = Query(default=None),
|
offense_team_id: list = Query(default=None), defense_team_id: list = Query(default=None),
|
||||||
double: Optional[int] = None, triple: Optional[int] = None, homerun: Optional[int] = None,
|
double: Optional[int] = None, triple: Optional[int] = None, homerun: Optional[int] = None,
|
||||||
sb: Optional[int] = None, cs: Optional[int] = None, manager_id: list = Query(default=None),
|
sb: Optional[int] = None, cs: Optional[int] = None, manager_id: list = Query(default=None),
|
||||||
|
run: Optional[int] = None, e_run: Optional[int] = None, rbi: list = Query(default=None),
|
||||||
outs: list = Query(default=None), wild_pitch: Optional[int] = None, is_final_out: Optional[bool] = None,
|
outs: list = Query(default=None), wild_pitch: Optional[int] = None, is_final_out: Optional[bool] = None,
|
||||||
is_go_ahead: Optional[bool] = None, is_tied: Optional[bool] = None, is_new_inning: Optional[bool] = None,
|
is_go_ahead: Optional[bool] = None, is_tied: Optional[bool] = None, is_new_inning: Optional[bool] = None,
|
||||||
short_output: Optional[bool] = False, sort: Optional[str] = None, limit: Optional[int] = 200):
|
short_output: Optional[bool] = False, sort: Optional[str] = None, limit: Optional[int] = 200):
|
||||||
@ -174,6 +176,12 @@ async def get_plays(
|
|||||||
all_plays = all_plays.where(StratPlay.cs == cs)
|
all_plays = all_plays.where(StratPlay.cs == cs)
|
||||||
if wild_pitch is not None:
|
if wild_pitch is not None:
|
||||||
all_plays = all_plays.where(StratPlay.wild_pitch == wild_pitch)
|
all_plays = all_plays.where(StratPlay.wild_pitch == wild_pitch)
|
||||||
|
if run is not None:
|
||||||
|
all_plays = all_plays.where(StratPlay.run == run)
|
||||||
|
if e_run is not None:
|
||||||
|
all_plays = all_plays.where(StratPlay.e_run == e_run)
|
||||||
|
if rbi is not None:
|
||||||
|
all_plays = all_plays.where(StratPlay.rbi << rbi)
|
||||||
if outs is not None:
|
if outs is not None:
|
||||||
all_plays = all_plays.where(StratPlay.outs << outs)
|
all_plays = all_plays.where(StratPlay.outs << outs)
|
||||||
if manager_id is not None:
|
if manager_id is not None:
|
||||||
@ -211,14 +219,17 @@ async def get_plays(
|
|||||||
|
|
||||||
|
|
||||||
@router.get('/batting')
|
@router.get('/batting')
|
||||||
async def get_totalplays(
|
async def get_batting_totals(
|
||||||
season: list = Query(default=None), s_type: Literal['regular', 'post', 'total', None] = None,
|
season: list = Query(default=None), week: list = Query(default=None),
|
||||||
|
s_type: Literal['regular', 'post', 'total', None] = None, position: list = Query(default=None),
|
||||||
player_id: list = Query(default=None), group_by: Literal['team', 'player', 'playerteam'] = 'player',
|
player_id: list = Query(default=None), group_by: Literal['team', 'player', 'playerteam'] = 'player',
|
||||||
min_pa: Optional[int] = 1, team_id: list = Query(default=None), manager_id: list = Query(default=None),
|
min_pa: Optional[int] = 1, team_id: list = Query(default=None), manager_id: list = Query(default=None),
|
||||||
sort: Optional[str] = None, limit: Optional[int] = None, short_output: Optional[bool] = False):
|
sort: Optional[str] = None, limit: Optional[int] = None, short_output: Optional[bool] = False):
|
||||||
season_games = StratGame.select()
|
season_games = StratGame.select()
|
||||||
if season is not None:
|
if season is not None:
|
||||||
season_games = season_games.where(StratGame.season << season)
|
season_games = season_games.where(StratGame.season << season)
|
||||||
|
if week is not None:
|
||||||
|
season_games = season_games.where(StratGame.week << week)
|
||||||
if manager_id is not None:
|
if manager_id is not None:
|
||||||
season_games = season_games.where(
|
season_games = season_games.where(
|
||||||
(StratGame.away_manager_id << manager_id) | (StratGame.home_manager_id << manager_id)
|
(StratGame.away_manager_id << manager_id) | (StratGame.home_manager_id << manager_id)
|
||||||
@ -266,6 +277,8 @@ async def get_totalplays(
|
|||||||
bat_plays = bat_plays.where(StratPlay.batter_team << all_teams)
|
bat_plays = bat_plays.where(StratPlay.batter_team << all_teams)
|
||||||
run_plays = run_plays.where(StratPlay.runner_team << all_teams)
|
run_plays = run_plays.where(StratPlay.runner_team << all_teams)
|
||||||
def_plays = def_plays.where(StratPlay.defender_team << all_teams)
|
def_plays = def_plays.where(StratPlay.defender_team << all_teams)
|
||||||
|
if position is not None:
|
||||||
|
bat_plays = bat_plays.where(StratPlay.batter_pos << position)
|
||||||
|
|
||||||
if group_by is not None:
|
if group_by is not None:
|
||||||
if group_by == 'player':
|
if group_by == 'player':
|
||||||
@ -289,10 +302,14 @@ async def get_totalplays(
|
|||||||
bat_plays = bat_plays.order_by(StratPlay.batter_team)
|
bat_plays = bat_plays.order_by(StratPlay.batter_team)
|
||||||
run_plays = run_plays.order_by(StratPlay.runner_team)
|
run_plays = run_plays.order_by(StratPlay.runner_team)
|
||||||
def_plays = def_plays.order_by(StratPlay.defender_team)
|
def_plays = def_plays.order_by(StratPlay.defender_team)
|
||||||
# elif sort == 'wpa-desc':
|
elif sort == 'wpa-desc':
|
||||||
# bat_plays = bat_plays.order_by(-StratPlay.sum_wpa)
|
bat_plays = bat_plays.order_by(SQL('sum_wpa').desc())
|
||||||
# elif sort == 'wpa-asc':
|
elif sort == 'wpa-asc':
|
||||||
# bat_plays = bat_plays.order_by(StratPlay.sum_wpa)
|
bat_plays = bat_plays.order_by(SQL('sum_wpa').asc())
|
||||||
|
elif sort == 'pa-desc':
|
||||||
|
bat_plays = bat_plays.order_by(SQL('sum_pa').desc())
|
||||||
|
elif sort == 'pa-asc':
|
||||||
|
bat_plays = bat_plays.order_by(SQL('sum_pa').asc())
|
||||||
if limit is not None:
|
if limit is not None:
|
||||||
if limit < 1:
|
if limit < 1:
|
||||||
limit = 1
|
limit = 1
|
||||||
@ -300,7 +317,6 @@ async def get_totalplays(
|
|||||||
|
|
||||||
logging.info(f'bat_plays query: {bat_plays}')
|
logging.info(f'bat_plays query: {bat_plays}')
|
||||||
logging.info(f'run_plays query: {run_plays}')
|
logging.info(f'run_plays query: {run_plays}')
|
||||||
logging.info(f'def_plays query: {def_plays}')
|
|
||||||
|
|
||||||
return_stats = {
|
return_stats = {
|
||||||
'count': bat_plays.count(),
|
'count': bat_plays.count(),
|
||||||
@ -318,6 +334,7 @@ async def get_totalplays(
|
|||||||
sum_cs = 0
|
sum_cs = 0
|
||||||
sum_wpa = 0
|
sum_wpa = 0
|
||||||
|
|
||||||
|
tot_ab = x.sum_ab if x.sum_ab > 0 else 1
|
||||||
return_stats['stats'].append({
|
return_stats['stats'].append({
|
||||||
'player': x.batter_id if short_output else model_to_dict(x.batter, recurse=False),
|
'player': x.batter_id if short_output else model_to_dict(x.batter, recurse=False),
|
||||||
'team': x.batter_team_id if short_output else model_to_dict(x.batter_team, recurse=False),
|
'team': x.batter_team_id if short_output else model_to_dict(x.batter_team, recurse=False),
|
||||||
@ -342,10 +359,10 @@ async def get_totalplays(
|
|||||||
'bp1b': x.sum_bp1b,
|
'bp1b': x.sum_bp1b,
|
||||||
'bplo': x.sum_bplo,
|
'bplo': x.sum_bplo,
|
||||||
'wpa': x.sum_wpa + sum_wpa,
|
'wpa': x.sum_wpa + sum_wpa,
|
||||||
'avg': x.sum_hit / x.sum_ab,
|
'avg': x.sum_hit / tot_ab,
|
||||||
'obp': (x.sum_hit + x.sum_bb + x.sum_hbp + x.sum_ibb) / x.sum_pa,
|
'obp': (x.sum_hit + x.sum_bb + x.sum_hbp + x.sum_ibb) / x.sum_pa,
|
||||||
'slg': (x.sum_hr * 4 + x.sum_triple * 3 + x.sum_double * 2 +
|
'slg': (x.sum_hr * 4 + x.sum_triple * 3 + x.sum_double * 2 +
|
||||||
(x.sum_hit - x.sum_double - x.sum_triple - x.sum_hr)) / x.sum_ab,
|
(x.sum_hit - x.sum_double - x.sum_triple - x.sum_hr)) / tot_ab,
|
||||||
'woba': (.69 * x.sum_bb + .72 * x.sum_hbp + .89 * (x.sum_hit - x.sum_double - x.sum_triple - x.sum_hr) +
|
'woba': (.69 * x.sum_bb + .72 * x.sum_hbp + .89 * (x.sum_hit - x.sum_double - x.sum_triple - x.sum_hr) +
|
||||||
1.27 * x.sum_double + 1.62 * x.sum_triple + 2.1 * x.sum_hr) / (x.sum_pa - x.sum_ibb)
|
1.27 * x.sum_double + 1.62 * x.sum_triple + 2.1 * x.sum_hr) / (x.sum_pa - x.sum_ibb)
|
||||||
})
|
})
|
||||||
@ -358,6 +375,254 @@ async def get_totalplays(
|
|||||||
return return_stats
|
return return_stats
|
||||||
|
|
||||||
|
|
||||||
|
@router.get('/pitching')
|
||||||
|
async def get_pitching_totals(
|
||||||
|
season: list = Query(default=None), week: list = Query(default=None),
|
||||||
|
s_type: Literal['regular', 'post', 'total', None] = None,
|
||||||
|
player_id: list = Query(default=None), group_by: Literal['team', 'player', 'playerteam'] = 'player',
|
||||||
|
min_pa: Optional[int] = 1, team_id: list = Query(default=None), manager_id: list = Query(default=None),
|
||||||
|
sort: Optional[str] = None, limit: Optional[int] = None, short_output: Optional[bool] = False):
|
||||||
|
season_games = StratGame.select()
|
||||||
|
if season is not None:
|
||||||
|
season_games = season_games.where(StratGame.season << season)
|
||||||
|
if week is not None:
|
||||||
|
season_games = season_games.where(StratGame.week << week)
|
||||||
|
if manager_id is not None:
|
||||||
|
season_games = season_games.where(
|
||||||
|
(StratGame.away_manager_id << manager_id) | (StratGame.home_manager_id << manager_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
pit_plays = (
|
||||||
|
StratPlay
|
||||||
|
.select(StratPlay.pitcher, StratPlay.pitcher_team, fn.SUM(StratPlay.pa).alias('sum_pa'),
|
||||||
|
fn.SUM(StratPlay.ab).alias('sum_ab'), fn.SUM(StratPlay.run).alias('sum_run'),
|
||||||
|
fn.SUM(StratPlay.hit).alias('sum_hit'),
|
||||||
|
fn.SUM(StratPlay.double).alias('sum_double'), fn.SUM(StratPlay.triple).alias('sum_triple'),
|
||||||
|
fn.SUM(StratPlay.homerun).alias('sum_hr'), fn.SUM(StratPlay.bb).alias('sum_bb'),
|
||||||
|
fn.SUM(StratPlay.so).alias('sum_so'), fn.SUM(StratPlay.wpa).alias('sum_wpa'),
|
||||||
|
fn.SUM(StratPlay.hbp).alias('sum_hbp'), fn.SUM(StratPlay.sac).alias('sum_sac'),
|
||||||
|
fn.SUM(StratPlay.ibb).alias('sum_ibb'), fn.SUM(StratPlay.gidp).alias('sum_gidp'),
|
||||||
|
fn.SUM(StratPlay.sb).alias('sum_sb'), fn.SUM(StratPlay.cs).alias('sum_cs'),
|
||||||
|
fn.SUM(StratPlay.bphr).alias('sum_bphr'), fn.SUM(StratPlay.bpfo).alias('sum_bpfo'),
|
||||||
|
fn.SUM(StratPlay.bp1b).alias('sum_bp1b'), fn.SUM(StratPlay.bplo).alias('sum_bplo'),
|
||||||
|
fn.SUM(StratPlay.wild_pitch).alias('sum_wp'), fn.SUM(StratPlay.balk).alias('sum_balk'),
|
||||||
|
fn.SUM(StratPlay.outs).alias('sum_outs'), fn.SUM(StratPlay.e_run).alias('sum_erun'))
|
||||||
|
.where((StratPlay.game << season_games) & (StratPlay.pitcher.is_null(False)))
|
||||||
|
.having(fn.SUM(StratPlay.pa) >= min_pa)
|
||||||
|
)
|
||||||
|
all_dec = (
|
||||||
|
Decision
|
||||||
|
.select(Decision.pitcher, fn.SUM(Decision.win).alias('sum_win'), fn.SUM(Decision.loss).alias('sum_loss'),
|
||||||
|
fn.SUM(Decision.hold).alias('sum_hold'), fn.SUM(Decision.is_save).alias('sum_save'),
|
||||||
|
fn.SUM(Decision.b_save).alias('sum_b_save'), fn.SUM(Decision.irunners).alias('sum_irunners'),
|
||||||
|
fn.SUM(Decision.irunners_scored).alias('sum_irun_scored'),
|
||||||
|
fn.SUM(Decision.is_start).alias('sum_gs'), fn.COUNT(Decision.game).alias('sum_game'))
|
||||||
|
.where(Decision.game << season_games)
|
||||||
|
)
|
||||||
|
|
||||||
|
if player_id is not None:
|
||||||
|
all_players = Player.select().where(Player.id << player_id)
|
||||||
|
pit_plays = pit_plays.where(StratPlay.pitcher << all_players)
|
||||||
|
if team_id is not None:
|
||||||
|
all_teams = Team.select().where(Team.id << team_id)
|
||||||
|
pit_plays = pit_plays.where(StratPlay.pitcher_team << all_teams)
|
||||||
|
|
||||||
|
if group_by is not None:
|
||||||
|
if group_by == 'player':
|
||||||
|
pit_plays = pit_plays.group_by(StratPlay.pitcher)
|
||||||
|
elif group_by == 'team':
|
||||||
|
pit_plays = pit_plays.group_by(StratPlay.pitcher_team)
|
||||||
|
elif group_by == 'playerteam':
|
||||||
|
pit_plays = pit_plays.group_by(StratPlay.pitcher, StratPlay.pitcher_team)
|
||||||
|
if sort is not None:
|
||||||
|
if sort == 'player':
|
||||||
|
pit_plays = pit_plays.order_by(StratPlay.pitcher)
|
||||||
|
elif sort == 'team':
|
||||||
|
pit_plays = pit_plays.order_by(StratPlay.pitcher_team)
|
||||||
|
elif sort == 'wpa-desc':
|
||||||
|
pit_plays = pit_plays.order_by(SQL('sum_wpa').asc()) # functions seem reversed since pitcher plays negative
|
||||||
|
elif sort == 'wpa-asc':
|
||||||
|
pit_plays = pit_plays.order_by(SQL('sum_wpa').desc())
|
||||||
|
elif sort == 'ip-desc':
|
||||||
|
pit_plays = pit_plays.order_by(SQL('sum_outs').desc())
|
||||||
|
elif sort == 'ip-asc':
|
||||||
|
pit_plays = pit_plays.order_by(SQL('sum_outs').asc())
|
||||||
|
elif sort == 'game-desc':
|
||||||
|
pit_plays = pit_plays.order_by(SQL('sum_game').desc())
|
||||||
|
elif sort == 'game-asc':
|
||||||
|
pit_plays = pit_plays.order_by(SQL('sum_game').asc())
|
||||||
|
if limit is not None:
|
||||||
|
if limit < 1:
|
||||||
|
limit = 1
|
||||||
|
pit_plays = pit_plays.limit(limit)
|
||||||
|
|
||||||
|
return_stats = {
|
||||||
|
'count': pit_plays.count(),
|
||||||
|
'stats': []
|
||||||
|
}
|
||||||
|
|
||||||
|
for x in pit_plays:
|
||||||
|
this_dec = all_dec.where(Decision.pitcher == x.pitcher)
|
||||||
|
tot_outs = x.sum_outs if x.sum_outs > 0 else 1
|
||||||
|
return_stats['stats'].append({
|
||||||
|
'player': x.pitcher_id if short_output else model_to_dict(x.pitcher, recurse=False),
|
||||||
|
'team': x.pitcher_team_id if short_output else model_to_dict(x.pitcher_team, recurse=False),
|
||||||
|
'tbf': x.sum_pa,
|
||||||
|
'outs': x.sum_outs,
|
||||||
|
'games': this_dec[0].sum_game,
|
||||||
|
'gs': this_dec[0].sum_gs,
|
||||||
|
'win': this_dec[0].sum_win,
|
||||||
|
'loss': this_dec[0].sum_loss,
|
||||||
|
'hold': this_dec[0].sum_hold,
|
||||||
|
'save': this_dec[0].sum_save,
|
||||||
|
'bsave': this_dec[0].sum_b_save,
|
||||||
|
'ir': this_dec[0].sum_irunners,
|
||||||
|
'ir_sc': this_dec[0].sum_irun_scored,
|
||||||
|
'ab': x.sum_ab,
|
||||||
|
'run': x.sum_run,
|
||||||
|
'e_run': x.sum_erun,
|
||||||
|
'hits': x.sum_hit,
|
||||||
|
'double': x.sum_double,
|
||||||
|
'triple': x.sum_triple,
|
||||||
|
'hr': x.sum_hr,
|
||||||
|
'bb': x.sum_bb,
|
||||||
|
'so': x.sum_so,
|
||||||
|
'hbp': x.sum_hbp,
|
||||||
|
'sac': x.sum_sac,
|
||||||
|
'ibb': x.sum_ibb,
|
||||||
|
'gidp': x.sum_gidp,
|
||||||
|
'sb': x.sum_sb,
|
||||||
|
'cs': x.sum_cs,
|
||||||
|
'bphr': x.sum_bphr,
|
||||||
|
'bpfo': x.sum_bpfo,
|
||||||
|
'bp1b': x.sum_bp1b,
|
||||||
|
'bplo': x.sum_bplo,
|
||||||
|
'wp': x.sum_wp,
|
||||||
|
'balk': x.sum_balk,
|
||||||
|
'wpa': x.sum_wpa * -1,
|
||||||
|
'era': (x.sum_erun * 27) / tot_outs,
|
||||||
|
'whip': ((x.sum_bb + x.sum_hit + x.sum_ibb) * 3) / tot_outs,
|
||||||
|
'avg': x.sum_hit / x.sum_ab,
|
||||||
|
'obp': (x.sum_hit + x.sum_bb + x.sum_hbp + x.sum_ibb) / x.sum_pa,
|
||||||
|
'slg': (x.sum_hr * 4 + x.sum_triple * 3 + x.sum_double * 2 +
|
||||||
|
(x.sum_hit - x.sum_double - x.sum_triple - x.sum_hr)) / x.sum_ab,
|
||||||
|
'woba': (.69 * x.sum_bb + .72 * x.sum_hbp + .89 * (x.sum_hit - x.sum_double - x.sum_triple - x.sum_hr) +
|
||||||
|
1.27 * x.sum_double + 1.62 * x.sum_triple + 2.1 * x.sum_hr) / (x.sum_pa - x.sum_ibb)
|
||||||
|
})
|
||||||
|
db.close()
|
||||||
|
return return_stats
|
||||||
|
|
||||||
|
|
||||||
|
@router.get('/fielding')
|
||||||
|
async def get_fielding_totals(
|
||||||
|
season: list = Query(default=None), week: list = Query(default=None),
|
||||||
|
s_type: Literal['regular', 'post', 'total', None] = None, position: list = Query(default=None),
|
||||||
|
player_id: list = Query(default=None), group_by: Literal['team', 'player', 'playerteam'] = 'player',
|
||||||
|
min_ch: Optional[int] = 1, team_id: list = Query(default=None), manager_id: list = Query(default=None),
|
||||||
|
sort: Optional[str] = None, limit: Optional[int] = None, short_output: Optional[bool] = False):
|
||||||
|
season_games = StratGame.select()
|
||||||
|
if season is not None:
|
||||||
|
season_games = season_games.where(StratGame.season << season)
|
||||||
|
if week is not None:
|
||||||
|
season_games = season_games.where(StratGame.week << week)
|
||||||
|
if manager_id is not None:
|
||||||
|
season_games = season_games.where(
|
||||||
|
(StratGame.away_manager_id << manager_id) | (StratGame.home_manager_id << manager_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
def_plays = (
|
||||||
|
StratPlay
|
||||||
|
.select(StratPlay.defender, StratPlay.defender_team, fn.SUM(StratPlay.error).alias('sum_error'),
|
||||||
|
fn.SUM(StratPlay.hit).alias('sum_hit'), fn.SUM(StratPlay.pa).alias('sum_chances'),
|
||||||
|
fn.SUM(StratPlay.wpa).alias('sum_wpa'))
|
||||||
|
.where((StratPlay.game << season_games) & (StratPlay.defender.is_null(False)))
|
||||||
|
.having(fn.SUM(StratPlay.pa) >= min_ch)
|
||||||
|
)
|
||||||
|
cat_plays = (
|
||||||
|
StratPlay
|
||||||
|
.select(StratPlay.catcher, StratPlay.catcher_team, fn.SUM(StratPlay.sb).alias('sum_sb'),
|
||||||
|
fn.SUM(StratPlay.cs).alias('sum_cs'), fn.SUM(StratPlay.wpa).alias('sum_wpa'),
|
||||||
|
fn.SUM(StratPlay.passed_ball).alias('sum_pb'))
|
||||||
|
.where((StratPlay.game << season_games) & (StratPlay.catcher.is_null(False)))
|
||||||
|
)
|
||||||
|
|
||||||
|
if player_id is not None:
|
||||||
|
all_players = Player.select().where(Player.id << player_id)
|
||||||
|
def_plays = def_plays.where(StratPlay.defender << all_players)
|
||||||
|
cat_plays = cat_plays.where(StratPlay.catcher << all_players)
|
||||||
|
if team_id is not None:
|
||||||
|
all_teams = Team.select().where(Team.id << team_id)
|
||||||
|
def_plays = def_plays.where(StratPlay.defender_team << all_teams)
|
||||||
|
cat_plays = cat_plays.where(StratPlay.catcher_team << all_teams)
|
||||||
|
if position is not None:
|
||||||
|
def_plays = def_plays.where(StratPlay.check_pos << position)
|
||||||
|
|
||||||
|
if group_by is not None:
|
||||||
|
if group_by == 'player':
|
||||||
|
def_plays = def_plays.group_by(StratPlay.defender)
|
||||||
|
cat_plays = cat_plays.group_by(StratPlay.catcher)
|
||||||
|
elif group_by == 'team':
|
||||||
|
def_plays = def_plays.group_by(StratPlay.defender_team)
|
||||||
|
cat_plays = cat_plays.group_by(StratPlay.catcher_team)
|
||||||
|
elif group_by == 'playerteam':
|
||||||
|
def_plays = def_plays.group_by(StratPlay.defender, StratPlay.defender_team)
|
||||||
|
cat_plays = cat_plays.group_by(StratPlay.catcher, StratPlay.catcher_team)
|
||||||
|
if sort is not None:
|
||||||
|
if sort == 'player':
|
||||||
|
def_plays = def_plays.order_by(StratPlay.defender)
|
||||||
|
elif sort == 'team':
|
||||||
|
def_plays = def_plays.order_by(StratPlay.defender_team)
|
||||||
|
elif sort == 'wpa-desc':
|
||||||
|
def_plays = def_plays.order_by(SQL('sum_wpa').asc())
|
||||||
|
elif sort == 'wpa-asc':
|
||||||
|
def_plays = def_plays.order_by(SQL('sum_wpa').desc())
|
||||||
|
elif sort == 'ch-desc':
|
||||||
|
def_plays = def_plays.order_by(SQL('sum_chances').desc())
|
||||||
|
elif sort == 'ch-asc':
|
||||||
|
def_plays = def_plays.order_by(SQL('sum_chances').asc())
|
||||||
|
if limit is not None:
|
||||||
|
if limit < 1:
|
||||||
|
limit = 1
|
||||||
|
def_plays = def_plays.limit(limit)
|
||||||
|
|
||||||
|
logging.info(f'def_plays query: {def_plays}')
|
||||||
|
|
||||||
|
return_stats = {
|
||||||
|
'count': def_plays.count(),
|
||||||
|
'stats': []
|
||||||
|
}
|
||||||
|
|
||||||
|
for x in def_plays:
|
||||||
|
this_cat = cat_plays.where(StratPlay.catcher == x.defender)
|
||||||
|
if this_cat.count() > 0:
|
||||||
|
sum_sb = this_cat[0].sum_sb
|
||||||
|
sum_cs = this_cat[0].sum_cs
|
||||||
|
sum_wpa = this_cat[0].sum_wpa
|
||||||
|
sum_pb = this_cat[0].sum_pb
|
||||||
|
else:
|
||||||
|
sum_sb = 0
|
||||||
|
sum_cs = 0
|
||||||
|
sum_wpa = 0
|
||||||
|
sum_pb = 0
|
||||||
|
return_stats['stats'].append({
|
||||||
|
'player': x.defender_id if short_output else model_to_dict(x.defender, recurse=False),
|
||||||
|
'team': x.defender_team_id if short_output else model_to_dict(x.defender_team, recurse=False),
|
||||||
|
'pos': 'TOT' if position is None or len(position) > 1 else position[0],
|
||||||
|
'x-ch': x.sum_chances,
|
||||||
|
'hit': x.sum_hit,
|
||||||
|
'error': x.sum_error,
|
||||||
|
'sb-ch': sum_sb + sum_cs,
|
||||||
|
'sb': sum_sb,
|
||||||
|
'cs': sum_cs,
|
||||||
|
'pb': sum_pb,
|
||||||
|
'wpa': (x.sum_wpa + sum_wpa) * -1,
|
||||||
|
'wf%': (x.sum_chances - (x.sum_error * .5) - (x.sum_hit * .75)) / x.sum_chances,
|
||||||
|
'cs%': sum_cs / (sum_sb + sum_cs) if (sum_sb + sum_cs) > 0 else ''
|
||||||
|
})
|
||||||
|
db.close()
|
||||||
|
return return_stats
|
||||||
|
|
||||||
|
|
||||||
@router.get('/{play_id}')
|
@router.get('/{play_id}')
|
||||||
async def get_one_play(play_id: int):
|
async def get_one_play(play_id: int):
|
||||||
if StratPlay.get_or_none(StratPlay.id == play_id) is None:
|
if StratPlay.get_or_none(StratPlay.id == play_id) is None:
|
||||||
@ -413,7 +678,6 @@ async def post_plays(p_list: PlayList, token: str = Depends(oauth2_scheme)):
|
|||||||
if this_play.pa == 0:
|
if this_play.pa == 0:
|
||||||
this_play.batter_final = None
|
this_play.batter_final = None
|
||||||
|
|
||||||
|
|
||||||
new_plays.append(this_play.dict())
|
new_plays.append(this_play.dict())
|
||||||
|
|
||||||
with db.atomic():
|
with db.atomic():
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user