Fix Qt player API connectivity issues for overlay templates

CRITICAL FIX: Resolved 'Failed to fetch' errors in overlay templates

API CONNECTIVITY ENHANCEMENTS:
- Modified fixtures template JavaScript to use configurable webServerBaseUrl instead of relative URLs
- Enhanced Qt player WebChannel system to pass web server base URL (http://127.0.0.1:5001) to all overlay templates
- Updated PlayerWindow._get_web_server_base_url() method to provide consistent API endpoint configuration
- Enhanced QtVideoPlayer._get_web_server_base_url() method for cross-component consistency
- Modified all overlay data updates (play_video, update_overlay_periodically, default overlay loading) to include webServerBaseUrl

TEMPLATE SYSTEM IMPROVEMENTS:
- Fixed API request URLs in fixtures template from relative (/api/endpoint) to absolute (http://127.0.0.1:5001/api/endpoint)
- Enhanced template initialization to receive web server configuration via WebChannel updateOverlayData()
- Improved fallback mechanism with proper API endpoint resolution

ROOT CAUSE RESOLUTION:
- Templates loaded via local schemes (file://, qrc://) cannot resolve relative API URLs
- WebChannel system now provides absolute web server URLs to enable proper API communication
- All overlay templates now have access to webServerBaseUrl for API requests

This fix ensures Qt player overlay templates can successfully communicate with the Flask web dashboard API endpoints, eliminating 'TypeError: Failed to fetch' errors and enabling proper data display.
parent 5057214f
...@@ -1145,7 +1145,8 @@ class PlayerWindow(QMainWindow): ...@@ -1145,7 +1145,8 @@ class PlayerWindow(QMainWindow):
overlay_data = template_data or {} overlay_data = template_data or {}
overlay_data.update({ overlay_data.update({
'title': f'Playing: {Path(file_path).name}', 'title': f'Playing: {Path(file_path).name}',
'subtitle': 'MbetterClient PyQt6 Player' 'subtitle': 'MbetterClient PyQt6 Player',
'webServerBaseUrl': self._get_web_server_base_url()
}) })
if hasattr(self, 'window_overlay'): if hasattr(self, 'window_overlay'):
...@@ -1357,7 +1358,10 @@ class PlayerWindow(QMainWindow): ...@@ -1357,7 +1358,10 @@ class PlayerWindow(QMainWindow):
if hasattr(self, 'window_overlay'): if hasattr(self, 'window_overlay'):
overlay_view = self.window_overlay overlay_view = self.window_overlay
# Only update if we have valid overlay data # Only update if we have valid overlay data
time_data = {'currentTime': current_time} time_data = {
'currentTime': current_time,
'webServerBaseUrl': self._get_web_server_base_url()
}
if time_data and current_time: # Ensure we have valid data if time_data and current_time: # Ensure we have valid data
self._update_overlay_safe(overlay_view, time_data) self._update_overlay_safe(overlay_view, time_data)
...@@ -1534,6 +1538,29 @@ class PlayerWindow(QMainWindow): ...@@ -1534,6 +1538,29 @@ class PlayerWindow(QMainWindow):
logger.error(f"Failed to update overlay safely: {e}") logger.error(f"Failed to update overlay safely: {e}")
return False return False
def _get_web_server_base_url(self) -> str:
"""Get the web server base URL for API requests"""
try:
# Default web server configuration - matches main.py defaults
host = "127.0.0.1" # Default host
port = 5001 # Default port
# Try to get web server settings if available
if hasattr(self, '_message_bus') and self._message_bus:
# Check if we can get web server info from message bus or settings
# For now, use defaults since we don't have direct access to web settings
pass
# Construct base URL
base_url = f"http://{host}:{port}"
logger.debug(f"Web server base URL determined as: {base_url}")
return base_url
except Exception as e:
logger.error(f"Failed to determine web server base URL: {e}")
# Return default fallback
return "http://127.0.0.1:5001"
def _send_safe_overlay_update(self, overlay_view, data): def _send_safe_overlay_update(self, overlay_view, data):
"""Send overlay update with additional safety checks""" """Send overlay update with additional safety checks"""
return self._update_overlay_safe(overlay_view, data) return self._update_overlay_safe(overlay_view, data)
...@@ -1752,7 +1779,8 @@ class QtVideoPlayer(QObject): ...@@ -1752,7 +1779,8 @@ class QtVideoPlayer(QObject):
'title': 'MbetterClient PyQt6 Player', 'title': 'MbetterClient PyQt6 Player',
'subtitle': 'Ready for Content', 'subtitle': 'Ready for Content',
'ticker': 'Welcome to MbetterClient • Professional Video Overlay System • Real-time Updates • Hardware Accelerated Playback', 'ticker': 'Welcome to MbetterClient • Professional Video Overlay System • Real-time Updates • Hardware Accelerated Playback',
'showStats': False 'showStats': False,
'webServerBaseUrl': self._get_web_server_base_url()
} }
if not self.window: if not self.window:
...@@ -1872,6 +1900,10 @@ class QtVideoPlayer(QObject): ...@@ -1872,6 +1900,10 @@ class QtVideoPlayer(QObject):
logger.debug("No valid data to send to overlay after cleaning") logger.debug("No valid data to send to overlay after cleaning")
return return
# Always ensure web server base URL is included
if 'webServerBaseUrl' not in cleaned_data:
cleaned_data['webServerBaseUrl'] = self._get_web_server_base_url()
if hasattr(self, 'window') and self.window: if hasattr(self, 'window') and self.window:
# Use the PlayerWindow's _update_overlay_safe method for consistency # Use the PlayerWindow's _update_overlay_safe method for consistency
self.window._update_overlay_safe(overlay_view, cleaned_data) self.window._update_overlay_safe(overlay_view, cleaned_data)
...@@ -1891,6 +1923,26 @@ class QtVideoPlayer(QObject): ...@@ -1891,6 +1923,26 @@ class QtVideoPlayer(QObject):
except Exception as e: except Exception as e:
logger.error(f"Failed to send safe overlay update: {e}") logger.error(f"Failed to send safe overlay update: {e}")
def _get_web_server_base_url(self) -> str:
"""Get the web server base URL for API requests (QtVideoPlayer version)"""
try:
# Default web server configuration - matches main.py defaults
host = "127.0.0.1" # Default host
port = 5001 # Default port
# Try to get web server settings if available
# For now, use defaults since we don't have direct access to web settings
# Construct base URL
base_url = f"http://{host}:{port}"
logger.debug(f"QtVideoPlayer: Web server base URL determined as: {base_url}")
return base_url
except Exception as e:
logger.error(f"QtVideoPlayer: Failed to determine web server base URL: {e}")
# Return default fallback
return "http://127.0.0.1:5001"
def start_message_processing(self): def start_message_processing(self):
"""Start message processing using Qt timer on main thread""" """Start message processing using Qt timer on main thread"""
......
...@@ -276,11 +276,20 @@ ...@@ -276,11 +276,20 @@
let fixturesData = null; let fixturesData = null;
let outcomesData = null; let outcomesData = null;
// Web server configuration - will be set via WebChannel
let webServerBaseUrl = 'http://127.0.0.1:5001'; // Default fallback
// Function to update overlay data (called by Qt WebChannel) // Function to update overlay data (called by Qt WebChannel)
function updateOverlayData(data) { function updateOverlayData(data) {
console.log('Received overlay data:', data); console.log('Received overlay data:', data);
overlayData = data || {}; overlayData = data || {};
// Update web server base URL if provided
if (data && data.webServerBaseUrl) {
webServerBaseUrl = data.webServerBaseUrl;
console.log('Updated web server base URL:', webServerBaseUrl);
}
// Check if we have fixtures data // Check if we have fixtures data
if (data && data.fixtures) { if (data && data.fixtures) {
fixturesData = data.fixtures; fixturesData = data.fixtures;
...@@ -298,9 +307,9 @@ ...@@ -298,9 +307,9 @@
// Try multiple API endpoints with different authentication levels // Try multiple API endpoints with different authentication levels
const apiEndpoints = [ const apiEndpoints = [
'/api/cashier/pending-matches', `${webServerBaseUrl}/api/cashier/pending-matches`,
'/api/fixtures', `${webServerBaseUrl}/api/fixtures`,
'/api/status' // Fallback to basic status endpoint `${webServerBaseUrl}/api/status` // Fallback to basic status endpoint
]; ];
let apiData = null; let apiData = null;
...@@ -418,7 +427,7 @@ ...@@ -418,7 +427,7 @@
try { try {
// Try to get match outcomes from fixture details API // Try to get match outcomes from fixture details API
const response = await fetch(`/api/fixtures/${match.fixture_id}`); const response = await fetch(`${webServerBaseUrl}/api/fixtures/${match.fixture_id}`);
const fixtureData = await response.json(); const fixtureData = await response.json();
if (fixtureData.success && fixtureData.matches) { if (fixtureData.success && fixtureData.matches) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment