diff --git a/resources/web/epg_mapping.js b/resources/web/epg_mapping.js index f3d1e5b..ddc0e76 100644 --- a/resources/web/epg_mapping.js +++ b/resources/web/epg_mapping.js @@ -272,9 +272,14 @@ class EPGMappingManager { const epgData = await epgResponse.json(); console.log('Provider channels received:', providerChannels.channels?.length || 0); - console.log('Current mappings:', currentMappings); + console.log('Current mappings response:', currentMappings); + console.log('Mapping object:', currentMappings.mapping); console.log('Sample mapping keys:', Object.keys(currentMappings.mapping || {}).slice(0, 5)); + console.log('Total mapping keys:', Object.keys(currentMappings.mapping || {}).length); console.log('Sample channel IDs:', providerChannels.channels?.slice(0, 5).map(c => c.Id) || []); + console.log('Sample channel names:', providerChannels.channels?.slice(0, 5).map(c => c.Name) || []); + console.log('EPG channels loaded:', epgData.channels?.length || 0); + console.log('EPG channel map size:', Object.keys(epgData.channel_map || {}).length); // Store EPG channels with their display names this.epgChannels = epgData.channels || []; @@ -290,16 +295,21 @@ class EPGMappingManager { let currentEpgId = null; const mappingValue = currentMappings.mapping?.[channelId]; - console.log(`Channel ${channelId}: mapping value =`, mappingValue); + console.log(`Channel ${channelId} (${channelName}): mapping value =`, mappingValue); + // Handle different mapping structures: + // 1. String: "epg_id" + // 2. Object: {"epg_id": "...", "name": "..."} if (typeof mappingValue === 'string') { currentEpgId = mappingValue; - } else if (mappingValue && mappingValue.epg_id) { + } else if (mappingValue && typeof mappingValue === 'object') { currentEpgId = mappingValue.epg_id; } const suggestions = this.getSuggestions(channelName); + console.log(` -> EPG ID: ${currentEpgId}, Suggestions:`, suggestions.map(s => `${s.epgId} (${s.score}%)`)); + return { id: channelId, name: channelName, @@ -643,7 +653,11 @@ class EPGMappingManager { const mappings = {}; this.channelData.forEach(channel => { if (channel.currentEpgId) { - mappings[channel.id] = channel.currentEpgId; + // Save in the same structure as loaded + mappings[channel.id] = { + epg_id: channel.currentEpgId, + name: channel.name + }; } }); diff --git a/service.py b/service.py index 10c5960..0701627 100644 --- a/service.py +++ b/service.py @@ -2337,17 +2337,29 @@ class UltimateService: if vfs.exists(mapping_file): mapping_data = vfs.read_json(mapping_file) if mapping_data: - # Remove internal fields before returning - if '_provider_name' in mapping_data: - del mapping_data['_provider_name'] + # The file structure is: + # { + # "_provider_name": "...", + # "channel_id": {"epg_id": "...", "name": "..."} + # } + + # Extract mapping (skip internal fields starting with _) + actual_mapping = { + k: v for k, v in mapping_data.items() + if not k.startswith('_') + } + + logger.info(f"Loaded EPG mapping for {provider}: {len(actual_mapping)} channels") + logger.debug(f"Sample mappings: {list(actual_mapping.items())[:3]}") return { "provider": provider, - "mapping": mapping_data, + "mapping": actual_mapping, "exists": True } # Return empty mapping if file doesn't exist + logger.info(f"No EPG mapping file found for {provider}") return { "provider": provider, "mapping": {}, @@ -2355,7 +2367,7 @@ class UltimateService: } except Exception as e: - logger.error(f"Error getting EPG mapping for {provider}: {e}") + logger.error(f"Error getting EPG mapping for {provider}: {e}", exc_info=True) response.status = 500 return {"error": f"Failed to load mapping: {str(e)}"} @@ -2377,12 +2389,36 @@ class UltimateService: response.status = 400 return {"error": "Invalid JSON in request body"} - # Add provider name to mapping file + # Get provider label if available + provider_label = provider + try: + provider_instance = self.manager.get_provider(provider) + if provider_instance: + provider_label = getattr(provider_instance, 'provider_label', provider) + except: + pass + + # Build the file structure: + # { + # "_provider_name": "Provider Label", + # "channel_id": {"epg_id": "...", "name": "..."} + # } full_mapping = { - "_provider_name": provider, - **mapping_data + "_provider_name": provider_label } + # Add each mapping entry + for channel_id, mapping_value in mapping_data.items(): + if isinstance(mapping_value, dict): + # Already has structure {"epg_id": "...", "name": "..."} + full_mapping[channel_id] = mapping_value + elif isinstance(mapping_value, str): + # Simple string, convert to object + full_mapping[channel_id] = { + "epg_id": mapping_value, + "name": "" # Name not provided + } + # Save to file vfs = VFS(addon_subdir="") mapping_file = f"{provider}_epg_mapping.json" @@ -2390,6 +2426,8 @@ class UltimateService: success = vfs.write_json(mapping_file, full_mapping) if success: + logger.info(f"Saved EPG mapping for {provider}: {len(mapping_data)} channels") + # Clear mapping cache if it exists try: from streaming_providers.base.epg.epg_mapping import EPGMapping @@ -2397,7 +2435,6 @@ class UltimateService: mapping_manager.reload_mapping(provider) logger.info(f"Reloaded EPG mapping cache for {provider}") except ImportError: - # EPGMapping not available, skip cache reload logger.debug("EPGMapping not available for cache reload") pass except Exception as reload_err: @@ -2405,7 +2442,8 @@ class UltimateService: return { "success": True, - "message": f"Mapping saved for {provider}" + "message": f"Mapping saved for {provider}", + "channels_mapped": len(mapping_data) } else: response.status = 500