* fix(odds-ticker): Reduce log spam from insufficient time warnings
- Add _insufficient_time_warning_logged flag to prevent repeated warnings
- Log insufficient time warning only once per display session
- Reset warning flag when starting new display or updating data
- Maintain debug logging for scroll position resets to aid debugging
This addresses the frequent 'Not enough time to complete content display'
warnings that were flooding the logs every few milliseconds.
* fix(leaderboard): Reduce log spam from progress and FPS logging
- Change progress logging from every 50 pixels to every 5 seconds
- Increase FPS logging interval from 10 seconds to 30 seconds
- Add progress_log_interval and last_progress_log_time variables
- Reset progress log timer when starting new display sessions or updating data
- Maintain debug capability while significantly reducing log volume
This addresses the frequent 'Leaderboard progress' and 'Leaderboard FPS'
messages that were flooding the logs during leaderboard scrolling.
* fix(music): Reduce log spam from track update logging
- Add throttling mechanism for track update logging
- Log track updates only when track title changes or after 5 seconds
- Track last_logged_track_title and last_track_log_time to prevent spam
- Maintain debug logging for throttled updates
- Apply throttling to both regular updates and first valid data logging
This addresses the frequent 'Track info updated' messages that were
flooding the logs every few hundred milliseconds for the same track.
* fix(logo-downloader): Fix TA&M filename normalization issue
- Add special case for TA&M to keep as TA&M instead of converting to TAANDM
- This fixes the issue where code was looking for TAANDM.png instead of TA&M.png
- The actual logo file exists as TA&M.png, so normalization was causing file not found errors
- Prevents unnecessary download attempts and permission errors for existing files
Fixes the error: 'Logo not found for TA&M at assets/sports/ncaa_logos/TAANDM.png'
* fix(logo-downloader): Implement robust filename variation handling
- Add get_logo_filename_variations() method to handle multiple filename formats
- Update _load_and_resize_logo() to try filename variations before downloading
- Handles cases like TA&M.png vs TAANDM.png gracefully
- Maintains backward compatibility with existing normalized filenames
- Prevents issues with special characters in filenames while supporting existing files
This addresses the ampersand filename issue more robustly by:
1. First trying the original filename (TA&M.png)
2. Falling back to normalized filename (TAANDM.png) if needed
3. Only attempting downloads if no variations exist
* fix(leaderboard): Reduce log spam from end reached messages
- Add _end_reached_logged flag to prevent repeated end reached warnings
- Log 'Leaderboard reached end' and 'scrolling stopped' messages only once per display session
- Maintain debug logging for throttled messages to aid debugging
- Reset flag when starting new display sessions or updating data
- Apply same throttling pattern used in odds ticker manager
This addresses the frequent 'Leaderboard reached end' and 'scrolling stopped'
messages that were flooding the logs every few milliseconds when at the end.
* Fix leaderboard scrolling performance after PR #39 merge
- Restore leaderboard background updates that were accidentally removed
- Fix duration method call from get_dynamic_duration() back to get_duration()
- Restore proper fallback duration (600s instead of 60s) for leaderboard
- Add back sports manager updates that feed data to leaderboard
- Fix leaderboard defer_update priority to prevent scrolling lag
These changes restore the leaderboard's dynamic duration calculation
and ensure it gets proper background updates for smooth scrolling.
* Apply PR #60 leaderboard performance optimizations
- Change scroll_delay from 0.05s to 0.01s (100fps instead of 20fps)
- Remove conditional scrolling logic - scroll every frame for smooth animation
- Add FPS tracking and logging for performance monitoring
- Restore high-framerate scrolling that was working before PR #39 merge
These changes restore the smooth leaderboard scrolling performance
that was achieved in PR #60 but was lost during the PR #39 merge.
* Fix critical bugs identified in PR #39 review
- Fix record filtering logic bug: change away_record == set to away_record in set
- Fix incorrect sport specification: change 'nfl' to 'ncaa_fb' for NCAA Football data requests
- These bugs were causing incorrect data display and wrong sport data fetching
Addresses issues found by cursor bot in PR #39 review:
- Record filtering was always evaluating to False
- NCAA Football was fetching NFL data instead of college football data
* Enhance cache clearing implementation from PR #39
- Add detailed logging to cache clearing process for better visibility
- Log cache clearing statistics (memory entries and file count)
- Improve startup logging to show cache clearing and data refetch process
- Addresses legoguy1000's comment about preventing stale data issues
This enhances the cache clearing implementation that was added in PR #39
to help prevent legacy cache issues and stale data problems.
* continuing on base_classes - added baseball and api extractor since we don't use ESPN api for all sports
* tests
* fix missing duration
* ensure milb, mlb, ncaa bb are all using new baseball base class properly
* cursor rule to help with PR creation
* fix image call
* fix _scoreboard suffix on milb, MLB
* rebase
* Update NFL and NCAA FB fetch
* update FB updates
* kinda working, kinda broken
* Fixed and update loggers
* move to individual files
* timeout updates
* seems to work well
* Leaderboard overestimates time
* ignore that
* minor syntax updates
* More consolidation but i broke something
* fixed
* Hockey seems to work
* Fix my changes to logo downloader
* even more consolidation
* fixes
* more cleanup
* inheritance stuff
* Change football to ESPN down text, it does what ur already doing. Change color to red on Red ZOne
* Fix leaderboard
* Update football.py
Signed-off-by: Alex Resnick <adr8292@gmail.com>
* Minor fixes
* don't want that
* background fetch
* whoops
---------
Signed-off-by: Alex Resnick <adr8292@gmail.com>
Co-authored-by: Alex Resnick <adr8282@gmail.com>
Co-authored-by: ChuckBuilds <33324927+ChuckBuilds@users.noreply.github.com>
* Fix NCAAFB ranking display issue
- Remove duplicate ranking system that was drawing rankings behind team logos
- Old system (_get_rank) was drawing rankings at top of logos
- New system (_fetch_team_rankings) correctly draws rankings in bottom corners
- Remove old ranking calls from live, recent, and upcoming game drawing functions
- Remove unnecessary _fetch_rankings() calls from update methods
- Rankings now only appear in designated corner positions, not overlapping logos
Fixes issue where team rankings/betting lines were being drawn behind
team logos instead of replacing team records in the corners.
* Add missing show_ranking and show_records options to NCAAFB web UI
- Add show_ranking option to NCAAFB scoreboard config template
- Add show_records and show_ranking toggle switches to NCAAFB web UI
- Update JavaScript form collection to include new fields
- Users can now control whether to show team records or rankings via web interface
This completes the fix for NCAAFB ranking display - users can now enable
show_ranking in the web UI to see AP Top 25 rankings instead of team records.
* Implement Background Threading for Season Data Fetching
Phase 1: Background Season Data Fetching - COMPLETED
Key Features:
- Created BackgroundDataService class with thread-safe operations
- Implemented automatic retry logic with exponential backoff
- Modified NFL manager to use background service
- Added immediate partial data return for non-blocking display
- Comprehensive logging and statistics tracking
Performance Benefits:
- Main display loop no longer blocked by API calls
- Season data always fresh with background updates
- Better user experience during data fetching
Files Added/Modified:
- src/background_data_service.py (NEW)
- src/nfl_managers.py (updated)
- config/config.template.json (updated)
- test_background_service.py (NEW)
- BACKGROUND_SERVICE_README.md (NEW)
* Fix data validation issues in background service
- Add comprehensive data structure validation in NFL managers
- Handle malformed events gracefully with proper error logging
- Validate cached data format and handle legacy formats
- Add data validation in background service response parsing
- Fix TypeError: string indices must be integers, not 'str'
This fixes the error where events were being treated as strings
instead of dictionaries, causing crashes in recent/upcoming games.
* Phase 2: Apply Background Service to Major Sport Managers
✅ Applied background service support to:
- NCAAFB Manager (College Football)
- NBA Manager (Basketball)
- NHL Manager (Hockey)
- MLB Manager (Baseball)
🔧 Key Features Added:
- Background service initialization for each sport
- Configurable workers, timeouts, and retry settings
- Graceful fallback when background service is disabled
- Comprehensive logging for monitoring
⚙️ Configuration Updates:
- Added background_service config section to NBA
- Added background_service config section to NHL
- Added background_service config section to NCAAFB
- Each sport can independently enable/disable background service
📈 Performance Benefits:
- Season data fetching no longer blocks display loops
- Immediate response with cached/partial data
- Background threads handle heavy API calls
- Better responsiveness across all supported sports
Next: Apply to remaining managers (MiLB, Soccer, etc.)
* Fix Python compatibility issue in BackgroundDataService shutdown
🐛 Bug Fix:
- Fixed TypeError in ThreadPoolExecutor.shutdown() for older Python versions
- Added try/catch to handle timeout parameter compatibility
- Fallback gracefully for Python < 3.9 that doesn't support timeout parameter
🔧 Technical Details:
- ThreadPoolExecutor.shutdown(timeout=) was added in Python 3.9
- Older versions only support shutdown(wait=)
- Added compatibility layer with proper error handling
✅ Result:
- No more shutdown exceptions on older Python versions
- Graceful degradation for different Python environments
- Maintains full functionality on newer Python versions
* Phase 2 Complete: Background Service Applied to All Sport Managers
🎉 MAJOR MILESTONE: Complete Background Service Rollout
✅ All Sport Managers Now Support Background Service:
- MiLB Manager (Minor League Baseball)
- Soccer Manager (Multiple leagues: Premier League, La Liga, etc.)
- Leaderboard Manager (Multi-sport standings)
- Odds Ticker Manager (Live betting odds)
🔧 Technical Implementation:
- Background service initialization in all managers
- Configurable workers, timeouts, and retry settings
- Graceful fallback when background service is disabled
- Comprehensive logging for monitoring and debugging
- Thread-safe operations with proper error handling
⚙️ Configuration Support Added:
- MiLB: background_service config section
- Soccer: background_service config section
- Leaderboard: background_service config section
- Odds Ticker: background_service config section
- Each manager can independently enable/disable background service
📈 Performance Benefits Achieved:
- Non-blocking data fetching across ALL sport managers
- Immediate response with cached/partial data
- Background threads handle heavy API calls
- Significantly improved responsiveness
- Better user experience during data loading
🚀 Production Ready:
- All major sport managers now support background threading
- Comprehensive configuration options
- Robust error handling and fallback mechanisms
- Ready for production deployment
Next: Phase 3 - Advanced features (priority queuing, analytics)
* Update wiki submodule with Background Service documentation
📚 Wiki Documentation Added:
- Complete Background Service Guide with architecture diagrams
- Configuration examples and best practices
- Performance benefits and troubleshooting guide
- Migration guide and advanced features
🔧 Navigation Updates:
- Added to sidebar under Technical section
- Updated home page with performance section
- Highlighted as NEW feature with ⚡ icon
The wiki now includes comprehensive documentation for the new
background threading system that improves performance across
all sport managers.
* Fix CacheManager constructor in test script
🐛 Bug Fix:
- Fixed CacheManager initialization in test_background_service.py
- CacheManager no longer takes config_manager parameter
- Updated constructor call to match current implementation
✅ Result:
- Test script now works with current CacheManager API
- Background service testing can proceed without errors
* Move test_background_service.py to test/ directory
📁 Organization Improvement:
- Moved test_background_service.py from root to test/ directory
- Updated import paths to work from new location
- Fixed sys.path to correctly reference src/ directory
- Updated imports to use relative paths
🔧 Technical Changes:
- Changed sys.path from 'src' to '../src' (go up from test/)
- Updated imports to remove 'src.' prefix
- Maintains all functionality while improving project structure
✅ Benefits:
- Better project organization
- Test files properly grouped in test/ directory
- Cleaner root directory structure
- Follows standard Python project layout
* Remove old test_background_service.py from root directory
📁 Cleanup:
- Removed test_background_service.py from root directory
- File has been moved to test/ directory for better organization
- Maintains clean project structure
* Fix NCAA FB team ranking display functionality
- Add missing _fetch_team_rankings() calls to all update methods (live, recent, upcoming)
- Add ranking display logic to live manager scorebug layout
- Remove unused old _fetch_rankings() method and top_25_rankings variable
- Rankings now properly display as #X format when show_ranking is enabled
- Fixes non-functional ranking feature despite existing UI and configuration options
- Reset display start time when force_clear is True or when starting fresh
- Reset scroll position for clean start when display is reset
- Add check for old display start time and reset if it's more than 2x dynamic duration
- Prevents the odds ticker from staying black when it comes back into rotation
- Ensures proper state management between display sessions
- Moved bases to right edge of odds column to be closer to inning indicator
- Reduced horizontal spacing from 10px to 8px between bases
- Reduced vertical spacing from 8px to 6px for more compact diamond
- Updated cluster width from 26px to 24px to match tighter spacing
- Adjusted positioning offset from 13px to 12px for proper centering
- Bases now positioned closer to the inning indicator for better visual flow
- Changed from circular bases to diamond-shaped bases (polygons)
- Increased base size from 6px to 8px to match MLB manager
- Increased spacing from 8px to 10px for better visibility
- Added proper cluster positioning and sizing calculations
- Shifted bases down 2 pixels from center for better positioning
- Increased minimum width to 30px to accommodate larger base cluster
- Now uses same diamond-shaped base style as MLB manager for consistency
- Removed text-based odds display for baseball live games entirely
- Graphical bases now replace the entire odds section (not just overlay it)
- Bases are properly centered vertically on the display (height // 2)
- Bases are centered horizontally within the odds column width
- Creates cleaner, more focused display with bases as the main visual element
- Added back day_text, date_text, and time_text variables for baseball live games
- These variables are needed for the datetime display section
- Shows inning (▲5), count (2-1), and outs (2 outs) in the datetime column
- Fixes the 'cannot access local variable' error that was occurring
- Removed old text-based bases display code that was still showing
- Fixed positioning calculation for graphical bases to center properly
- Added bounds checking to prevent bases from overlapping off display
- Bases are now properly centered in the odds column with appropriate spacing
- Cleaned up baseball live game display to show only count, outs, and graphical bases
- Added _draw_base_indicators() method similar to MLB manager
- Replaced text-based bases display with graphical diamond representation
- Shows diamond outline with filled circles for occupied bases
- Displays count and outs as text while showing bases graphically
- Creates more visual and intuitive representation of game state
- Uses smaller size (6px) and spacing (8px) appropriate for odds ticker
- Changed outs display to use proper pluralization:
- '1 out' for single out
- '2 outs', '3 outs' for multiple outs
- This makes the live game information more grammatically correct and readable
- Modified calculate_dynamic_duration() to add extra buffer time when looping is enabled
- Added 20% extra buffer for looping to ensure smooth transitions
- Added logic to detect when display is ending and reset scroll position for clean transitions
- Added display start time tracking to manage duration properly
- This prevents the odds ticker from cutting off mid-scroll when switching modes
- Removed parentheses around scores for live games (e.g., 'Team 5' instead of 'Team (5)')
- Improved bases section for baseball games:
- Changed from '1', '2', '3' to '1B', '2B', '3B' for clarity
- Changed from '---' to 'Empty' when no bases are occupied
- This makes it much clearer what the information represents
- Live games now show cleaner, more readable score format
- Added debug logging to _fetch_upcoming_games() to track data fetching
- Added debug logging to _create_ticker_image() to track image creation
- Added logging for favorite teams, odds filtering, and game counts
- Added logging for total_scroll_width calculation
- This will help identify why dynamic duration is falling back to minimum
- Modified get_dynamic_duration() to trigger update when total_scroll_width is 0
- This ensures the dynamic duration is calculated with actual data before being used
- Prevents fallback to minimum duration (30s) when odds ticker hasn't updated yet
- Added debug logging to track when updates are triggered for duration calculation
- Fixed double-counting of display width in total_scroll_width calculation
- Added detailed debug logging for dynamic duration calculation
- Added debug logging for scrolling behavior and loop resets
- Created test script for debugging dynamic duration issues
- The issue was that total_scroll_width included display width, causing
incorrect duration calculations that resulted in early cutoff