From 7ed1dd2b4c3501784d06b425acbab34c32a1b189 Mon Sep 17 00:00:00 2001 From: Nirvana Date: Thu, 11 Dec 2025 21:08:03 +0100 Subject: [PATCH] Add web config --- lib/streaming_providers/base/manager.py | 103 ++++++++++++++++++++++++ service.py | 61 +++++++++++++- 2 files changed, 160 insertions(+), 4 deletions(-) diff --git a/lib/streaming_providers/base/manager.py b/lib/streaming_providers/base/manager.py index a260b2a..c635a2c 100644 --- a/lib/streaming_providers/base/manager.py +++ b/lib/streaming_providers/base/manager.py @@ -783,3 +783,106 @@ class ProviderManager: """Clear all registered DRM plugins""" logger.info("ProviderManager: Clearing all DRM plugins") self.drm_plugin_manager.clear_plugins() + + @staticmethod + def get_provider_class(provider_name: str): + """ + Get provider class from AVAILABLE_PROVIDERS registry. + + Args: + provider_name: Name of the provider (without country suffix) + + Returns: + Provider class or None if not found + """ + from streaming_providers import AVAILABLE_PROVIDERS + + # Remove country suffix if present (e.g., "joyn_de" -> "joyn") + base_name = provider_name + if '_' in provider_name: + # Check if suffix looks like a country code (2-3 letters) + name_parts = provider_name.rsplit('_', 1) + if len(name_parts[1]) in (2, 3) and name_parts[1].isalpha(): + base_name = name_parts[0] + + return AVAILABLE_PROVIDERS.get(base_name) + + + def reinitialize_provider(self, provider_name: str) -> bool: + """ + Reinitialize a provider instance (e.g., after credentials change). + + Args: + provider_name: Name of the provider to reinitialize + + Returns: + True if successful, False otherwise + + Note: + This creates a new provider instance with the same country, + preserving the original configuration but with fresh HTTP session. + """ + logger.info(f"ProviderManager: Reinitializing provider '{provider_name}'") + + # Get existing provider to extract configuration + existing_provider = self.get_provider(provider_name) + if not existing_provider: + logger.error(f"ProviderManager: Cannot reinitialize - provider '{provider_name}' not found") + return False + + # Extract country from existing provider + country = getattr(existing_provider, 'country', 'DE') + + # Get provider class + provider_class = self.get_provider_class(provider_name) + if not provider_class: + logger.error(f"ProviderManager: Provider class not found for '{provider_name}'") + return False + + try: + # Create new provider instance with same country + new_provider = provider_class(country=country) + + # Replace in registry + self.providers[provider_name] = new_provider + + logger.info(f"ProviderManager: Successfully reinitialized provider '{provider_name}'") + return True + + except Exception as e: + logger.error(f"ProviderManager: Failed to reinitialize provider '{provider_name}': {e}") + return False + + + def reinitialize_providers(self, provider_names: List[str]) -> Dict[str, bool]: + """ + Reinitialize multiple providers. + + Args: + provider_names: List of provider names to reinitialize + + Returns: + Dictionary mapping provider names to success status + """ + logger.info(f"ProviderManager: Reinitializing {len(provider_names)} providers") + + results = {} + for provider_name in provider_names: + success = self.reinitialize_provider(provider_name) + results[provider_name] = success + + successful = sum(1 for result in results.values() if result) + logger.info(f"ProviderManager: Reinitialization completed - {successful}/{len(provider_names)} successful") + + return results + + + def reinitialize_all_providers(self) -> Dict[str, bool]: + """ + Reinitialize all registered providers. + + Returns: + Dictionary mapping provider names to success status + """ + provider_names = list(self.providers.keys()) + return self.reinitialize_providers(provider_names) \ No newline at end of file diff --git a/service.py b/service.py index 08b6651..bb2326c 100644 --- a/service.py +++ b/service.py @@ -1358,13 +1358,19 @@ class UltimateService: logger.info(f"Save result for {provider}: success={success}, message={message}") if success: + # Reinitialize provider to pick up new credentials + reinit_success = self.manager.reinitialize_provider(provider) + if not reinit_success: + logger.warning(f"Failed to reinitialize provider '{provider}' after credential change") + response.status = 200 response.content_type = 'application/json; charset=utf-8' return { 'success': True, 'provider': provider, 'message': message, - 'action': 'updated' if existing_credentials else 'created' + 'action': 'updated' if existing_credentials else 'created', + 'reinitialized': reinit_success } else: # Determine appropriate status code @@ -1394,12 +1400,18 @@ class UltimateService: success, message = settings_manager.delete_provider_credentials_from_api(provider) if success: + # Reinitialize provider to clear any cached authentication + reinit_success = self.manager.reinitialize_provider(provider) + if not reinit_success: + logger.warning(f"Failed to reinitialize provider '{provider}' after credential deletion") + response.status = 200 response.content_type = 'application/json; charset=utf-8' return { 'success': True, 'provider': provider, - 'message': message + 'message': message, + 'reinitialized': reinit_success } else: # Determine appropriate status code @@ -1499,12 +1511,18 @@ class UltimateService: ) if success: + # Reinitialize provider to pick up new proxy configuration + reinit_success = self.manager.reinitialize_provider(provider) + if not reinit_success: + logger.warning(f"Failed to reinitialize provider '{provider}' after proxy change") + response.status = 200 response.content_type = 'application/json; charset=utf-8' return { 'success': True, 'provider': provider, - 'message': message + 'message': message, + 'reinitialized': reinit_success } else: # Determine appropriate status code @@ -1534,12 +1552,18 @@ class UltimateService: success, message = settings_manager.delete_provider_proxy_from_api(provider) if success: + # Reinitialize provider to remove proxy configuration + reinit_success = self.manager.reinitialize_provider(provider) # Changed: self.manager + if not reinit_success: + logger.warning(f"Failed to reinitialize provider '{provider}' after proxy deletion") + response.status = 200 response.content_type = 'application/json; charset=utf-8' return { 'success': True, 'provider': provider, - 'message': message + 'message': message, + 'reinitialized': reinit_success } else: # Determine appropriate status code @@ -1555,6 +1579,35 @@ class UltimateService: response.status = 500 return {'error': f'Internal server error: {str(api_err)}'} + @self.app.route('/api/providers//reinitialize', method='POST') + def reinitialize_provider(provider): + """ + Manually reinitialize a provider (e.g., after external configuration changes) + + Example: POST /api/providers/joyn_de/reinitialize + """ + try: + success = self.manager.reinitialize_provider(provider) # self.manager + + if success: + return { + 'success': True, + 'provider': provider, + 'message': f'Provider {provider} reinitialized successfully' + } + else: + response.status = 500 + return { + 'success': False, + 'provider': provider, + 'message': f'Failed to reinitialize provider {provider}' + } + + except Exception as e: + logger.error(f"Error reinitializing provider {provider}: {e}") + response.status = 500 + return {'error': f'Internal server error: {str(e)}'} + @self.app.route('/api/config/export') def export_config(): """Export all configurations as JSON"""