Files
Sportstime/Scripts/generate_canonical_data.py
Trey t 92d808caf5 Add Stadium Progress system and themed loading spinners
Stadium Progress & Achievements:
- Add StadiumVisit and Achievement SwiftData models
- Create Progress tab with interactive map view
- Implement photo-based visit import with GPS/date matching
- Add achievement badges (count-based, regional, journey)
- Create shareable progress cards for social media
- Add canonical data infrastructure (stadium identities, team aliases)
- Implement score resolution from free APIs (MLB, NBA, NHL stats)

UI Improvements:
- Add ThemedSpinner and ThemedSpinnerCompact components
- Replace all ProgressView() with themed spinners throughout app
- Fix sport selection state not persisting when navigating away

Bug Fixes:
- Fix Coast to Coast trips showing only 1 city (validation issue)
- Fix stadium progress showing 0/0 (filtering issue)
- Remove "Stadium Quest" title from progress view

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 20:20:03 -06:00

406 lines
15 KiB
Python

#!/usr/bin/env python3
"""
Generate Canonical Data for SportsTime App
==========================================
Generates team_aliases.json and league_structure.json from team mappings.
Usage:
python generate_canonical_data.py
python generate_canonical_data.py --output ./data
"""
import argparse
import json
from datetime import datetime
from pathlib import Path
# =============================================================================
# LEAGUE STRUCTURE
# =============================================================================
MLB_STRUCTURE = {
"leagues": [
{"id": "mlb_al", "name": "American League", "abbreviation": "AL"},
{"id": "mlb_nl", "name": "National League", "abbreviation": "NL"},
],
"divisions": [
# American League
{"id": "mlb_al_east", "name": "AL East", "parent_id": "mlb_al", "teams": ["NYY", "BOS", "TOR", "BAL", "TBR"]},
{"id": "mlb_al_central", "name": "AL Central", "parent_id": "mlb_al", "teams": ["CLE", "DET", "MIN", "CHW", "KCR"]},
{"id": "mlb_al_west", "name": "AL West", "parent_id": "mlb_al", "teams": ["HOU", "SEA", "TEX", "LAA", "OAK"]},
# National League
{"id": "mlb_nl_east", "name": "NL East", "parent_id": "mlb_nl", "teams": ["ATL", "PHI", "NYM", "MIA", "WSN"]},
{"id": "mlb_nl_central", "name": "NL Central", "parent_id": "mlb_nl", "teams": ["MIL", "CHC", "STL", "PIT", "CIN"]},
{"id": "mlb_nl_west", "name": "NL West", "parent_id": "mlb_nl", "teams": ["LAD", "ARI", "SDP", "SFG", "COL"]},
]
}
NBA_STRUCTURE = {
"conferences": [
{"id": "nba_eastern", "name": "Eastern Conference", "abbreviation": "East"},
{"id": "nba_western", "name": "Western Conference", "abbreviation": "West"},
],
"divisions": [
# Eastern Conference
{"id": "nba_atlantic", "name": "Atlantic", "parent_id": "nba_eastern", "teams": ["BOS", "BRK", "NYK", "PHI", "TOR"]},
{"id": "nba_central", "name": "Central", "parent_id": "nba_eastern", "teams": ["CHI", "CLE", "DET", "IND", "MIL"]},
{"id": "nba_southeast", "name": "Southeast", "parent_id": "nba_eastern", "teams": ["ATL", "CHO", "MIA", "ORL", "WAS"]},
# Western Conference
{"id": "nba_northwest", "name": "Northwest", "parent_id": "nba_western", "teams": ["DEN", "MIN", "OKC", "POR", "UTA"]},
{"id": "nba_pacific", "name": "Pacific", "parent_id": "nba_western", "teams": ["GSW", "LAC", "LAL", "PHO", "SAC"]},
{"id": "nba_southwest", "name": "Southwest", "parent_id": "nba_western", "teams": ["DAL", "HOU", "MEM", "NOP", "SAS"]},
]
}
NHL_STRUCTURE = {
"conferences": [
{"id": "nhl_eastern", "name": "Eastern Conference", "abbreviation": "East"},
{"id": "nhl_western", "name": "Western Conference", "abbreviation": "West"},
],
"divisions": [
# Eastern Conference
{"id": "nhl_atlantic", "name": "Atlantic", "parent_id": "nhl_eastern", "teams": ["BOS", "BUF", "DET", "FLA", "MTL", "OTT", "TBL", "TOR"]},
{"id": "nhl_metropolitan", "name": "Metropolitan", "parent_id": "nhl_eastern", "teams": ["CAR", "CBJ", "NJD", "NYI", "NYR", "PHI", "PIT", "WSH"]},
# Western Conference
{"id": "nhl_central", "name": "Central", "parent_id": "nhl_western", "teams": ["ARI", "CHI", "COL", "DAL", "MIN", "NSH", "STL", "WPG"]},
{"id": "nhl_pacific", "name": "Pacific", "parent_id": "nhl_western", "teams": ["ANA", "CGY", "EDM", "LAK", "SEA", "SJS", "VAN", "VGK"]},
]
}
# =============================================================================
# TEAM ALIASES (Historical name changes, relocations, abbreviation changes)
# =============================================================================
# Format: {current_abbrev: [(alias_type, alias_value, valid_from, valid_until), ...]}
MLB_ALIASES = {
# Washington Nationals (formerly Montreal Expos)
"WSN": [
("name", "Montreal Expos", "1969-01-01", "2004-12-31"),
("abbreviation", "MON", "1969-01-01", "2004-12-31"),
("city", "Montreal", "1969-01-01", "2004-12-31"),
],
# Oakland Athletics (moving to Sacramento, formerly in Kansas City and Philadelphia)
"OAK": [
("name", "Kansas City Athletics", "1955-01-01", "1967-12-31"),
("abbreviation", "KCA", "1955-01-01", "1967-12-31"),
("city", "Kansas City", "1955-01-01", "1967-12-31"),
("name", "Philadelphia Athletics", "1901-01-01", "1954-12-31"),
("abbreviation", "PHA", "1901-01-01", "1954-12-31"),
("city", "Philadelphia", "1901-01-01", "1954-12-31"),
],
# Cleveland Guardians (formerly Indians)
"CLE": [
("name", "Cleveland Indians", "1915-01-01", "2021-12-31"),
],
# Tampa Bay Rays (formerly Devil Rays)
"TBR": [
("name", "Tampa Bay Devil Rays", "1998-01-01", "2007-12-31"),
],
# Miami Marlins (formerly Florida Marlins)
"MIA": [
("name", "Florida Marlins", "1993-01-01", "2011-12-31"),
("city", "Florida", "1993-01-01", "2011-12-31"),
],
# Los Angeles Angels (various names)
"LAA": [
("name", "Anaheim Angels", "1997-01-01", "2004-12-31"),
("name", "Los Angeles Angels of Anaheim", "2005-01-01", "2015-12-31"),
("name", "California Angels", "1965-01-01", "1996-12-31"),
],
# Texas Rangers (formerly Washington Senators II)
"TEX": [
("name", "Washington Senators", "1961-01-01", "1971-12-31"),
("abbreviation", "WS2", "1961-01-01", "1971-12-31"),
("city", "Washington", "1961-01-01", "1971-12-31"),
],
# Milwaukee Brewers (briefly Seattle Pilots)
"MIL": [
("name", "Seattle Pilots", "1969-01-01", "1969-12-31"),
("abbreviation", "SEP", "1969-01-01", "1969-12-31"),
("city", "Seattle", "1969-01-01", "1969-12-31"),
],
# Houston Astros (formerly Colt .45s)
"HOU": [
("name", "Houston Colt .45s", "1962-01-01", "1964-12-31"),
],
}
NBA_ALIASES = {
# Brooklyn Nets (formerly New Jersey Nets, New York Nets)
"BRK": [
("name", "New Jersey Nets", "1977-01-01", "2012-04-30"),
("abbreviation", "NJN", "1977-01-01", "2012-04-30"),
("city", "New Jersey", "1977-01-01", "2012-04-30"),
("name", "New York Nets", "1968-01-01", "1977-12-31"),
],
# Oklahoma City Thunder (formerly Seattle SuperSonics)
"OKC": [
("name", "Seattle SuperSonics", "1967-01-01", "2008-07-01"),
("abbreviation", "SEA", "1967-01-01", "2008-07-01"),
("city", "Seattle", "1967-01-01", "2008-07-01"),
],
# Memphis Grizzlies (formerly Vancouver Grizzlies)
"MEM": [
("name", "Vancouver Grizzlies", "1995-01-01", "2001-05-31"),
("abbreviation", "VAN", "1995-01-01", "2001-05-31"),
("city", "Vancouver", "1995-01-01", "2001-05-31"),
],
# New Orleans Pelicans (formerly Hornets, formerly Charlotte Hornets original)
"NOP": [
("name", "New Orleans Hornets", "2002-01-01", "2013-04-30"),
("abbreviation", "NOH", "2002-01-01", "2013-04-30"),
("name", "New Orleans/Oklahoma City Hornets", "2005-01-01", "2007-12-31"),
],
# Charlotte Hornets (current, formerly Bobcats)
"CHO": [
("name", "Charlotte Bobcats", "2004-01-01", "2014-04-30"),
("abbreviation", "CHA", "2004-01-01", "2014-04-30"),
],
# Washington Wizards (formerly Bullets)
"WAS": [
("name", "Washington Bullets", "1974-01-01", "1997-05-31"),
("name", "Capital Bullets", "1973-01-01", "1973-12-31"),
("name", "Baltimore Bullets", "1963-01-01", "1972-12-31"),
],
# Los Angeles Clippers (formerly San Diego, Buffalo)
"LAC": [
("name", "San Diego Clippers", "1978-01-01", "1984-05-31"),
("abbreviation", "SDC", "1978-01-01", "1984-05-31"),
("city", "San Diego", "1978-01-01", "1984-05-31"),
("name", "Buffalo Braves", "1970-01-01", "1978-05-31"),
("abbreviation", "BUF", "1970-01-01", "1978-05-31"),
("city", "Buffalo", "1970-01-01", "1978-05-31"),
],
# Sacramento Kings (formerly Kansas City Kings, etc.)
"SAC": [
("name", "Kansas City Kings", "1975-01-01", "1985-05-31"),
("abbreviation", "KCK", "1975-01-01", "1985-05-31"),
("city", "Kansas City", "1975-01-01", "1985-05-31"),
],
# Utah Jazz (formerly New Orleans Jazz)
"UTA": [
("name", "New Orleans Jazz", "1974-01-01", "1979-05-31"),
("city", "New Orleans", "1974-01-01", "1979-05-31"),
],
}
NHL_ALIASES = {
# Arizona/Utah Hockey Club (formerly Phoenix Coyotes, originally Winnipeg Jets)
"ARI": [
("name", "Arizona Coyotes", "2014-01-01", "2024-04-30"),
("name", "Phoenix Coyotes", "1996-01-01", "2013-12-31"),
("abbreviation", "PHX", "1996-01-01", "2013-12-31"),
("city", "Phoenix", "1996-01-01", "2013-12-31"),
("name", "Winnipeg Jets", "1979-01-01", "1996-05-31"), # Original Jets
],
# Carolina Hurricanes (formerly Hartford Whalers)
"CAR": [
("name", "Hartford Whalers", "1979-01-01", "1997-05-31"),
("abbreviation", "HFD", "1979-01-01", "1997-05-31"),
("city", "Hartford", "1979-01-01", "1997-05-31"),
],
# Colorado Avalanche (formerly Quebec Nordiques)
"COL": [
("name", "Quebec Nordiques", "1979-01-01", "1995-05-31"),
("abbreviation", "QUE", "1979-01-01", "1995-05-31"),
("city", "Quebec", "1979-01-01", "1995-05-31"),
],
# Dallas Stars (formerly Minnesota North Stars)
"DAL": [
("name", "Minnesota North Stars", "1967-01-01", "1993-05-31"),
("abbreviation", "MNS", "1967-01-01", "1993-05-31"),
("city", "Minnesota", "1967-01-01", "1993-05-31"),
],
# New Jersey Devils (formerly Kansas City Scouts, Colorado Rockies)
"NJD": [
("name", "Colorado Rockies", "1976-01-01", "1982-05-31"),
("abbreviation", "CLR", "1976-01-01", "1982-05-31"),
("city", "Colorado", "1976-01-01", "1982-05-31"),
("name", "Kansas City Scouts", "1974-01-01", "1976-05-31"),
("abbreviation", "KCS", "1974-01-01", "1976-05-31"),
("city", "Kansas City", "1974-01-01", "1976-05-31"),
],
# Winnipeg Jets (current, formerly Atlanta Thrashers)
"WPG": [
("name", "Atlanta Thrashers", "1999-01-01", "2011-05-31"),
("abbreviation", "ATL", "1999-01-01", "2011-05-31"),
("city", "Atlanta", "1999-01-01", "2011-05-31"),
],
# Florida Panthers (originally in Miami)
"FLA": [
("city", "Miami", "1993-01-01", "1998-12-31"),
],
# Vegas Golden Knights (no aliases, expansion team)
# Seattle Kraken (no aliases, expansion team)
}
def generate_league_structure() -> list[dict]:
"""Generate league_structure.json data."""
structures = []
order = 0
# MLB
structures.append({
"id": "mlb_league",
"sport": "MLB",
"type": "league",
"name": "Major League Baseball",
"abbreviation": "MLB",
"parent_id": None,
"display_order": order,
})
order += 1
for league in MLB_STRUCTURE["leagues"]:
structures.append({
"id": league["id"],
"sport": "MLB",
"type": "conference", # AL/NL are like conferences
"name": league["name"],
"abbreviation": league["abbreviation"],
"parent_id": "mlb_league",
"display_order": order,
})
order += 1
for div in MLB_STRUCTURE["divisions"]:
structures.append({
"id": div["id"],
"sport": "MLB",
"type": "division",
"name": div["name"],
"abbreviation": None,
"parent_id": div["parent_id"],
"display_order": order,
})
order += 1
# NBA
structures.append({
"id": "nba_league",
"sport": "NBA",
"type": "league",
"name": "National Basketball Association",
"abbreviation": "NBA",
"parent_id": None,
"display_order": order,
})
order += 1
for conf in NBA_STRUCTURE["conferences"]:
structures.append({
"id": conf["id"],
"sport": "NBA",
"type": "conference",
"name": conf["name"],
"abbreviation": conf["abbreviation"],
"parent_id": "nba_league",
"display_order": order,
})
order += 1
for div in NBA_STRUCTURE["divisions"]:
structures.append({
"id": div["id"],
"sport": "NBA",
"type": "division",
"name": div["name"],
"abbreviation": None,
"parent_id": div["parent_id"],
"display_order": order,
})
order += 1
# NHL
structures.append({
"id": "nhl_league",
"sport": "NHL",
"type": "league",
"name": "National Hockey League",
"abbreviation": "NHL",
"parent_id": None,
"display_order": order,
})
order += 1
for conf in NHL_STRUCTURE["conferences"]:
structures.append({
"id": conf["id"],
"sport": "NHL",
"type": "conference",
"name": conf["name"],
"abbreviation": conf["abbreviation"],
"parent_id": "nhl_league",
"display_order": order,
})
order += 1
for div in NHL_STRUCTURE["divisions"]:
structures.append({
"id": div["id"],
"sport": "NHL",
"type": "division",
"name": div["name"],
"abbreviation": None,
"parent_id": div["parent_id"],
"display_order": order,
})
order += 1
return structures
def generate_team_aliases() -> list[dict]:
"""Generate team_aliases.json data."""
aliases = []
alias_id = 1
for sport, sport_aliases in [("MLB", MLB_ALIASES), ("NBA", NBA_ALIASES), ("NHL", NHL_ALIASES)]:
for current_abbrev, alias_list in sport_aliases.items():
team_canonical_id = f"team_{sport.lower()}_{current_abbrev.lower()}"
for alias_type, alias_value, valid_from, valid_until in alias_list:
aliases.append({
"id": f"alias_{sport.lower()}_{alias_id}",
"team_canonical_id": team_canonical_id,
"alias_type": alias_type,
"alias_value": alias_value,
"valid_from": valid_from,
"valid_until": valid_until,
})
alias_id += 1
return aliases
def main():
parser = argparse.ArgumentParser(description='Generate canonical data JSON files')
parser.add_argument('--output', type=str, default='./data', help='Output directory')
args = parser.parse_args()
output_dir = Path(args.output)
output_dir.mkdir(parents=True, exist_ok=True)
# Generate league structure
print("Generating league_structure.json...")
league_structure = generate_league_structure()
with open(output_dir / 'league_structure.json', 'w') as f:
json.dump(league_structure, f, indent=2)
print(f" Created {len(league_structure)} structure entries")
# Generate team aliases
print("Generating team_aliases.json...")
team_aliases = generate_team_aliases()
with open(output_dir / 'team_aliases.json', 'w') as f:
json.dump(team_aliases, f, indent=2)
print(f" Created {len(team_aliases)} alias entries")
print(f"\nFiles written to {output_dir}")
if __name__ == '__main__':
main()