RosterHash/services/espn_api.py

122 lines
5.7 KiB
Python

import requests
from datetime import datetime, timedelta, timezone
import zoneinfo
class ESPNAPI:
BASE_URL = 'https://site.api.espn.com/apis/site/v2/sports/football/nfl'
def __init__(self):
self.session = requests.Session()
def get_week_schedule(self, week, season, user_timezone='America/Los_Angeles'):
"""Get NFL schedule for a specific week"""
try:
print(f"ESPN API: Fetching schedule for week {week}, season {season}", flush=True)
# Get current NFL scoreboard
url = f"{self.BASE_URL}/scoreboard"
response = self.session.get(url)
response.raise_for_status()
data = response.json()
print(f"ESPN API: Response status: {response.status_code}", flush=True)
games = []
if 'events' in data:
print(f"ESPN API: Found {len(data['events'])} events", flush=True)
for i, event in enumerate(data['events']):
try:
# Parse the game date as UTC
game_date_utc = datetime.strptime(event['date'], '%Y-%m-%dT%H:%MZ').replace(tzinfo=timezone.utc)
# Convert to user's timezone (default PST)
try:
user_tz = zoneinfo.ZoneInfo(user_timezone)
except:
# Fallback to PST if timezone is invalid
user_tz = zoneinfo.ZoneInfo('America/Los_Angeles')
user_timezone = 'America/Los_Angeles'
game_date_local = game_date_utc.astimezone(user_tz)
# Get timezone abbreviation
tz_abbr = game_date_local.strftime('%Z')
if not tz_abbr: # Fallback if %Z doesn't work
if 'Los_Angeles' in user_timezone or 'Pacific' in user_timezone:
tz_abbr = 'PST' if game_date_local.dst() == timedelta(0) else 'PDT'
elif 'New_York' in user_timezone or 'Eastern' in user_timezone:
tz_abbr = 'EST' if game_date_local.dst() == timedelta(0) else 'EDT'
else:
tz_abbr = 'Local'
# Extract team information
competitors = event['competitions'][0]['competitors']
home_team = None
away_team = None
# Identify home and away teams
for comp in competitors:
team_abbrev = comp['team']['abbreviation']
if comp['homeAway'] == 'home':
home_team = team_abbrev
else:
away_team = team_abbrev
print(f"ESPN API: {away_team} @ {home_team} at {game_date_local.strftime('%I:%M %p')} {tz_abbr}", flush=True)
# Store game data with user's local times
games.append({
'date': game_date_utc, # Keep UTC for reference
'date_local': game_date_local,
'day_of_week': game_date_local.strftime('%A'),
'date_formatted': game_date_local.strftime('%m/%d'),
'time': f"{game_date_local.strftime('%I:%M %p')} {tz_abbr}",
'home_team': home_team,
'away_team': away_team,
'teams': [home_team, away_team],
'is_past': game_date_local < datetime.now(game_date_local.tzinfo)
})
except Exception as e:
print(f"ESPN API: Error processing event {i+1}: {str(e)}", flush=True)
else:
print("ESPN API: No 'events' key found in response", flush=True)
print(f"ESPN API: Processed {len(games)} games total", flush=True)
schedule = self._organize_by_day(games)
# Log games by day
for day, day_games in schedule.items():
print(f"ESPN API: {day}: {len(day_games)} games", flush=True)
return schedule
except Exception as e:
print(f"ESPN API: Error fetching schedule: {e}", flush=True)
return {}
def _organize_by_day(self, games):
"""Organize games by day, sorted chronologically with date info"""
schedule = {}
# Sort games by date first
games_sorted = sorted(games, key=lambda x: x['date_local'])
# Group games by day
for game in games_sorted:
day_key = f"{game['day_of_week']} {game['date_formatted']}"
if day_key not in schedule:
schedule[day_key] = {
'day_name': game['day_of_week'],
'date': game['date_formatted'],
'date_obj': game['date_local'].date(),
'is_past': game['date_local'].date() < datetime.now(game['date_local'].tzinfo).date(),
'games': []
}
schedule[day_key]['games'].append(game)
# Sort games within each day by time
for day_info in schedule.values():
day_info['games'].sort(key=lambda x: x['date_local'])
return schedule