From 1f809bd571b11165b7eae5fb9bd80e9441f29f6e Mon Sep 17 00:00:00 2001 From: Horst Beham Date: Wed, 17 Mar 2021 07:01:05 +0100 Subject: [PATCH] - bugfix for Sharp/Dyon/... .csv file formats with less than 52 colums - improved reference list channel matching: if multiple channels match the same name, then the candidates are narrowed down by service type (TV/radio/data - if known), case sensitivity (upper/lowercase), encryption (unencrypted first) --- source/ChanSort.Api/Controller/Editor.cs | 70 +++++++++++++------ .../ChanSort.Loader.Sharp/SharpSerializer.cs | 3 +- source/changelog.md | 4 ++ 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/source/ChanSort.Api/Controller/Editor.cs b/source/ChanSort.Api/Controller/Editor.cs index 631f4fc..1e50cd3 100644 --- a/source/ChanSort.Api/Controller/Editor.cs +++ b/source/ChanSort.Api/Controller/Editor.cs @@ -264,7 +264,7 @@ namespace ChanSort.Api if (!(chanFilter?.Invoke(refChannel, true) ?? true)) continue; - var tvChannel = FindChannel(tvList, refChannel, onidTsidSid); + var tvChannel = FindChannel(tvList, tvListPosIndex, refChannel, onidTsidSid); if (tvChannel != null) { @@ -314,37 +314,63 @@ namespace ChanSort.Api } } - private ChannelInfo FindChannel(ChannelList tvList, ChannelInfo refChannel, Dictionary> onidTsidSid) + private ChannelInfo FindChannel(ChannelList tvList, int subListIndex, ChannelInfo refChannel, Dictionary> onidTsidSid) { - var tvChannels = refChannel.Uid == "0-0-0" ? null : tvList.GetChannelByUid(refChannel.Uid); + List candidates; - // try to find matching channels based on ONID+TSID+SID - if ((tvChannels?.Count ?? 0) == 0) + // try to find matching channels based on UID or ONID+TSID+SID+Transponder + var channels = refChannel.Uid == "0-0-0" ? new List() : tvList.GetChannelByUid(refChannel.Uid).ToList(); + if (channels.Count == 0) { var key = DvbKey(refChannel.OriginalNetworkId, refChannel.TransportStreamId, refChannel.ServiceId); - if (key != 0 && onidTsidSid.TryGetValue(key, out var candidates)) - { - tvChannels = candidates; + if (key != 0 && onidTsidSid.TryGetValue(key, out candidates)) + channels = candidates; - // narrow the list down further when a transponder is also provided (i.e. the same TV channel can be received on multiple DVB-T frequencies) - if (tvChannels.Count > 1 && !string.IsNullOrEmpty(refChannel.ChannelOrTransponder)) - { - candidates = tvChannels.Where(ch => ch.ChannelOrTransponder == refChannel.ChannelOrTransponder).ToList(); - if (candidates.Count > 0) - tvChannels = candidates; - } + // narrow the list down further when a transponder is also provided (i.e. the same channel can be received on multiple DVB-T frequencies) + if (channels.Count > 1 && !string.IsNullOrEmpty(refChannel.ChannelOrTransponder)) + { + candidates = channels.Where(ch => ch.ChannelOrTransponder == refChannel.ChannelOrTransponder).ToList(); + if (candidates.Count > 0) + channels = candidates; } } + var channel = channels.FirstOrDefault(c => c.GetPosition(subListIndex) == -1); + if (channel != null) + return channel; + // try to find matching channels by name - if ((tvChannels?.Count ?? 0) == 0 && !string.IsNullOrWhiteSpace(refChannel.Name)) - tvChannels = tvList.GetChannelByName(refChannel.Name).ToList(); + channels = tvList.GetChannelByName(refChannel.Name).Where(c => c.GetPosition(subListIndex) == -1).ToList(); - // get the first unassigned channel from the candidates (e.g. when matching by non-unique names), or fall back to the first matching channel (e.g. by unique ID) - ChannelInfo tvChannel = tvChannels.FirstOrDefault(c => c.GetPosition(0) == -1); - if (tvChannel == null && tvChannels.Count > 0) - tvChannel = tvChannels[0]; - return tvChannel; + // if the reference list has information about a service type (tv/radio/data), then only consider channels matching it (or lacking service type information) + var serviceType = refChannel.SignalSource & SignalSource.MaskTvRadioData; + if (serviceType != 0) + { + channels = channels.Where(ch => + { + var m = ch.SignalSource & SignalSource.MaskTvRadioData; + return m == 0 || m == serviceType; + }).ToList(); + } + + if (channels.Count == 0) + return null; + + if (channels.Count > 1) + { + // exact upper/lowercase matching (often there are channels like "DISCOVERY" and "Discovery") + candidates = channels.Where(c => c.Name == refChannel.Name).ToList(); + if (candidates.Count > 0) + channels = candidates; + } + if (channels.Count > 1) + { + // prefer unencrypted channels + candidates = channels.Where(c => c.Encrypted.HasValue && c.Encrypted.Value == false).ToList(); + if (candidates.Count > 0) + channels = candidates; + } + return channels[0]; } long DvbKey(int onid, int tsid, int sid) diff --git a/source/ChanSort.Loader.Sharp/SharpSerializer.cs b/source/ChanSort.Loader.Sharp/SharpSerializer.cs index b14ffe3..dd97398 100644 --- a/source/ChanSort.Loader.Sharp/SharpSerializer.cs +++ b/source/ChanSort.Loader.Sharp/SharpSerializer.cs @@ -72,6 +72,8 @@ namespace ChanSort.Loader.Sharp var content = File.ReadAllBytes(this.FileName); this.encoding = Tools.IsUtf8(content) ? new UTF8Encoding(false) : Encoding.GetEncoding(1252); this.lines = this.encoding.GetString(content).Replace("\r", "").Split('\n'); + if (lines.Length > 2) + this.cols = lines[2].ToLowerInvariant().Split(','); this.formatVersion = DetectFormatVersion(); this.AdjustVisibleColumns(); @@ -194,7 +196,6 @@ namespace ChanSort.Loader.Sharp return FormatVersion.Sharp7Columns; // fallback for formats with more information, as long as they contain the required columns - this.cols = lines[2].ToLowerInvariant().Split(','); var dict = new HashSet(); foreach (var col in cols) dict.Add(col); diff --git a/source/changelog.md b/source/changelog.md index 103ddfe..9a61b62 100644 --- a/source/changelog.md +++ b/source/changelog.md @@ -1,6 +1,10 @@ ChanSort Change Log =================== +2021-03-17 +- improved reference list channel matching: if multiple channels match the same name, then the candidates are narrowed + down by service type (TV/radio/data - if known), case sensitivity (upper/lowercase), encryption (unencrypted first) + 2021-03-16 - Sharp, Dyon, Blaupunkt, ...: added support for DVBS_Program.csv and \*DVBS_CHANNEL_TABLE.csv files - Enigma2: added support for Linux based Set-Top-Boxes (Dreambox, VU+, Octagon, ...) using lamedb and bouquets