diff --git a/StreamMaster.SchedulesDirect/Converters/XmlTv2Mxf.cs b/StreamMaster.SchedulesDirect/Converters/XmlTv2Mxf.cs index 835f7e940..429788eca 100644 --- a/StreamMaster.SchedulesDirect/Converters/XmlTv2Mxf.cs +++ b/StreamMaster.SchedulesDirect/Converters/XmlTv2Mxf.cs @@ -36,8 +36,8 @@ private class SeriesEpisodeInfo { schedulesDirectData = new SchedulesDirectData(logger, _epgImportLogger, ePGHelper, memoryCache, EPGNumber); if ( - !BuildLineupAndChannelServices(xmlTv) || - !BuildScheduleEntries(xmlTv) + !BuildLineupAndChannelServices(xmlTv, EPGNumber) || + !BuildScheduleEntries(xmlTv, EPGNumber) ) { return null; @@ -48,7 +48,7 @@ private class SeriesEpisodeInfo return xmlTv; } - private bool BuildLineupAndChannelServices(XMLTV xmlTv, string lineupName = "SM+ Default Lineup Name") + private bool BuildLineupAndChannelServices(XMLTV xmlTv, int epgNumber, string lineupName = "SM+ Default Lineup Name") { logger.LogInformation("Building lineup and channel services."); @@ -56,8 +56,9 @@ private bool BuildLineupAndChannelServices(XMLTV xmlTv, string lineupName = "SM+ foreach (XmltvChannel channel in xmlTv.Channels) { - MxfService mxfService = schedulesDirectData.FindOrCreateService(channel.Id); - + string serviceName = $"{epgNumber}-{channel.Id}"; + MxfService mxfService = schedulesDirectData.FindOrCreateService(serviceName); + if (string.IsNullOrEmpty(mxfService.CallSign)) { // add "callsign" and "station name" @@ -123,7 +124,7 @@ private bool BuildLineupAndChannelServices(XMLTV xmlTv, string lineupName = "SM+ return true; } - private bool BuildScheduleEntries(XMLTV xmlTv) + private bool BuildScheduleEntries(XMLTV xmlTv, int epgNumber) { Setting settings = memoryCache.GetSetting(); @@ -132,7 +133,8 @@ private bool BuildScheduleEntries(XMLTV xmlTv) { SeriesEpisodeInfo info = GetSeriesEpisodeInfo(program); - MxfService mxfService = schedulesDirectData.FindOrCreateService(program.Channel); + string serviceName = $"{epgNumber}-{program.Channel}"; + MxfService mxfService = schedulesDirectData.FindOrCreateService(serviceName); MxfProgram mxfProgram = schedulesDirectData.FindOrCreateProgram(DetermineProgramUid(program)); if (mxfProgram.Title == null) diff --git a/StreamMaster.SchedulesDirect/Lineups.cs b/StreamMaster.SchedulesDirect/Lineups.cs index 0a66c0541..4fe0972ae 100644 --- a/StreamMaster.SchedulesDirect/Lineups.cs +++ b/StreamMaster.SchedulesDirect/Lineups.cs @@ -74,13 +74,15 @@ public async Task BuildLineupServices(CancellationToken cancellationToken } // build the service if necessary - MxfService mxfService = schedulesDirectData.FindOrCreateService(station.StationId); + string serviceName = $"{EPGHelper.SchedulesDirectId}-{station.StationId}"; + + MxfService mxfService = schedulesDirectData.FindOrCreateService(serviceName); if (string.IsNullOrEmpty(mxfService.CallSign)) { // instantiate stationLogo and override uid StationImage? stationLogo = null; - mxfService.UidOverride = $"!Service!STREAMMASTER_{station.StationId}"; + mxfService.UidOverride = $"!Service!STREAMMASTER_{serviceName}"; // add callsign and station name mxfService.CallSign = station.Callsign; diff --git a/StreamMaster.SchedulesDirect/Schedules.cs b/StreamMaster.SchedulesDirect/Schedules.cs index ba9b964c1..02db11a46 100644 --- a/StreamMaster.SchedulesDirect/Schedules.cs +++ b/StreamMaster.SchedulesDirect/Schedules.cs @@ -10,7 +10,7 @@ namespace StreamMaster.SchedulesDirect; -public class Schedules(ILogger logger, IMemoryCache memoryCache, ISchedulesDirectAPIService schedulesDirectAPI, IEPGCache epgCache, ISchedulesDirectDataService schedulesDirectDataService) : ISchedules +public class Schedules(ILogger logger, IMemoryCache memoryCache, IEPGHelper ePGHelper, ISchedulesDirectAPIService schedulesDirectAPI, IEPGCache epgCache, ISchedulesDirectDataService schedulesDirectDataService) : ISchedules { private int cachedSchedules; private int downloadedSchedules; @@ -120,9 +120,10 @@ private async Task GetMd5ScheduleEntries(string[] dates, int start, Dictio for (int i = 0; i < requests.Length; ++i) { + (int epgNumber, string stationId) = ePGHelper.ExtractEPGNumberAndStationId(toProcess[start + i].StationId); requests[i] = new ScheduleRequest() { - StationId = toProcess[start + i].StationId, + StationId = stationId, Date = dates }; } @@ -143,18 +144,10 @@ private async Task GetMd5ScheduleEntries(string[] dates, int start, Dictio { Dictionary requestErrors = []; + string serviceName = $"{EPGHelper.SchedulesDirectId}-{request.StationId}"; + MxfService mxfService = schedulesDirectData.FindOrCreateService(serviceName); + IEnumerable> test = schedulesDirectData.Services.Where(arg => arg.Value.StationId.Equals(serviceName)); - MxfService mxfService = schedulesDirectData.FindOrCreateService(request.StationId); - IEnumerable> test = schedulesDirectData.Services.Where(arg => arg.Value.StationId.Equals(request.StationId)); - - if (!schedulesDirectData.Services.ContainsKey(request.StationId)) - { - int aaa = 1; - } - else - { - MxfService b = schedulesDirectData.Services[request.StationId]; - } if (stationResponses.TryGetValue(request.StationId, out Dictionary? stationResponse)) { @@ -368,7 +361,8 @@ private void ProcessMd5ScheduleEntry(string md5) // determine which service entry applies to ISchedulesDirectData schedulesDirectData = schedulesDirectDataService.SchedulesDirectData(); - MxfService mxfService = schedulesDirectData.FindOrCreateService(schedule.StationId); + string serviceName = $"{EPGHelper.SchedulesDirectId}-{schedule.StationId}"; + MxfService mxfService = schedulesDirectData.FindOrCreateService(serviceName); // process each program schedule entry foreach (ScheduleProgram scheduleProgram in schedule.Programs) diff --git a/StreamMaster.SchedulesDirect/XMLTVBuilder.cs b/StreamMaster.SchedulesDirect/XMLTVBuilder.cs index ed60483e2..934293f64 100644 --- a/StreamMaster.SchedulesDirect/XMLTVBuilder.cs +++ b/StreamMaster.SchedulesDirect/XMLTVBuilder.cs @@ -28,6 +28,7 @@ public class XMLTVBuilder(IMemoryCache memoryCache, IEPGHelper ePGHelper, IIconS public XMLTV? CreateXmlTv(string baseUrl, List videoStreamConfigs) { seriesDict = []; + keywordDict = []; _baseUrl = baseUrl; try { @@ -36,7 +37,7 @@ public class XMLTVBuilder(IMemoryCache memoryCache, IEPGHelper ePGHelper, IIconS Date = DateTime.UtcNow.ToString(CultureInfo.InvariantCulture), SourceInfoUrl = "https://github.com/SenexCrenshaw/StreamMaster", SourceInfoName = "Stream Master", - GeneratorInfoName = "StreamMaster", + GeneratorInfoName = "Stream Master", GeneratorInfoUrl = "https://github.com/SenexCrenshaw/StreamMaster", Channels = [], Programs = [] @@ -47,32 +48,22 @@ public class XMLTVBuilder(IMemoryCache memoryCache, IEPGHelper ePGHelper, IIconS int newServiceCount = 0; - // Pre-process all keywords into a HashSet for faster lookup - if (keywordDict.Count == 0) - { - keywordDict = schedulesDirectDataService.AllKeywords - .Where(k => !string.Equals(k.Word, "Uncategorized", StringComparison.OrdinalIgnoreCase) && - !k.Word.Contains("premiere", StringComparison.OrdinalIgnoreCase)) - .GroupBy(k => k.Id) - .ToDictionary( - g => g.Key, - g => - { - string word = g.First().Word; - return string.Equals(word, "Movies", StringComparison.OrdinalIgnoreCase) ? "Movie" : word; - } - ); - } + keywordDict = schedulesDirectDataService.AllKeywords + .Where(k => !string.Equals(k.Word, "Uncategorized", StringComparison.OrdinalIgnoreCase) && + !k.Word.Contains("premiere", StringComparison.OrdinalIgnoreCase)) + .GroupBy(k => k.Id) + .ToDictionary( + g => g.Key, + g => + { + string word = g.First().Word; + return string.Equals(word, "Movies", StringComparison.OrdinalIgnoreCase) ? "Movie" : word; + } + ); + foreach (MxfSeriesInfo seriesInfo in schedulesDirectDataService.AllSeriesInfos) { - if (seriesDict.ContainsKey(seriesInfo.Index)) - { - MxfSeriesInfo a = seriesDict[seriesInfo.Index]; - // Handle the duplicate key scenario, e.g., log it or throw an exception - // LogWarning($"Duplicate series index found: {seriesInfo.Index}"); - continue; - } - seriesDict.Add(seriesInfo.Index, seriesInfo); + seriesDict.TryAdd(seriesInfo.Index, seriesInfo); } List services = schedulesDirectDataService.AllServices; @@ -86,17 +77,16 @@ public class XMLTVBuilder(IMemoryCache memoryCache, IEPGHelper ePGHelper, IIconS int epgNumber; string stationId; (epgNumber, stationId) = ePGHelper.ExtractEPGNumberAndStationId(videoStreamConfig.User_Tvg_ID); - //} - MxfService? origService = services.FirstOrDefault(a => a.StationId == stationId && a.EPGNumber == epgNumber); + MxfService? origService = services.FirstOrDefault(a => a.StationId == videoStreamConfig.User_Tvg_ID && a.EPGNumber == epgNumber); + if (origService == null) { continue; } - - MxfService newService = new(newServiceCount++, videoStreamConfig.User_Tvg_ID);// schedulesDirectDataService.FindOrCreateService(stationId); + MxfService newService = new(newServiceCount++, videoStreamConfig.User_Tvg_ID); // videoStreamConfig.User_Tvg_ID); if (origService.MxfScheduleEntries is not null) { @@ -290,15 +280,11 @@ private void DoPrograms(List services, int progCount, XMLTV xmlTv) XmltvProgramme program = BuildXmltvProgram(scheduleEntry, logger, channel.Id, settings, ePGHelper, iconService, _baseUrl); xmlTv.Programs.Add(program); ++count; - if (count % 1000 == 0) - { - sw.Stop(); - logger.LogInformation($"Processed {count} programs in {sw.ElapsedMilliseconds} ms"); - sw.Restart(); - } + }); }; - logger.LogInformation($"Finsihed processing {count} programs"); + sw.Stop(); + logger.LogInformation($"Finsihed processing {count} programs in {sw.ElapsedMilliseconds} ms"); } catch (Exception ex) {