158 lines
5.2 KiB
Python
158 lines
5.2 KiB
Python
"""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]
|