Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Baseball Player Stats and Box Player #457

Merged
merged 2 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions espn_api/baseball/box_player.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from .constant import POSITION_MAP, PRO_TEAM_MAP
from .player import Player
from datetime import datetime, timedelta


class BoxPlayer(Player):
'''player with extra data from a matchup'''
def __init__(self, data, pro_schedule, week, year):
super(BoxPlayer, self).__init__(data, year)
self.slot_position = 'FA'
self.pro_opponent = "None" # professional team playing against
self.pro_pos_rank = 0 # rank of professional team against player position
self.game_played = 100 # 0-100 for percent of game played
self.on_bye_week = False

if 'lineupSlotId' in data:
self.slot_position = POSITION_MAP[data['lineupSlotId']]

player = data['playerPoolEntry']['player'] if 'playerPoolEntry' in data else data['player']
if player['proTeamId'] in pro_schedule:
(opp_id, date) = pro_schedule[player['proTeamId']]
self.game_date = datetime.fromtimestamp(date/1000.0)
self.game_played = 100 if datetime.now() > self.game_date + timedelta(hours=3) else 0
self.pro_opponent = PRO_TEAM_MAP[opp_id]
else: # bye week
self.on_bye_week = True

stats = self.stats.get(week, {})
self.points = stats.get('points', 0)
self.points_breakdown = stats.get('breakdown', 0)
self.projected_points = stats.get('projected_points', 0)
self.projected_breakdown = stats.get('projected_breakdown', 0)

def __repr__(self):
return f'Player({self.name}, points:{self.points}, projected:{self.projected_points})'
25 changes: 23 additions & 2 deletions espn_api/baseball/box_score.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from abc import ABC, abstractmethod
from .box_player import BoxPlayer

from .constant import STATS_MAP

Expand Down Expand Up @@ -34,7 +35,7 @@ def __repr__(self):

class H2HCategoryBoxScore(BoxScore):
'''Boxscore class for head to head categories leagues'''
def __init__(self, data):
def __init__(self, data, pro_schedule, year, scoring_period = 0):
super().__init__(data)

def _process_team(self, team_data, is_home_team):
Expand Down Expand Up @@ -68,9 +69,29 @@ def _process_team(self, team_data, is_home_team):

class H2HPointsBoxScore(BoxScore):
'''Boxscore class for head to head points leagues'''
def __init__(self, data):
def __init__(self, data, pro_schedule, year, scoring_period = 0):
super().__init__(data)

(self.home_team, self.home_score, self.home_projected, self.home_lineup) = self._get_team_data('home', data, pro_schedule, scoring_period, year)

(self.away_team, self.away_score, self.away_projected, self.away_lineup) = self._get_team_data('away', data, pro_schedule, scoring_period, year)

def _process_team(self, team_data, is_home_team):
super()._process_team(team_data, is_home_team)
# TODO implement setting the scores

def _get_team_data(self, team, data, pro_schedule, week, year):
if team not in data:
return (0, 0, -1, [])

team_id = data[team]['teamId']
team_projected = -1
if 'totalPointsLive' in data[team]:
team_score = round(data[team]['totalPointsLive'], 2)
team_projected = round(data[team].get('totalProjectedPointsLive', -1), 2)
else:
team_score = round(data[team]['totalPoints'], 2)
team_roster = data[team].get('rosterForCurrentScoringPeriod', {}).get('entries', [])
team_lineup = [BoxPlayer(player, pro_schedule, week, year) for player in team_roster]

return (team_id, team_score, team_projected, team_lineup)
5 changes: 3 additions & 2 deletions espn_api/baseball/league.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def free_agents(self, week: int=None, size: int=50, position: str=None, position
data = self.espn_request.league_get(params=params, headers=headers)
players = data['players']

return [Player(player) for player in players]
return [Player(player, self.year) for player in players]

def box_scores(self, matchup_period: int = None, scoring_period: int = None) -> List[Union[BoxScore, H2HCategoryBoxScore]]:
'''Returns list of box score for a given matchup or scoring period'''
Expand All @@ -159,9 +159,10 @@ def box_scores(self, matchup_period: int = None, scoring_period: int = None) ->
filters = {"schedule":{"filterMatchupPeriodIds":{"value":[matchup_id]}}}
headers = {'x-fantasy-filter': json.dumps(filters)}
data = self.espn_request.league_get(params=params, headers=headers)
pro_schedule = self._get_pro_schedule(scoring_id)

schedule = data['schedule']
box_data = [self._box_score_class(matchup) for matchup in schedule]
box_data = [self._box_score_class(matchup, pro_schedule, self.year, scoring_id) for matchup in schedule]

for team in self.teams:
for matchup in box_data:
Expand Down
22 changes: 20 additions & 2 deletions espn_api/baseball/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class Player(object):
'''Player are part of team'''
def __init__(self, data):
def __init__(self, data, year):
self.name = json_parsing(data, 'fullName')
self.playerId = json_parsing(data, 'id')
self.position = POSITION_MAP.get(json_parsing(data, 'defaultPositionId') - 1, json_parsing(data, 'defaultPositionId') - 1)
Expand All @@ -15,10 +15,28 @@ def __init__(self, data):
self.injuryStatus = json_parsing(data, 'injuryStatus')
self.stats = {}

# add available stats
player = data.get('playerPoolEntry', {}).get('player') or data['player']
self.injuryStatus = player.get('injuryStatus', self.injuryStatus)
self.injured = player.get('injured', False)

# add available stats
player_stats = player.get('stats', [])
for stats in player_stats:
if stats.get('seasonId') != year:
continue
stats_breakdown = stats.get('stats') or stats.get('appliedStats', {})
breakdown = {STATS_MAP.get(int(k), k):v for (k,v) in stats_breakdown.items()}
points = round(stats.get('appliedTotal', 0), 2)
scoring_period = stats.get('scoringPeriodId')
stat_source = stats.get('statSourceId')
(points_type, breakdown_type) = ('points', 'breakdown') if stat_source == 0 else ('projected_points', 'projected_breakdown')
if self.stats.get(scoring_period):
self.stats[scoring_period][points_type] = points
self.stats[scoring_period][breakdown_type] = breakdown
else:
self.stats[scoring_period] = {points_type: points, breakdown_type: breakdown}
self.total_points = self.stats.get(0, {}).get('points', 0)
self.projected_total_points = self.stats.get(0, {}).get('projected_points', 0)

def __repr__(self):
return 'Player(%s)' % (self.name, )
6 changes: 3 additions & 3 deletions espn_api/baseball/team.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,20 @@ def __init__(self, data, member, roster, schedule, year, **kwargs):
if 'logo' in data:
self.logo_url = data['logo']

self._fetch_roster(roster)
self._fetch_roster(roster, year)
self._fetch_schedule(schedule)

def __repr__(self):
return f'Team({self.team_name})'


def _fetch_roster(self, data):
def _fetch_roster(self, data, year):
'''Fetch teams roster'''
self.roster.clear()
roster = data['entries']

for player in roster:
self.roster.append(Player(player))
self.roster.append(Player(player, year))


def _fetch_schedule(self, data):
Expand Down
2 changes: 1 addition & 1 deletion tests/baseball/integration/test_league.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_league_free_agents(self):
self.assertNotEqual(len(free_agents), 0)

def test_league_box_scores(self):
box_scores = self.league.box_scores(1)
box_scores = self.league.box_scores(0)

self.assertNotEqual(len(box_scores), 0)

Expand Down