""" Pydantic models for the source finding module. Contains data models for representing game search results and metadata. """ from typing import Optional from pydantic import BaseModel, Field class GameResult(BaseModel): """ Represents a single college football game found on nfl-video.com. Attributes: title: Full title from the website, e.g. "Ohio State vs Oregon Football 2024 Big Ten Championship Full Game Replay" team_a: First team name parsed from the title (appears before "vs") team_b: Second team name parsed from the title (appears after "vs") url: Full URL to the game's page on nfl-video.com thumbnail_url: URL to the game's thumbnail image, if available date_str: Date string parsed from the page, e.g. "January 8, 2024" event: Event name parsed from the title, e.g. "CFP National Championship", "Big Ten Championship" year: Year of the game, parsed from the title """ title: str = Field(..., description="Full title of the game from the website") team_a: str = Field(..., description="First team name (before 'vs')") team_b: str = Field(..., description="Second team name (after 'vs')") url: str = Field(..., description="Full URL to the game page") thumbnail_url: Optional[str] = Field(default=None, description="URL to thumbnail image") date_str: Optional[str] = Field(default=None, description="Date string, e.g. 'January 8, 2024'") event: Optional[str] = Field(default=None, description="Event name, e.g. 'CFP National Championship'") year: Optional[int] = Field(default=None, description="Year of the game") def __str__(self) -> str: """Human-readable representation of the game.""" event_str = f" ({self.event})" if self.event else "" date_str = f" - {self.date_str}" if self.date_str else "" return f"{self.team_a} vs {self.team_b}{event_str}{date_str}" def get_filename_base(self) -> str: """ Generate a safe filename base for this game (without extension). Returns: A filename-safe string like "Ohio_State_vs_Oregon_2024" """ # Replace spaces with underscores and remove special characters # pylint: disable=no-member # False positive: Pydantic fields are strings at runtime team_a_safe = self.team_a.replace(" ", "_").replace("(", "").replace(")", "") team_b_safe = self.team_b.replace(" ", "_").replace("(", "").replace(")", "") year_str = f"_{self.year}" if self.year else "" return f"{team_a_safe}_vs_{team_b_safe}{year_str}" class SearchResults(BaseModel): """ Results from searching for games on nfl-video.com. Attributes: query_team_a: The team name that was searched for (required) query_team_b: Optional second team name that was searched for games: List of matching GameResult objects pages_searched: Number of pages that were searched total_games_scanned: Total number of games scanned across all pages """ query_team_a: str = Field(..., description="Primary team name searched for") query_team_b: Optional[str] = Field(default=None, description="Optional second team name searched for") games: list[GameResult] = Field(default_factory=list, description="List of matching games found") pages_searched: int = Field(default=0, description="Number of pages searched") total_games_scanned: int = Field(default=0, description="Total games scanned across all pages") def __str__(self) -> str: """Human-readable summary of search results.""" team_str = self.query_team_a if self.query_team_b: team_str += f" vs {self.query_team_b}" return f"Search for '{team_str}': {len(self.games)} games found (scanned {self.total_games_scanned} across {self.pages_searched} pages)"