andytaylor-smg's picture
simple request
4f9adc4
"""
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)"