wip
This commit is contained in:
157
Scripts/sportstime_parser/models/sport.py
Normal file
157
Scripts/sportstime_parser/models/sport.py
Normal 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]
|
||||
Reference in New Issue
Block a user