/standings, /teams, /transactions added
This commit is contained in:
parent
0c7712cd78
commit
54b0485599
@ -1,6 +1,6 @@
|
||||
from fastapi import Depends, FastAPI
|
||||
|
||||
from routers_v3 import current, players, results, schedules
|
||||
from routers_v3 import current, players, results, schedules, standings, teams, transactions
|
||||
|
||||
app = FastAPI(
|
||||
responses={404: {'description': 'Not found'}}
|
||||
@ -11,6 +11,9 @@ app.include_router(current.router)
|
||||
app.include_router(players.router)
|
||||
app.include_router(results.router)
|
||||
app.include_router(schedules.router)
|
||||
app.include_router(teams.router)
|
||||
app.include_router(transactions.router)
|
||||
app.include_router(standings.router)
|
||||
|
||||
|
||||
# @app.get("/api")
|
||||
|
||||
@ -44,7 +44,7 @@ class PlayerList(pydantic.BaseModel):
|
||||
@router.get('')
|
||||
def get_players(
|
||||
season: Optional[int], team_id: list = Query(default=None), pos: list = Query(default=None),
|
||||
is_injured: Optional[bool] = None, sort: Optional[str] = None):
|
||||
is_injured: Optional[bool] = None, short_output: Optional[bool] = False, sort: Optional[str] = None):
|
||||
logging.info(f'team_id: {team_id}')
|
||||
|
||||
all_players = Player.select_season(season)
|
||||
@ -74,17 +74,17 @@ def get_players(
|
||||
|
||||
return_players = {
|
||||
'count': all_players.count(),
|
||||
'players': [model_to_dict(x) for x in all_players]
|
||||
'players': [model_to_dict(x, recurse=not short_output) for x in all_players]
|
||||
}
|
||||
db.close()
|
||||
return return_players
|
||||
|
||||
|
||||
@router.get('/{player_id}')
|
||||
def get_one_player(player_id: int):
|
||||
def get_one_player(player_id: int, short_output: Optional[bool] = False):
|
||||
this_player = Player.get_or_none(Player.id == player_id)
|
||||
if this_player:
|
||||
r_player = model_to_dict(this_player)
|
||||
r_player = model_to_dict(this_player, recurse=not short_output)
|
||||
else:
|
||||
r_player = None
|
||||
db.close()
|
||||
|
||||
@ -31,7 +31,8 @@ class ResultList(pydantic.BaseModel):
|
||||
def get_results(
|
||||
season: int, team_abbrev: list = Query(default=None), week_start: list = Query(default=None),
|
||||
week_end: list = Query(default=None), game_num: list = Query(default=None),
|
||||
away_abbrev: list = Query(default=None), home_abbrev: list = Query(default=None)):
|
||||
away_abbrev: list = Query(default=None), home_abbrev: list = Query(default=None),
|
||||
short_output: Optional[bool] = False):
|
||||
all_results = Result.select_season(season)
|
||||
|
||||
if team_abbrev is not None:
|
||||
@ -65,17 +66,17 @@ def get_results(
|
||||
|
||||
return_results = {
|
||||
'count': all_results.count(),
|
||||
'results': [model_to_dict(x) for x in all_results]
|
||||
'results': [model_to_dict(x, recurse=not short_output) for x in all_results]
|
||||
}
|
||||
db.close()
|
||||
return return_results
|
||||
|
||||
|
||||
@router.get('/{result_id}')
|
||||
def get_one_result(result_id: int):
|
||||
def get_one_result(result_id: int, short_output: Optional[bool] = False):
|
||||
this_result = Result.get_or_none(Result.id == result_id)
|
||||
if this_result is not None:
|
||||
r_result = model_to_dict(this_result)
|
||||
r_result = model_to_dict(this_result, recurse=not short_output)
|
||||
else:
|
||||
r_result = None
|
||||
db.close()
|
||||
@ -86,10 +87,15 @@ def get_one_result(result_id: int):
|
||||
def patch_result(
|
||||
result_id: int, week_num: Optional[int] = None, game_num: Optional[int] = None,
|
||||
away_team_id: Optional[int] = None, home_team_id: Optional[int] = None, away_score: Optional[int] = None,
|
||||
home_score: Optional[int] = None, season: Optional[int] = None, scorecard_url: Optional[str] = None):
|
||||
home_score: Optional[int] = None, season: Optional[int] = None, scorecard_url: Optional[str] = None,
|
||||
token: str = Depends(oauth2_scheme)):
|
||||
if not valid_token(token):
|
||||
logging.warning(f'patch_player - Bad Token: {token}')
|
||||
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||
|
||||
this_result = Result.get_or_none(Result.id == result_id)
|
||||
if this_result is None:
|
||||
raise KeyError(f'Result ID {result_id} not found')
|
||||
raise HTTPException(status_code=404, detail=f'Result ID {result_id} not found')
|
||||
|
||||
if week_num is not None:
|
||||
this_result.week = week_num
|
||||
@ -121,17 +127,21 @@ def patch_result(
|
||||
return r_result
|
||||
else:
|
||||
db.close()
|
||||
raise DatabaseError(f'Unable to patch result {result_id}')
|
||||
raise HTTPException(status_code=500, detail=f'Unable to patch result {result_id}')
|
||||
|
||||
|
||||
@router.post('')
|
||||
def post_results(result_list: ResultList):
|
||||
def post_results(result_list: ResultList, token: str = Depends(oauth2_scheme)):
|
||||
if not valid_token(token):
|
||||
logging.warning(f'patch_player - Bad Token: {token}')
|
||||
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||
|
||||
new_results = []
|
||||
for x in result_list.results:
|
||||
if Team.get_or_none(Team.id == x.awayteam_id) is None:
|
||||
raise KeyError(f'Team ID {x.awayteam_id} not found')
|
||||
raise HTTPException(status_code=404, detail=f'Team ID {x.awayteam_id} not found')
|
||||
if Team.get_or_none(Team.id == x.hometeam_id) is None:
|
||||
raise KeyError(f'Team ID {x.hometeam_id} not found')
|
||||
raise HTTPException(status_code=404, detail=f'Team ID {x.hometeam_id} not found')
|
||||
|
||||
new_results.append(x.dict())
|
||||
|
||||
@ -144,11 +154,15 @@ def post_results(result_list: ResultList):
|
||||
|
||||
|
||||
@router.delete('/{result_id}')
|
||||
def delete_result(result_id: int):
|
||||
def delete_result(result_id: int, token: str = Depends(oauth2_scheme)):
|
||||
if not valid_token(token):
|
||||
logging.warning(f'delete_result - Bad Token: {token}')
|
||||
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||
|
||||
this_result = Result.get_or_none(Result.id == result_id)
|
||||
if not this_result:
|
||||
db.close()
|
||||
raise KeyError(f'Result ID {result_id} not found')
|
||||
raise HTTPException(status_code=404, detail=f'Result ID {result_id} not found')
|
||||
|
||||
count = this_result.delete_instance()
|
||||
db.close()
|
||||
@ -156,6 +170,6 @@ def delete_result(result_id: int):
|
||||
if count == 1:
|
||||
return f'Result {result_id} has been deleted'
|
||||
else:
|
||||
raise DatabaseError(f'Result {result_id} could not be deleted')
|
||||
raise HTTPException(status_code=500, detail=f'Result {result_id} could not be deleted')
|
||||
|
||||
|
||||
|
||||
@ -27,7 +27,8 @@ class ScheduleList(pydantic.BaseModel):
|
||||
@router.get('')
|
||||
def get_schedules(
|
||||
season: int, team_abbrev: list = Query(default=None), away_abbrev: list = Query(default=None),
|
||||
home_abbrev: list = Query(default=None), week_start: Optional[int] = None, week_end: Optional[int] = None):
|
||||
home_abbrev: list = Query(default=None), week_start: Optional[int] = None, week_end: Optional[int] = None,
|
||||
short_output: Optional[bool] = False):
|
||||
all_sched = Schedule.select_season(season)
|
||||
|
||||
if team_abbrev is not None:
|
||||
@ -60,17 +61,17 @@ def get_schedules(
|
||||
|
||||
return_sched = {
|
||||
'count': all_sched.count(),
|
||||
'schedules': [model_to_dict(x) for x in all_sched]
|
||||
'schedules': [model_to_dict(x, recurse=not short_output) for x in all_sched]
|
||||
}
|
||||
db.close()
|
||||
return return_sched
|
||||
|
||||
|
||||
@router.get('/{schedule_id}')
|
||||
def get_one_schedule(schedule_id: int):
|
||||
def get_one_schedule(schedule_id: int, short_output: Optional[bool] = False):
|
||||
this_sched = Schedule.get_or_none(Schedule.id == schedule_id)
|
||||
if this_sched is not None:
|
||||
r_sched = model_to_dict(this_sched)
|
||||
r_sched = model_to_dict(this_sched, recurse=not short_output)
|
||||
else:
|
||||
r_sched = None
|
||||
db.close()
|
||||
@ -83,7 +84,7 @@ def patch_schedule(
|
||||
hometeam_id: Optional[int] = None, gamecount: Optional[int] = None, season: Optional[int] = None):
|
||||
this_sched = Schedule.get_or_none(Schedule.id == schedule_id)
|
||||
if this_sched is None:
|
||||
raise KeyError(f'Schedule ID {schedule_id} not found')
|
||||
raise HTTPException(status_code=404, detail=f'Schedule ID {schedule_id} not found')
|
||||
|
||||
if week is not None:
|
||||
this_sched.week = week
|
||||
@ -106,7 +107,7 @@ def patch_schedule(
|
||||
return r_sched
|
||||
else:
|
||||
db.close()
|
||||
raise DatabaseError(f'Unable to patch schedule {schedule_id}')
|
||||
raise HTTPException(status_code=500, detail=f'Unable to patch schedule {schedule_id}')
|
||||
|
||||
|
||||
@router.post('')
|
||||
@ -114,9 +115,9 @@ def post_schedules(sched_list: ScheduleList):
|
||||
new_sched = []
|
||||
for x in sched_list.schedules:
|
||||
if Team.get_or_none(Team.id == x.awayteam_id) is None:
|
||||
raise KeyError(f'Team ID {x.awayteam_id} not found')
|
||||
raise HTTPException(status_code=404, detail=f'Team ID {x.awayteam_id} not found')
|
||||
if Team.get_or_none(Team.id == x.hometeam_id) is None:
|
||||
raise KeyError(f'Team ID {x.hometeam_id} not found')
|
||||
raise HTTPException(status_code=404, detail=f'Team ID {x.hometeam_id} not found')
|
||||
|
||||
new_sched.append(x.dict())
|
||||
|
||||
@ -132,7 +133,7 @@ def post_schedules(sched_list: ScheduleList):
|
||||
def delete_schedule(schedule_id: int):
|
||||
this_sched = Schedule.get_or_none(Schedule.id == schedule_id)
|
||||
if this_sched is None:
|
||||
raise KeyError(f'Schedule ID {schedule_id} not found')
|
||||
raise HTTPException(status_code=404, detail=f'Schedule ID {schedule_id} not found')
|
||||
|
||||
count = this_sched.delete_instance()
|
||||
db.close()
|
||||
@ -140,4 +141,4 @@ def delete_schedule(schedule_id: int):
|
||||
if count == 1:
|
||||
return f'Schedule {this_sched} has been deleted'
|
||||
else:
|
||||
raise DatabaseError(f'Schedule {this_sched} could not be deleted')
|
||||
raise HTTPException(status_code=500, detail=f'Schedule {this_sched} could not be deleted')
|
||||
|
||||
102
app/routers_v3/standings.py
Normal file
102
app/routers_v3/standings.py
Normal file
@ -0,0 +1,102 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from typing import List, Optional
|
||||
import logging
|
||||
import pydantic
|
||||
|
||||
from db_engine import db, Standings, Team, Division, model_to_dict, chunked, fn
|
||||
from dependencies import oauth2_scheme, valid_token, logging
|
||||
|
||||
router = APIRouter(
|
||||
prefix='/api/v3/standings',
|
||||
tags=['standings']
|
||||
)
|
||||
|
||||
|
||||
@router.get('')
|
||||
async def v1_standings(
|
||||
season: int, team_abbrev: Optional[str] = None, league_abbrev: Optional[str] = None,
|
||||
division_abbrev: Optional[str] = None, short_output: Optional[bool] = False):
|
||||
standings = Standings.select_season(season)
|
||||
|
||||
if standings.count() == 0:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'No output for season {season}')
|
||||
|
||||
if team_abbrev:
|
||||
this_team = Team.get_season(team_abbrev, season)
|
||||
if not this_team:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found')
|
||||
|
||||
standings = standings.where(Standings.team == this_team)
|
||||
|
||||
if league_abbrev:
|
||||
these_divisions = Division.select().where(fn.Lower(Division.league_abbrev) == league_abbrev.lower())
|
||||
if these_divisions.count() == 0:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'No output for league {league_abbrev}')
|
||||
|
||||
standings = standings.where(Standings.team.division << these_divisions)
|
||||
|
||||
if division_abbrev:
|
||||
this_division = Division.select().where(fn.Lower(Division.division_abbrev) == division_abbrev.lower())
|
||||
if not this_division:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'No output for division {division_abbrev}')
|
||||
|
||||
standings = standings.where(Standings.team.division << this_division)
|
||||
|
||||
def win_pct(this_team_stan):
|
||||
if this_team_stan.wins + this_team_stan.losses == 0:
|
||||
return 0
|
||||
else:
|
||||
return (this_team_stan.wins / (this_team_stan.wins + this_team_stan.losses)) + \
|
||||
(this_team_stan.run_diff * .000001)
|
||||
|
||||
div_teams = [team_stan for team_stan in standings]
|
||||
div_teams.sort(key=lambda team: win_pct(team), reverse=True)
|
||||
|
||||
return_standings = {
|
||||
'count': len(div_teams),
|
||||
'standings': [model_to_dict(x, recurse=not short_output) for x in div_teams]
|
||||
}
|
||||
|
||||
db.close()
|
||||
return return_standings
|
||||
|
||||
|
||||
@router.patch('/api/v1/standings/{stan_id}')
|
||||
async def patch_standings(
|
||||
stan_id, wins: Optional[int] = None, losses: Optional[int] = None, token: str = Depends(oauth2_scheme)):
|
||||
if not valid_token(token):
|
||||
logging.warning(f'patch_player - Bad Token: {token}')
|
||||
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||
|
||||
try:
|
||||
this_stan = Standings.get_by_id(stan_id)
|
||||
except Exception as e:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'No team found with id {stan_id}')
|
||||
|
||||
if wins:
|
||||
this_stan.wins = wins
|
||||
if losses:
|
||||
this_stan.losses = losses
|
||||
|
||||
this_stan.save()
|
||||
db.close()
|
||||
|
||||
return model_to_dict(this_stan)
|
||||
|
||||
|
||||
@router.post('/api/v1/standings/s{season}/recalculate')
|
||||
async def recalculate_standings(season: int, token: str = Depends(oauth2_scheme)):
|
||||
if not valid_token(token):
|
||||
logging.warning(f'recalculate_standings - Bad Token: {token}')
|
||||
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||
|
||||
code = Standings.recalculate(season)
|
||||
db.close()
|
||||
if code == 69:
|
||||
HTTPException(status_code=500, detail=f'Error recreating Standings rows')
|
||||
raise HTTPException(status_code=200, detail=f'Just recalculated standings for season {season}')
|
||||
200
app/routers_v3/teams.py
Normal file
200
app/routers_v3/teams.py
Normal file
@ -0,0 +1,200 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from typing import List, Optional
|
||||
import logging
|
||||
import pydantic
|
||||
|
||||
from db_engine import db, Team, Manager, Division, model_to_dict, chunked
|
||||
from dependencies import oauth2_scheme, valid_token, logging
|
||||
|
||||
router = APIRouter(
|
||||
prefix='/api/v3/teams',
|
||||
tags=['teams']
|
||||
)
|
||||
|
||||
|
||||
class TeamModel(pydantic.BaseModel):
|
||||
abbrev: str
|
||||
sname: str
|
||||
lname: str
|
||||
gmid: Optional[int] = None
|
||||
gmid2: Optional[int] = None
|
||||
manager1_id: Optional[int] = None
|
||||
manager2_id: Optional[int] = None
|
||||
division_id: Optional[int] = None
|
||||
stadium: Optional[str] = None
|
||||
thumbnail: Optional[str] = None
|
||||
color: Optional[str] = None
|
||||
dice_color: Optional[str] = None
|
||||
season: int
|
||||
|
||||
|
||||
class TeamList(pydantic.BaseModel):
|
||||
teams: List[TeamModel]
|
||||
|
||||
|
||||
@router.get('')
|
||||
def get_teams(
|
||||
season: Optional[int] = None, owner_id: Optional[int] = None, manager_id: Optional[int] = None,
|
||||
abbrev: Optional[str] = None, active_only: Optional[bool] = False, short_output: Optional[bool] = False):
|
||||
if season is not None:
|
||||
all_teams = Team.select_season(season)
|
||||
else:
|
||||
all_teams = Team.select()
|
||||
|
||||
if manager_id is not None:
|
||||
all_teams = all_teams.where(
|
||||
(Team.manager1_id == manager_id) | (Team.manager2_id == manager_id)
|
||||
)
|
||||
|
||||
if owner_id:
|
||||
all_teams = all_teams.where((Team.gmid == owner_id) | (Team.gmid2 == owner_id))
|
||||
|
||||
if active_only:
|
||||
all_teams = all_teams.where(
|
||||
~(Team.abbrev.endswith('IL')) & ~(Team.abbrev.endswith('MiL'))
|
||||
)
|
||||
|
||||
if abbrev is not None:
|
||||
all_teams = all_teams.where(Team.abbrev == abbrev)
|
||||
|
||||
return_teams = {
|
||||
'count': all_teams.count(),
|
||||
'teams': [model_to_dict(x, recurse=not short_output) for x in all_teams]
|
||||
}
|
||||
db.close()
|
||||
return return_teams
|
||||
|
||||
|
||||
@router.get('/{team_id}')
|
||||
def get_one_team(team_id: int, short_output: Optional[bool] = False):
|
||||
this_team = Team.get_or_none(Team.id == team_id)
|
||||
if this_team:
|
||||
r_team = model_to_dict(this_team, recurse=not short_output)
|
||||
else:
|
||||
r_team = None
|
||||
db.close()
|
||||
return r_team
|
||||
|
||||
|
||||
@router.get('/{team_id}')
|
||||
def patch_team(
|
||||
team_id: int, manager1_id: Optional[int] = None, manager2_id: Optional[int] = None, gmid: Optional[int] = None,
|
||||
gmid2: Optional[int] = None, mascot: Optional[str] = None, stadium: Optional[str] = None,
|
||||
thumbnail: Optional[str] = None, color: Optional[str] = None, abbrev: Optional[str] = None,
|
||||
sname: Optional[str] = None, lname: Optional[str] = None, dice_color: Optional[str] = None,
|
||||
division_id: Optional[int] = None):
|
||||
this_team = Team.get_or_none(Team.id == team_id)
|
||||
if not this_team:
|
||||
return None
|
||||
|
||||
if abbrev is not None:
|
||||
this_team.abbrev = abbrev
|
||||
if manager1_id is not None:
|
||||
if manager1_id == 0:
|
||||
this_team.manager1 = None
|
||||
else:
|
||||
this_manager = Manager.get_or_none(Manager.id == manager1_id)
|
||||
if not this_manager:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Manager ID {manager1_id} not found')
|
||||
this_team.manager1 = this_manager
|
||||
if manager2_id is not None:
|
||||
if manager2_id == 0:
|
||||
this_team.manager2 = None
|
||||
else:
|
||||
this_manager = Manager.get_or_none(Manager.id == manager2_id)
|
||||
if not this_manager:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Manager ID {manager2_id} not found')
|
||||
this_team.manager2 = this_manager
|
||||
if gmid is not None:
|
||||
this_team.gmid = gmid
|
||||
if gmid2 is not None:
|
||||
if gmid2 == 0:
|
||||
this_team.gmid2 = None
|
||||
else:
|
||||
this_team.gmid2 = gmid2
|
||||
if mascot is not None:
|
||||
if mascot == 'False':
|
||||
this_team.mascot = None
|
||||
else:
|
||||
this_team.mascot = mascot
|
||||
if stadium is not None:
|
||||
this_team.stadium = stadium
|
||||
if thumbnail is not None:
|
||||
this_team.thumbnail = thumbnail
|
||||
if color is not None:
|
||||
this_team.color = color
|
||||
if dice_color is not None:
|
||||
this_team.dice_color = dice_color
|
||||
if sname is not None:
|
||||
this_team.sname = sname
|
||||
if lname is not None:
|
||||
this_team.lname = lname
|
||||
if division_id is not None:
|
||||
if division_id == 0:
|
||||
this_team.division = None
|
||||
else:
|
||||
this_division = Division.get_or_none(Division.id == division_id)
|
||||
if not this_division:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Division ID {division_id} not found')
|
||||
this_team.division = this_division
|
||||
|
||||
if this_team.save():
|
||||
r_team = model_to_dict(this_team)
|
||||
db.close()
|
||||
return r_team
|
||||
else:
|
||||
db.close()
|
||||
raise HTTPException(status_code=500, detail=f'Unable to patch team {team_id}')
|
||||
|
||||
|
||||
@router.get('')
|
||||
def post_team(team_list: TeamList):
|
||||
new_teams = []
|
||||
for team in team_list.teams:
|
||||
dupe_team = Team.get_or_none(Team.season == team.season, Team.abbrev == team.abbrev)
|
||||
if dupe_team:
|
||||
db.close()
|
||||
raise HTTPException(
|
||||
status_code=500, detail=f'Team Abbrev {team.abbrev} already in use in Season {team.season}'
|
||||
)
|
||||
|
||||
if team.manager1_id and not Manager.get_or_none(Manager.id == team.manager1_id):
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Manager ID {team.manager1_id} not found')
|
||||
|
||||
if team.manager2_id and not Manager.get_or_none(Manager.id == team.manager2_id):
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Manager ID {team.manager2_id} not found')
|
||||
|
||||
if team.division_id and not Division.get_or_none(Division.id == team.division_id):
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Division ID {team.division_id} not found')
|
||||
|
||||
new_teams.append(team.dict())
|
||||
|
||||
with db.atomic():
|
||||
for batch in chunked(new_teams, 15):
|
||||
Team.insert_many(batch).on_conflict_replace().execute()
|
||||
db.close()
|
||||
|
||||
return f'Inserted {len(new_teams)} teams'
|
||||
|
||||
|
||||
@router.get('/{team_id}')
|
||||
def delete_team(team_id: int):
|
||||
this_team = Team.get_or_none(Team.id == team_id)
|
||||
if not this_team:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Team ID {team_id} not found')
|
||||
|
||||
count = this_team.delete_instance()
|
||||
db.close()
|
||||
|
||||
if count == 1:
|
||||
return f'Team {team_id} has been deleted'
|
||||
else:
|
||||
raise HTTPException(status_code=500, detail=f'Team {team_id} could not be deleted')
|
||||
|
||||
176
app/routers_v3/transactions.py
Normal file
176
app/routers_v3/transactions.py
Normal file
@ -0,0 +1,176 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Response
|
||||
from typing import List, Optional
|
||||
from pandas import DataFrame
|
||||
import logging
|
||||
import pydantic
|
||||
|
||||
from db_engine import db, Transaction, Team, Player, model_to_dict, chunked, fn
|
||||
from dependencies import oauth2_scheme, valid_token, logging
|
||||
|
||||
router = APIRouter(
|
||||
prefix='/api/v3/transactions',
|
||||
tags=['transactions']
|
||||
)
|
||||
|
||||
|
||||
class TransactionModel(pydantic.BaseModel):
|
||||
week: int
|
||||
player_id: int
|
||||
oldteam_id: int
|
||||
newteam_id: int
|
||||
season: int
|
||||
moveid: str
|
||||
cancelled: Optional[bool] = False
|
||||
frozen: Optional[bool] = False
|
||||
|
||||
|
||||
class TransactionList(pydantic.BaseModel):
|
||||
count: int
|
||||
moves: List[TransactionModel]
|
||||
|
||||
|
||||
@router.get('')
|
||||
async def get_transactions(
|
||||
season, team_abbrev: Optional[str] = None, week_start: Optional[int] = 0,
|
||||
week_end: Optional[int] = None, cancelled: Optional[bool] = None, frozen: Optional[bool] = None,
|
||||
player_name: Optional[str] = None, player_id: Optional[int] = None, move_id: Optional[str] = None,
|
||||
is_trade: Optional[bool] = None, short_output: Optional[bool] = False):
|
||||
if season:
|
||||
transactions = Transaction.select_season(season)
|
||||
else:
|
||||
transactions = Transaction.select()
|
||||
|
||||
# if transactions.count() == 0:
|
||||
# db.close()
|
||||
# raise HTTPException(status_code=404, detail=f'Season {season} not found')
|
||||
|
||||
if team_abbrev:
|
||||
these_teams = Team.select().where(
|
||||
(Team.abbrev == team_abbrev.upper()) |
|
||||
(Team.abbrev == f'{team_abbrev.upper()}MiL') | (Team.abbrev == f'{team_abbrev.upper()}IL')
|
||||
)
|
||||
if these_teams.count() == 0:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found')
|
||||
|
||||
transactions = transactions.where(
|
||||
(Transaction.newteam << these_teams) | (Transaction.oldteam << these_teams)
|
||||
)
|
||||
|
||||
if week_start is not None:
|
||||
transactions = transactions.where(Transaction.week >= week_start)
|
||||
|
||||
if week_end is not None:
|
||||
transactions = transactions.where(Transaction.week <= week_end)
|
||||
|
||||
if move_id:
|
||||
transactions = transactions.where(Transaction.moveid == move_id)
|
||||
|
||||
if player_id or player_name:
|
||||
if player_id:
|
||||
try:
|
||||
this_player = Player.get_by_id(player_id)
|
||||
except Exception as e:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Player id {player_id} not found')
|
||||
|
||||
transactions = transactions.where(Transaction.player == this_player)
|
||||
else:
|
||||
these_players = Player.select().where(fn.Lower(Player.name) == player_name.lower())
|
||||
print(f'these_players: {these_players}\nCount: {these_players.count()}')
|
||||
if these_players.count() == 0:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Player {player_name} not found')
|
||||
|
||||
transactions = transactions.where(Transaction.player << these_players)
|
||||
|
||||
if cancelled:
|
||||
transactions = transactions.where(Transaction.cancelled == 1)
|
||||
else:
|
||||
transactions = transactions.where(Transaction.cancelled == 0)
|
||||
|
||||
if frozen:
|
||||
transactions = transactions.where(Transaction.frozen == 1)
|
||||
else:
|
||||
transactions = transactions.where(Transaction.frozen == 0)
|
||||
|
||||
if is_trade is not None:
|
||||
raise HTTPException(status_code=501, detail='The is_trade parameter is not implemented, yet')
|
||||
|
||||
transactions = transactions.order_by(-Transaction.week, Transaction.moveid)
|
||||
|
||||
return_trans = {
|
||||
'count': transactions.count(),
|
||||
'transactions': [model_to_dict(x, recurse=not short_output) for x in transactions]
|
||||
}
|
||||
|
||||
db.close()
|
||||
return return_trans
|
||||
|
||||
|
||||
@router.patch('/{move_id}')
|
||||
async def patch_transactions(
|
||||
move_id, token: str = Depends(oauth2_scheme), frozen: Optional[bool] = None, cancelled: Optional[bool] = None):
|
||||
if not valid_token(token):
|
||||
logging.warning(f'patch_transactions - Bad Token: {token}')
|
||||
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||
|
||||
these_moves = Transaction.select().where(Transaction.moveid == move_id)
|
||||
if these_moves.count() == 0:
|
||||
db.close()
|
||||
raise HTTPException(status_code=404, detail=f'Move ID {move_id} not found')
|
||||
|
||||
if frozen is not None:
|
||||
for x in these_moves:
|
||||
x.frozen = frozen
|
||||
x.save()
|
||||
if cancelled is not None:
|
||||
for x in these_moves:
|
||||
x.cancelled = cancelled
|
||||
x.save()
|
||||
|
||||
db.close()
|
||||
raise HTTPException(status_code=200, detail=f'Updated {these_moves.count()} transactions')
|
||||
|
||||
|
||||
@router.post('')
|
||||
async def post_transactions(moves: TransactionList, token: str = Depends(oauth2_scheme)):
|
||||
if not valid_token(token):
|
||||
logging.warning(f'post_transactions - Bad Token: {token}')
|
||||
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||
|
||||
all_moves = []
|
||||
|
||||
for x in moves.moves:
|
||||
if Team.get_or_none(Team.id == x.oldteam_id) is None:
|
||||
raise HTTPException(status_code=404, detail=f'Team ID {x.oldteam_id} not found')
|
||||
if Team.get_or_none(Team.id == x.newteam_id) is None:
|
||||
raise HTTPException(status_code=404, detail=f'Team ID {x.newteam_id} not found')
|
||||
if Player.get_or_none(Player.id == x.player_id):
|
||||
raise HTTPException(status_code=404, detail=f'Player ID {x.player_id} not found')
|
||||
|
||||
all_moves.append(x.dict())
|
||||
|
||||
with db.atomic():
|
||||
for batch in chunked(all_moves, 15):
|
||||
Transaction.insert_many(batch).on_conflict_replace().execute()
|
||||
|
||||
db.close()
|
||||
raise HTTPException(status_code=200, detail=f'{len(all_moves)} transactions have been added')
|
||||
|
||||
|
||||
@router.delete('/{move_id}')
|
||||
async def delete_transactions(move_id, token: str = Depends(oauth2_scheme)):
|
||||
if not valid_token(token):
|
||||
logging.warning(f'delete_transactions - Bad Token: {token}')
|
||||
raise HTTPException(status_code=401, detail='Unauthorized')
|
||||
|
||||
delete_query = Transaction.delete().where(Transaction.moveid == move_id)
|
||||
|
||||
count = delete_query.execute()
|
||||
db.close()
|
||||
if count > 0:
|
||||
raise HTTPException(status_code=200, detail=f'Removed {count} transactions')
|
||||
else:
|
||||
raise HTTPException(status_code=418, detail=f'Well slap my ass and call me a teapot; '
|
||||
f'I did not delete any records')
|
||||
Loading…
Reference in New Issue
Block a user