"""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]