This commit is contained in:
Trey t
2026-01-20 11:16:20 -06:00
parent 11adfc10dd
commit fbfdf136ae
15 changed files with 539 additions and 97064 deletions

View File

@@ -11,6 +11,15 @@ from .aliases import (
FuzzyMatch,
ManualReviewItem,
)
from .sport import (
Sport,
LeagueStructure,
LeagueStructureType,
save_sports,
load_sports,
save_league_structures,
load_league_structures,
)
__all__ = [
# Game
@@ -32,4 +41,12 @@ __all__ = [
"StadiumAlias",
"FuzzyMatch",
"ManualReviewItem",
# Sport and League Structure
"Sport",
"LeagueStructure",
"LeagueStructureType",
"save_sports",
"load_sports",
"save_league_structures",
"load_league_structures",
]

View File

@@ -0,0 +1,157 @@
"""Sport and LeagueStructure data models for sportstime-parser."""
from dataclasses import dataclass
from enum import Enum
from typing import Optional
import json
class LeagueStructureType(str, Enum):
"""Type of league structure element."""
CONFERENCE = "conference"
DIVISION = "division"
LEAGUE = "league"
@dataclass
class Sport:
"""Represents a sport with all CloudKit fields.
Attributes:
id: Canonical sport ID (e.g., 'MLB', 'NBA')
abbreviation: Sport abbreviation (e.g., 'MLB', 'NBA')
display_name: Full display name (e.g., 'Major League Baseball')
icon_name: SF Symbol name for the sport icon
color_hex: Primary color as hex string (e.g., '#FF0000')
season_start_month: Month number when season typically starts (1-12)
season_end_month: Month number when season typically ends (1-12)
is_active: Whether the sport is currently active/supported
"""
id: str
abbreviation: str
display_name: str
icon_name: str
color_hex: str
season_start_month: int
season_end_month: int
is_active: bool = True
def to_dict(self) -> dict:
"""Convert to dictionary for JSON serialization."""
return {
"id": self.id,
"abbreviation": self.abbreviation,
"display_name": self.display_name,
"icon_name": self.icon_name,
"color_hex": self.color_hex,
"season_start_month": self.season_start_month,
"season_end_month": self.season_end_month,
"is_active": self.is_active,
}
@classmethod
def from_dict(cls, data: dict) -> "Sport":
"""Create a Sport from a dictionary."""
return cls(
id=data["id"],
abbreviation=data["abbreviation"],
display_name=data["display_name"],
icon_name=data["icon_name"],
color_hex=data["color_hex"],
season_start_month=data["season_start_month"],
season_end_month=data["season_end_month"],
is_active=data.get("is_active", True),
)
def to_json(self) -> str:
"""Serialize to JSON string."""
return json.dumps(self.to_dict(), indent=2)
@classmethod
def from_json(cls, json_str: str) -> "Sport":
"""Deserialize from JSON string."""
return cls.from_dict(json.loads(json_str))
@dataclass
class LeagueStructure:
"""Represents a league structure element (conference, division, etc.).
Attributes:
id: Unique ID (e.g., 'nba_eastern', 'mlb_al_east')
sport: Sport code (e.g., 'NBA', 'MLB')
structure_type: Type of structure (conference, division, league)
name: Full name (e.g., 'Eastern Conference', 'AL East')
abbreviation: Optional abbreviation (e.g., 'East', 'ALE')
parent_id: Parent structure ID (e.g., division's parent is conference)
display_order: Order for display (0-indexed)
"""
id: str
sport: str
structure_type: LeagueStructureType
name: str
abbreviation: Optional[str] = None
parent_id: Optional[str] = None
display_order: int = 0
def to_dict(self) -> dict:
"""Convert to dictionary for JSON serialization."""
return {
"id": self.id,
"sport": self.sport,
"structure_type": self.structure_type.value,
"name": self.name,
"abbreviation": self.abbreviation,
"parent_id": self.parent_id,
"display_order": self.display_order,
}
@classmethod
def from_dict(cls, data: dict) -> "LeagueStructure":
"""Create a LeagueStructure from a dictionary."""
return cls(
id=data["id"],
sport=data["sport"],
structure_type=LeagueStructureType(data["structure_type"]),
name=data["name"],
abbreviation=data.get("abbreviation"),
parent_id=data.get("parent_id"),
display_order=data.get("display_order", 0),
)
def to_json(self) -> str:
"""Serialize to JSON string."""
return json.dumps(self.to_dict(), indent=2)
@classmethod
def from_json(cls, json_str: str) -> "LeagueStructure":
"""Deserialize from JSON string."""
return cls.from_dict(json.loads(json_str))
def save_sports(sports: list[Sport], filepath: str) -> None:
"""Save a list of sports to a JSON file."""
with open(filepath, "w", encoding="utf-8") as f:
json.dump([s.to_dict() for s in sports], f, indent=2)
def load_sports(filepath: str) -> list[Sport]:
"""Load a list of sports from a JSON file."""
with open(filepath, "r", encoding="utf-8") as f:
data = json.load(f)
return [Sport.from_dict(d) for d in data]
def save_league_structures(structures: list[LeagueStructure], filepath: str) -> None:
"""Save a list of league structures to a JSON file."""
with open(filepath, "w", encoding="utf-8") as f:
json.dump([s.to_dict() for s in structures], f, indent=2)
def load_league_structures(filepath: str) -> list[LeagueStructure]:
"""Load a list of league structures from a JSON file."""
with open(filepath, "r", encoding="utf-8") as f:
data = json.load(f)
return [LeagueStructure.from_dict(d) for d in data]