mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
cursor rules (#87)
This commit is contained in:
38
.cursor/rules/coding-standards.mdc
Normal file
38
.cursor/rules/coding-standards.mdc
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
globs: *.py
|
||||||
|
---
|
||||||
|
|
||||||
|
# Python Coding Standards
|
||||||
|
|
||||||
|
## Code Quality Principles
|
||||||
|
- **Simplicity First**: Prefer clear, readable code over clever optimizations
|
||||||
|
- **Explicit over Implicit**: Make intentions clear through naming and structure
|
||||||
|
- **Fail Fast**: Validate inputs and handle errors early
|
||||||
|
- **Documentation**: Use docstrings for classes and complex functions
|
||||||
|
|
||||||
|
## Naming Conventions
|
||||||
|
- **Classes**: PascalCase (e.g., `NHLRecentManager`)
|
||||||
|
- **Functions/Variables**: snake_case (e.g., `fetch_game_data`)
|
||||||
|
- **Constants**: UPPER_SNAKE_CASE (e.g., `ESPN_NHL_SCOREBOARD_URL`)
|
||||||
|
- **Private methods**: Leading underscore (e.g., `_fetch_data`)
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
- **Logging**: Use structured logging with context (e.g., `[NHL Recent]`)
|
||||||
|
- **Exceptions**: Catch specific exceptions, not bare `except:`
|
||||||
|
- **User-friendly messages**: Explain what went wrong and potential solutions
|
||||||
|
- **Graceful degradation**: Continue operation when non-critical features fail
|
||||||
|
|
||||||
|
## Manager Pattern
|
||||||
|
All sports managers should follow this structure:
|
||||||
|
```python
|
||||||
|
class BaseManager:
|
||||||
|
def __init__(self, config, display_manager, cache_manager)
|
||||||
|
def update(self) # Fetch and process data
|
||||||
|
def display(self, force_clear=False) # Render to display
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Management
|
||||||
|
- **Type hints**: Use for function parameters and return values
|
||||||
|
- **Configuration validation**: Check required fields on initialization
|
||||||
|
- **Default values**: Provide sensible defaults in code, not config
|
||||||
|
- **Environment awareness**: Handle different deployment contexts
|
||||||
42
.cursor/rules/configuration-management.mdc
Normal file
42
.cursor/rules/configuration-management.mdc
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
globs: config/*.json,src/*.py
|
||||||
|
---
|
||||||
|
|
||||||
|
# Configuration Management
|
||||||
|
|
||||||
|
## Configuration Structure
|
||||||
|
- **Main config**: [config/config.json](mdc:config/config.json) - Primary configuration
|
||||||
|
- **Secrets**: [config/config_secrets.json](mdc:config/config_secrets.json) - API keys and sensitive data
|
||||||
|
- **Templates**: [config/config.template.json](mdc:config/config.template.json) - Default values
|
||||||
|
|
||||||
|
## Configuration Principles
|
||||||
|
- **Validation**: Check required fields and data types on startup
|
||||||
|
- **Defaults**: Provide sensible defaults in code, not just config
|
||||||
|
- **Environment awareness**: Handle development vs production differences
|
||||||
|
- **Security**: Never commit secrets to version control
|
||||||
|
|
||||||
|
## Manager Configuration Pattern
|
||||||
|
```python
|
||||||
|
def __init__(self, config, display_manager, cache_manager):
|
||||||
|
self.mode_config = config.get("sport_scoreboard", {})
|
||||||
|
self.favorite_teams = self.mode_config.get("favorite_teams", [])
|
||||||
|
self.show_favorite_only = self.mode_config.get("show_favorite_teams_only", False)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Required Configuration Sections
|
||||||
|
- **Display settings**: Update intervals, display durations
|
||||||
|
- **API settings**: Timeouts, retry logic, rate limiting
|
||||||
|
- **Background service**: Threading, caching, priority settings
|
||||||
|
- **Team preferences**: Favorite teams, filtering options
|
||||||
|
|
||||||
|
## Configuration Validation
|
||||||
|
- **Type checking**: Ensure numeric values are numbers, lists are lists
|
||||||
|
- **Range validation**: Check that intervals are reasonable
|
||||||
|
- **Dependency checking**: Verify required services are available
|
||||||
|
- **Fallback values**: Provide defaults when config is missing or invalid
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
- **Documentation**: Comment complex configuration options
|
||||||
|
- **Examples**: Provide working examples in templates
|
||||||
|
- **Migration**: Handle configuration changes between versions
|
||||||
|
- **Testing**: Validate configuration in test environments
|
||||||
50
.cursor/rules/error-handling-logging.mdc
Normal file
50
.cursor/rules/error-handling-logging.mdc
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
globs: src/*.py
|
||||||
|
---
|
||||||
|
|
||||||
|
# Error Handling and Logging
|
||||||
|
|
||||||
|
## Logging Standards
|
||||||
|
- **Structured prefixes**: Use consistent tags like `[NHL Recent]`, `[NFL Live]`
|
||||||
|
- **Context information**: Include relevant details (team names, game status, dates)
|
||||||
|
- **Appropriate levels**:
|
||||||
|
- `info`: Normal operations and status updates
|
||||||
|
- `debug`: Detailed information for troubleshooting
|
||||||
|
- `warning`: Non-critical issues that should be noted
|
||||||
|
- `error`: Problems that need attention
|
||||||
|
|
||||||
|
## Error Handling Patterns
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
data = self._fetch_data()
|
||||||
|
if not data or 'events' not in data:
|
||||||
|
self.logger.warning("[Manager] No events found in API response")
|
||||||
|
return
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
self.logger.error(f"[Manager] API error: {e}")
|
||||||
|
return None
|
||||||
|
```
|
||||||
|
|
||||||
|
## User-Friendly Messages
|
||||||
|
- **Explain the situation**: "No games available during off-season"
|
||||||
|
- **Provide context**: "NHL season typically runs October-June"
|
||||||
|
- **Suggest solutions**: "Check back when season starts"
|
||||||
|
- **Distinguish issues**: API problems vs no data vs filtering results
|
||||||
|
|
||||||
|
## Graceful Degradation
|
||||||
|
- **Fallback content**: Show alternative games when favorites unavailable
|
||||||
|
- **Cached data**: Use cached data when API fails
|
||||||
|
- **Service continuity**: Continue operation when non-critical features fail
|
||||||
|
- **Clear communication**: Explain what's happening to users
|
||||||
|
|
||||||
|
## Debugging Support
|
||||||
|
- **Comprehensive logging**: Log API responses, filtering results, display updates
|
||||||
|
- **State tracking**: Log current state and transitions
|
||||||
|
- **Performance monitoring**: Track timing and resource usage
|
||||||
|
- **Error context**: Include stack traces for debugging
|
||||||
|
|
||||||
|
## Off-Season Awareness
|
||||||
|
- **Seasonal messaging**: Different messages for different times of year
|
||||||
|
- **Helpful context**: Explain why no games are available
|
||||||
|
- **Future planning**: Mention when season starts
|
||||||
|
- **Realistic expectations**: Set appropriate expectations during off-season
|
||||||
51
.cursor/rules/git-workflow.mdc
Normal file
51
.cursor/rules/git-workflow.mdc
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Git Workflow and Branching
|
||||||
|
|
||||||
|
## Branch Naming Conventions
|
||||||
|
- **Features**: `feature/description-of-feature` (e.g., `feature/weather-forecast-improvements`)
|
||||||
|
- **Bug fixes**: `fix/description-of-bug` (e.g., `fix/nhl-manager-improvements`)
|
||||||
|
- **Hotfixes**: `hotfix/critical-issue-description`
|
||||||
|
- **Refactoring**: `refactor/description-of-refactor`
|
||||||
|
|
||||||
|
## Commit Message Format
|
||||||
|
```
|
||||||
|
type(scope): description
|
||||||
|
|
||||||
|
[optional body]
|
||||||
|
|
||||||
|
[optional footer]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Types**: feat, fix, docs, style, refactor, test, chore
|
||||||
|
**Examples**:
|
||||||
|
- `feat(nhl): Add enhanced logging for data visibility`
|
||||||
|
- `fix(display): Resolve rendering performance issue`
|
||||||
|
- `docs(api): Update ESPN API integration guide`
|
||||||
|
|
||||||
|
## Pull Request Guidelines
|
||||||
|
- **Self-review**: Review your own PR before requesting review
|
||||||
|
- **Testing**: Test thoroughly on Raspberry Pi hardware
|
||||||
|
- **Documentation**: Update relevant documentation if needed
|
||||||
|
- **Clean history**: Squash commits if necessary for clean history
|
||||||
|
|
||||||
|
## Code Review Checklist
|
||||||
|
- **Code Quality**: Proper error handling, logging, type hints
|
||||||
|
- **Architecture**: Follows project patterns, doesn't break existing functionality
|
||||||
|
- **Performance**: No negative impact on display performance
|
||||||
|
- **Testing**: Works on Raspberry Pi hardware
|
||||||
|
- **Documentation**: Comments added for complex logic
|
||||||
|
|
||||||
|
## Merge Strategies
|
||||||
|
- **Squash and Merge**: Preferred for feature branches and bug fixes
|
||||||
|
- **Merge Commit**: For complex features with multiple logical commits
|
||||||
|
- **Rebase and Merge**: For simple, single-commit changes
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
- **Keep branches small and focused**
|
||||||
|
- **Commit frequently with meaningful messages**
|
||||||
|
- **Update branch regularly with main**
|
||||||
|
- **Test changes incrementally**
|
||||||
|
- **Delete feature branches after merge**
|
||||||
23
.cursor/rules/project-structure.mdc
Normal file
23
.cursor/rules/project-structure.mdc
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# LEDMatrix Project Structure
|
||||||
|
|
||||||
|
## Core Architecture
|
||||||
|
- **Main entry point**: [run.py](mdc:run.py) - Primary application launcher
|
||||||
|
- **Configuration**: [config/config.json](mdc:config/config.json) - Main configuration file
|
||||||
|
- **Display management**: [src/display_controller.py](mdc:src/display_controller.py) - Core display logic
|
||||||
|
- **Web interface**: [web_interface_v2.py](mdc:web_interface_v2.py) - Modern web UI
|
||||||
|
|
||||||
|
## Source Code Organization
|
||||||
|
- **Managers**: [src/](mdc:src/) - All sports/weather/stock managers
|
||||||
|
- **Assets**: [assets/](mdc:assets/) - Logos, fonts, and static resources
|
||||||
|
- **Tests**: [test/](mdc:test/) - Unit and integration tests
|
||||||
|
- **Documentation**: [LEDMatrix.wiki/](mdc:LEDMatrix.wiki/) - Comprehensive guides
|
||||||
|
|
||||||
|
## Key Design Principles
|
||||||
|
- **Single Responsibility**: Each manager handles one sport/domain
|
||||||
|
- **Consistent Patterns**: All managers follow similar structure
|
||||||
|
- **Configuration-Driven**: Behavior controlled via [config/config.json](mdc:config/config.json)
|
||||||
|
- **Raspberry Pi Focus**: Optimized for Pi hardware, not Windows development
|
||||||
41
.cursor/rules/raspberry-pi-development.mdc
Normal file
41
.cursor/rules/raspberry-pi-development.mdc
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Raspberry Pi Development Guidelines
|
||||||
|
|
||||||
|
## Hardware Constraints
|
||||||
|
- **Pi-only execution**: Code must run on Raspberry Pi, not Windows development machine
|
||||||
|
- **LED matrix library**: Uses [rpi-rgb-led-matrix-master/](mdc:rpi-rgb-led-matrix-master/) for hardware control
|
||||||
|
- **Memory limitations**: Optimize for Pi's limited RAM
|
||||||
|
- **Performance**: Consider Pi's CPU capabilities in design
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
- **Local development**: Write and test code on Windows
|
||||||
|
- **Pi deployment**: Deploy and test on actual Pi hardware
|
||||||
|
- **SSH access**: Use SSH for Pi-based testing and debugging
|
||||||
|
- **Service management**: Use systemd services for production deployment
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
- **Unit tests**: Test logic without hardware dependencies
|
||||||
|
- **Integration tests**: Test with mock display managers
|
||||||
|
- **Hardware tests**: Validate on actual Pi with LED matrix
|
||||||
|
- **Performance tests**: Monitor memory and CPU usage
|
||||||
|
|
||||||
|
## Deployment Considerations
|
||||||
|
- **Service files**: [ledmatrix.service](mdc:ledmatrix.service), [ledmatrix-web.service](mdc:ledmatrix-web.service)
|
||||||
|
- **Installation scripts**: [first_time_install.sh](mdc:first_time_install.sh), [install_service.sh](mdc:install_service.sh)
|
||||||
|
- **Dependencies**: [requirements.txt](mdc:requirements.txt) for Pi environment
|
||||||
|
- **Permissions**: Handle file permissions for Pi user
|
||||||
|
|
||||||
|
## Performance Optimization
|
||||||
|
- **Caching**: Use [src/cache_manager.py](mdc:src/cache_manager.py) for data persistence
|
||||||
|
- **Background services**: Non-blocking data fetching
|
||||||
|
- **Memory management**: Clean up resources regularly
|
||||||
|
- **Display optimization**: Minimize unnecessary redraws
|
||||||
|
|
||||||
|
## Debugging on Pi
|
||||||
|
- **Logging**: Comprehensive logging for remote debugging
|
||||||
|
- **Error reporting**: Clear error messages for troubleshooting
|
||||||
|
- **Status monitoring**: Health checks and status reporting
|
||||||
|
- **Remote access**: Web interface for configuration and monitoring
|
||||||
42
.cursor/rules/sports-managers.mdc
Normal file
42
.cursor/rules/sports-managers.mdc
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
globs: src/*_managers.py
|
||||||
|
---
|
||||||
|
|
||||||
|
# Sports Manager Development
|
||||||
|
|
||||||
|
## Manager Architecture
|
||||||
|
All sports managers inherit from base classes and follow consistent patterns:
|
||||||
|
- **Base classes**: [src/nhl_managers.py](mdc:src/nhl_managers.py), [src/nfl_managers.py](mdc:src/nfl_managers.py)
|
||||||
|
- **Common functionality**: Data fetching, caching, display rendering
|
||||||
|
- **Configuration-driven**: Behavior controlled via config sections
|
||||||
|
|
||||||
|
## Required Methods
|
||||||
|
```python
|
||||||
|
def __init__(self, config, display_manager, cache_manager)
|
||||||
|
def update(self) # Fetch fresh data
|
||||||
|
def display(self, force_clear=False) # Render current data
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Flow Pattern
|
||||||
|
1. **Fetch**: Get data from API (with caching)
|
||||||
|
2. **Process**: Extract relevant game information
|
||||||
|
3. **Filter**: Apply favorite team preferences
|
||||||
|
4. **Display**: Render to LED matrix
|
||||||
|
|
||||||
|
## Logging Standards
|
||||||
|
- **Structured prefixes**: `[NHL Recent]`, `[NFL Live]`, etc.
|
||||||
|
- **Context information**: Include team names, game status, dates
|
||||||
|
- **Debug levels**: Use appropriate log levels (info, debug, warning, error)
|
||||||
|
- **User-friendly messages**: Explain what's happening and why
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
- **API failures**: Log and continue with cached data if available
|
||||||
|
- **No data scenarios**: Distinguish between API issues vs no games available
|
||||||
|
- **Off-season awareness**: Provide helpful context during non-active periods
|
||||||
|
- **Fallback behavior**: Show alternative content when preferred content unavailable
|
||||||
|
|
||||||
|
## Configuration Integration
|
||||||
|
- **Required settings**: Validate on initialization
|
||||||
|
- **Optional settings**: Provide sensible defaults
|
||||||
|
- **Background service**: Use for non-blocking data fetching
|
||||||
|
- **Caching strategy**: Implement intelligent cache management
|
||||||
51
.cursor/rules/testing-standards.mdc
Normal file
51
.cursor/rules/testing-standards.mdc
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
globs: test/*.py,src/*.py
|
||||||
|
---
|
||||||
|
|
||||||
|
# Testing Standards
|
||||||
|
|
||||||
|
## Test Organization
|
||||||
|
- **Test directory**: [test/](mdc:test/) - All test files
|
||||||
|
- **Unit tests**: Test individual components in isolation
|
||||||
|
- **Integration tests**: Test component interactions
|
||||||
|
- **Hardware tests**: Validate on Raspberry Pi with actual LED matrix
|
||||||
|
|
||||||
|
## Testing Principles
|
||||||
|
- **Test behavior, not implementation**: Focus on what the code does, not how
|
||||||
|
- **Mock external dependencies**: Use mocks for APIs, display managers, cache
|
||||||
|
- **Test edge cases**: Empty data, API failures, configuration errors
|
||||||
|
- **Pi-specific testing**: Validate hardware integration
|
||||||
|
|
||||||
|
## Test Structure
|
||||||
|
```python
|
||||||
|
def test_manager_initialization():
|
||||||
|
"""Test that manager initializes with valid config"""
|
||||||
|
config = {"sport_scoreboard": {"enabled": True}}
|
||||||
|
manager = ManagerClass(config, mock_display, mock_cache)
|
||||||
|
assert manager.enabled == True
|
||||||
|
|
||||||
|
def test_api_failure_handling():
|
||||||
|
"""Test graceful handling of API failures"""
|
||||||
|
# Test that system continues when API fails
|
||||||
|
# Verify fallback to cached data
|
||||||
|
# Check appropriate error logging
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mock Patterns
|
||||||
|
- **Display Manager**: Mock for testing without hardware
|
||||||
|
- **Cache Manager**: Mock for testing data persistence
|
||||||
|
- **API responses**: Mock for consistent test data
|
||||||
|
- **Configuration**: Use test-specific configs
|
||||||
|
|
||||||
|
## Test Categories
|
||||||
|
- **Unit tests**: Individual manager methods
|
||||||
|
- **Integration tests**: Manager interactions with services
|
||||||
|
- **Configuration tests**: Validate config loading and validation
|
||||||
|
- **Error handling tests**: API failures, invalid data, edge cases
|
||||||
|
|
||||||
|
## Testing Best Practices
|
||||||
|
- **Descriptive names**: Test names should explain what they test
|
||||||
|
- **Single responsibility**: Each test should verify one thing
|
||||||
|
- **Independent tests**: Tests should not depend on each other
|
||||||
|
- **Clean setup/teardown**: Reset state between tests
|
||||||
|
- **Pi compatibility**: Ensure tests work in Pi environment
|
||||||
Submodule LEDMatrix.wiki updated: a01c72e156...fbd8d89a18
76
clear_nhl_cache.py
Normal file
76
clear_nhl_cache.py
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Script to clear NHL cache so managers will fetch fresh data.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# Add the src directory to the path
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
|
||||||
|
|
||||||
|
def clear_nhl_cache():
|
||||||
|
"""Clear NHL cache to force fresh data fetch."""
|
||||||
|
print("Clearing NHL cache...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
from cache_manager import CacheManager
|
||||||
|
|
||||||
|
# Create cache manager
|
||||||
|
cache_manager = CacheManager()
|
||||||
|
|
||||||
|
# Clear NHL cache for current season
|
||||||
|
now = datetime.now()
|
||||||
|
season_year = now.year
|
||||||
|
if now.month < 9:
|
||||||
|
season_year = now.year - 1
|
||||||
|
|
||||||
|
cache_key = f"nhl_api_data_{season_year}"
|
||||||
|
print(f"Clearing cache key: {cache_key}")
|
||||||
|
|
||||||
|
# Clear the cache
|
||||||
|
cache_manager.clear_cache(cache_key)
|
||||||
|
print(f"Successfully cleared cache for {cache_key}")
|
||||||
|
|
||||||
|
# Also clear any other NHL-related cache keys
|
||||||
|
nhl_keys = [
|
||||||
|
f"nhl_api_data_{season_year}",
|
||||||
|
f"nhl_api_data_{season_year-1}",
|
||||||
|
f"nhl_api_data_{season_year+1}",
|
||||||
|
"nhl_live_games",
|
||||||
|
"nhl_recent_games",
|
||||||
|
"nhl_upcoming_games"
|
||||||
|
]
|
||||||
|
|
||||||
|
for key in nhl_keys:
|
||||||
|
try:
|
||||||
|
cache_manager.clear_cache(key)
|
||||||
|
print(f"Cleared cache key: {key}")
|
||||||
|
except:
|
||||||
|
pass # Key might not exist
|
||||||
|
|
||||||
|
print("NHL cache cleared successfully!")
|
||||||
|
print("NHL managers will now fetch fresh data from ESPN API.")
|
||||||
|
|
||||||
|
except ImportError as e:
|
||||||
|
print(f"Could not import cache manager: {e}")
|
||||||
|
print("This script needs to be run on the Raspberry Pi where the cache manager is available.")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error clearing cache: {e}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main function."""
|
||||||
|
print("=" * 50)
|
||||||
|
print("NHL Cache Clearer")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
clear_nhl_cache()
|
||||||
|
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print("Cache clearing complete!")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
21
fix_nhl_cache.sh
Normal file
21
fix_nhl_cache.sh
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
"""
|
||||||
|
Script to fix NHL cache issues on Raspberry Pi.
|
||||||
|
This will clear the NHL cache and restart the display service.
|
||||||
|
"""
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "Fixing NHL Cache Issues"
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
|
# Clear NHL cache
|
||||||
|
echo "Clearing NHL cache..."
|
||||||
|
python3 clear_nhl_cache.py
|
||||||
|
|
||||||
|
# Restart the display service to force fresh data fetch
|
||||||
|
echo "Restarting display service..."
|
||||||
|
sudo systemctl restart ledmatrix.service
|
||||||
|
|
||||||
|
echo "NHL cache cleared and service restarted!"
|
||||||
|
echo "NHL managers should now fetch fresh data from ESPN API."
|
||||||
|
echo "Check the logs to see if NHL games are now being displayed."
|
||||||
109
test/test_nhl_manager_debug.py
Normal file
109
test/test_nhl_manager_debug.py
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test script to debug NHL manager data fetching issues.
|
||||||
|
This will help us understand why NHL managers aren't finding games.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import pytz
|
||||||
|
|
||||||
|
# Add the src directory to the path so we can import the managers
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
|
||||||
|
def test_nhl_season_logic():
|
||||||
|
"""Test the NHL season logic."""
|
||||||
|
print("Testing NHL season logic...")
|
||||||
|
|
||||||
|
now = datetime.now(pytz.utc)
|
||||||
|
print(f"Current date: {now}")
|
||||||
|
print(f"Current month: {now.month}")
|
||||||
|
|
||||||
|
# Test the off-season logic
|
||||||
|
if now.month in [6, 7, 8]: # Off-season months (June, July, August)
|
||||||
|
print("Status: Off-season")
|
||||||
|
elif now.month == 9: # September
|
||||||
|
print("Status: Pre-season (should have games)")
|
||||||
|
elif now.month == 10 and now.day < 15: # Early October
|
||||||
|
print("Status: Early season")
|
||||||
|
else:
|
||||||
|
print("Status: Regular season")
|
||||||
|
|
||||||
|
# Test season year calculation
|
||||||
|
season_year = now.year
|
||||||
|
if now.month < 9:
|
||||||
|
season_year = now.year - 1
|
||||||
|
|
||||||
|
print(f"Season year: {season_year}")
|
||||||
|
print(f"Cache key would be: nhl_api_data_{season_year}")
|
||||||
|
|
||||||
|
def test_espn_api_direct():
|
||||||
|
"""Test the ESPN API directly to see what data is available."""
|
||||||
|
print("\nTesting ESPN API directly...")
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
url = "https://site.api.espn.com/apis/site/v2/sports/hockey/nhl/scoreboard"
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test with current date range
|
||||||
|
now = datetime.now(pytz.utc)
|
||||||
|
start_date = (now - timedelta(days=30)).strftime("%Y%m%d")
|
||||||
|
end_date = (now + timedelta(days=30)).strftime("%Y%m%d")
|
||||||
|
date_range = f"{start_date}-{end_date}"
|
||||||
|
|
||||||
|
params = {
|
||||||
|
"dates": date_range,
|
||||||
|
"limit": 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.get(url, params=params, headers=headers, timeout=15)
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
events = data.get('events', [])
|
||||||
|
print(f"Found {len(events)} events in API response")
|
||||||
|
|
||||||
|
if events:
|
||||||
|
print("Sample events:")
|
||||||
|
for i, event in enumerate(events[:3]):
|
||||||
|
print(f" {i+1}. {event.get('name', 'Unknown')} on {event.get('date', 'Unknown')}")
|
||||||
|
|
||||||
|
# Check status distribution
|
||||||
|
status_counts = {}
|
||||||
|
for event in events:
|
||||||
|
competitions = event.get('competitions', [])
|
||||||
|
if competitions:
|
||||||
|
status = competitions[0].get('status', {}).get('type', {})
|
||||||
|
state = status.get('state', 'unknown')
|
||||||
|
status_counts[state] = status_counts.get(state, 0) + 1
|
||||||
|
|
||||||
|
print(f"\nStatus distribution:")
|
||||||
|
for status, count in status_counts.items():
|
||||||
|
print(f" {status}: {count} games")
|
||||||
|
else:
|
||||||
|
print("No events found in API response")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error testing API: {e}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Run all tests."""
|
||||||
|
print("=" * 60)
|
||||||
|
print("NHL Manager Debug Test")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
test_nhl_season_logic()
|
||||||
|
test_espn_api_direct()
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("Debug test complete!")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user