--- phase: 01-script-architecture plan: 02 type: execute --- Extract NBA and NHL scrapers to dedicated sport modules. Purpose: Continue the modular pattern established in Plan 01. Output: `Scripts/nba.py` and `Scripts/nhl.py` with respective scrapers. @~/.claude/get-shit-done/workflows/execute-phase.md @~/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md **Prior work:** @.planning/phases/01-script-architecture/01-01-SUMMARY.md **Source files:** @Scripts/core.py @Scripts/scrape_schedules.py Task 1: Create nba.py sport module Scripts/nba.py Create `Scripts/nba.py` following the mlb.py pattern: 1. Import from core: ```python from core import Game, Stadium, ScraperSource, StadiumScraperSource, fetch_page, scrape_with_fallback, scrape_stadiums_with_fallback ``` 2. NBA game scrapers: - `scrape_nba_basketball_reference(season: int) -> list[Game]` - `scrape_nba_espn(season: int) -> list[Game]` - `scrape_nba_cbssports(season: int) -> list[Game]` 3. NBA stadium scrapers: - `scrape_nba_stadiums() -> list[Stadium]` (from generate_stadiums_from_teams or hardcoded) 4. Source configurations: - `NBA_GAME_SOURCES` list of ScraperSource - `NBA_STADIUM_SOURCES` list of StadiumScraperSource 5. Convenience functions: - `scrape_nba_games(season: int) -> list[Game]` - `get_nba_season_string(season: int) -> str` - returns "2024-25" format Copy exact parsing logic including team abbreviations and venue mappings from scrape_schedules.py. python3 -c "from Scripts.nba import scrape_nba_games, NBA_GAME_SOURCES; print('OK')" nba.py exists, imports from core.py, exports NBA scrapers Task 2: Create nhl.py sport module Scripts/nhl.py Create `Scripts/nhl.py` following the same pattern: 1. Import from core: ```python from core import Game, Stadium, ScraperSource, StadiumScraperSource, fetch_page, scrape_with_fallback, scrape_stadiums_with_fallback ``` 2. NHL game scrapers: - `scrape_nhl_hockey_reference(season: int) -> list[Game]` - `scrape_nhl_api(season: int) -> list[Game]` - `scrape_nhl_espn(season: int) -> list[Game]` 3. NHL stadium scrapers: - `scrape_nhl_stadiums() -> list[Stadium]` 4. Source configurations: - `NHL_GAME_SOURCES` list of ScraperSource - `NHL_STADIUM_SOURCES` list of StadiumScraperSource 5. Convenience functions: - `scrape_nhl_games(season: int) -> list[Game]` - `get_nhl_season_string(season: int) -> str` - returns "2024-25" format Copy exact parsing logic from scrape_schedules.py. python3 -c "from Scripts.nhl import scrape_nhl_games, NHL_GAME_SOURCES; print('OK')" nhl.py exists, imports from core.py, exports NHL scrapers Before declaring plan complete: - [ ] `Scripts/nba.py` exists and imports cleanly - [ ] `Scripts/nhl.py` exists and imports cleanly - [ ] No syntax errors: `python3 -m py_compile Scripts/nba.py Scripts/nhl.py` - [ ] Both import from core.py (not duplicating shared utilities) - nba.py contains all NBA-specific scrapers - nhl.py contains all NHL-specific scrapers - Both follow the pattern established in mlb.py - All files import without errors After completion, create `.planning/phases/01-script-architecture/01-02-SUMMARY.md`