mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-01-17 21:02:04 +01:00
- W.I.P: Enigma2 lamedb / bouquets support for Linux based Set-Top-Boxes (Dreambox, VU+, Octagon, ...)
- Toshiba settingsDB.db: support for lists without analog tuner data (missing TADTunerDataTable) - Grunding: failed to load lists where the <Digital> element did not contain a <channels> child element - W.I.P: reworking the reference list system so that a simple list of channels can be applied to the main channel numbers or a particular favorite list. (The "Automatically reorder all lists" options currently does not work)
This commit is contained in:
@@ -208,7 +208,7 @@ namespace ChanSort.Api
|
||||
log.AppendFormat("Skipped reference list {0}\r\n", refList.ShortCaption);
|
||||
continue;
|
||||
}
|
||||
ApplyReferenceList(refDataRoot, refList, tvList, true);
|
||||
ApplyReferenceList(refDataRoot, refList, -1, tvList, -1, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace ChanSort.Api
|
||||
/// </param>
|
||||
/// <param name="overwrite">controls whether Pr# will be reassigned to the reference channel when they are already in-use in the TV list</param>
|
||||
/// <param name="consecutive">when true, consecutive numbers will be used instead of the Pr# in the reference list when applying the order</param>
|
||||
public void ApplyReferenceList(DataRoot refDataRoot, ChannelList refList, ChannelList tvList, bool addProxyChannels = true, int positionOffset = 0, Func<ChannelInfo, bool, bool> chanFilter = null, bool overwrite = true, bool consecutive = false)
|
||||
public void ApplyReferenceList(DataRoot refDataRoot, ChannelList refList, int refListPosIndex, ChannelList tvList, int tvListPosIndex, bool addProxyChannels = true, int positionOffset = 0, Func<ChannelInfo, bool, bool> chanFilter = null, bool overwrite = true, bool consecutive = false)
|
||||
{
|
||||
// create Hashtable for exact channel lookup
|
||||
// the UID of a TV channel list contains a source-indicator (Analog, Cable, Sat), which may be undefined in the reference list)
|
||||
@@ -245,39 +245,12 @@ namespace ChanSort.Api
|
||||
}
|
||||
|
||||
var incNr = 1 + positionOffset;
|
||||
foreach (var refChannel in refList.Channels.OrderBy(ch => ch.OldProgramNr))
|
||||
foreach (var refChannel in refList.Channels.OrderBy(ch => ch.GetOldPosition(refListPosIndex)))
|
||||
{
|
||||
if (!(chanFilter?.Invoke(refChannel, true) ?? true))
|
||||
continue;
|
||||
|
||||
var tvChannels = refChannel.Uid == "0-0-0" ? null : tvList.GetChannelByUid(refChannel.Uid);
|
||||
|
||||
// try to find matching channels based on ONID+TSID+SID
|
||||
if ((tvChannels?.Count ?? 0) == 0)
|
||||
{
|
||||
var key = DvbKey(refChannel.OriginalNetworkId, refChannel.TransportStreamId, refChannel.ServiceId);
|
||||
if (key != 0 && onidTsidSid.TryGetValue(key, out var candidates))
|
||||
{
|
||||
tvChannels = 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try to find matching channels by name
|
||||
if ((tvChannels?.Count ?? 0) == 0 && !string.IsNullOrWhiteSpace(refChannel.Name))
|
||||
tvChannels = tvList.GetChannelByName(refChannel.Name).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];
|
||||
var tvChannel = FindChannel(tvList, refChannel, onidTsidSid);
|
||||
|
||||
if (tvChannel != null)
|
||||
{
|
||||
@@ -293,7 +266,7 @@ namespace ChanSort.Api
|
||||
foreach (var chan in curChans)
|
||||
chan.NewProgramNr = -1;
|
||||
|
||||
tvChannel.SetPosition(0, newNr);
|
||||
tvChannel.SetPosition(tvListPosIndex, newNr);
|
||||
if (refDataRoot.CanSkip && this.DataRoot.CanSkip)
|
||||
tvChannel.Skip = refChannel.Skip;
|
||||
if (refDataRoot.CanLock && this.DataRoot.CanLock)
|
||||
@@ -308,7 +281,8 @@ namespace ChanSort.Api
|
||||
tvChannel.IsNameModified = true;
|
||||
}
|
||||
|
||||
ApplyFavorites(refDataRoot, refChannel, tvChannel);
|
||||
if (tvListPosIndex == -1)
|
||||
ApplyFavorites(refDataRoot, refChannel, tvChannel);
|
||||
}
|
||||
else if (addProxyChannels)
|
||||
{
|
||||
@@ -318,6 +292,39 @@ namespace ChanSort.Api
|
||||
}
|
||||
}
|
||||
|
||||
private ChannelInfo FindChannel(ChannelList tvList, ChannelInfo refChannel, Dictionary<long, List<ChannelInfo>> onidTsidSid)
|
||||
{
|
||||
var tvChannels = refChannel.Uid == "0-0-0" ? null : tvList.GetChannelByUid(refChannel.Uid);
|
||||
|
||||
// try to find matching channels based on ONID+TSID+SID
|
||||
if ((tvChannels?.Count ?? 0) == 0)
|
||||
{
|
||||
var key = DvbKey(refChannel.OriginalNetworkId, refChannel.TransportStreamId, refChannel.ServiceId);
|
||||
if (key != 0 && onidTsidSid.TryGetValue(key, out var candidates))
|
||||
{
|
||||
tvChannels = 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try to find matching channels by name
|
||||
if ((tvChannels?.Count ?? 0) == 0 && !string.IsNullOrWhiteSpace(refChannel.Name))
|
||||
tvChannels = tvList.GetChannelByName(refChannel.Name).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;
|
||||
}
|
||||
|
||||
long DvbKey(int onid, int tsid, int sid)
|
||||
{
|
||||
return ((long)onid << 32) | ((long)tsid << 16) | (long)sid;
|
||||
@@ -332,9 +339,9 @@ namespace ChanSort.Api
|
||||
tvChannel.Favorites = refChannel.Favorites & DataRoot.SupportedFavorites;
|
||||
if (refDataRoot.SortedFavorites)
|
||||
{
|
||||
var c = Math.Min(refChannel.FavIndex.Count, tvChannel.OldFavIndex.Count);
|
||||
var c = Math.Min(refDataRoot.FavListCount, this.DataRoot.FavListCount);
|
||||
for (int i = 0; i < c; i++)
|
||||
tvChannel.FavIndex[i] = refChannel.OldFavIndex[i];
|
||||
tvChannel.SetPosition(i+1, refChannel.GetOldPosition(i+1));
|
||||
}
|
||||
else
|
||||
this.ApplyPrNrToFavLists(tvChannel);
|
||||
@@ -363,13 +370,13 @@ namespace ChanSort.Api
|
||||
if (sortedFav)
|
||||
{
|
||||
foreach (var channel in favList.Channels)
|
||||
maxPosition = Math.Max(maxPosition, channel.FavIndex[favIndex]);
|
||||
maxPosition = Math.Max(maxPosition, channel.GetPosition(favIndex+1));
|
||||
}
|
||||
|
||||
foreach (var channel in list)
|
||||
{
|
||||
if (sortedFav && channel.FavIndex[favIndex] == -1)
|
||||
channel.FavIndex[favIndex] = ++maxPosition;
|
||||
if (sortedFav && channel.GetPosition(favIndex+1) == -1)
|
||||
channel.SetPosition(favIndex+1,++maxPosition);
|
||||
channel.Favorites |= favMask;
|
||||
}
|
||||
}
|
||||
@@ -377,8 +384,8 @@ namespace ChanSort.Api
|
||||
{
|
||||
foreach (var channel in list)
|
||||
{
|
||||
if (sortedFav && channel.FavIndex[favIndex] != -1)
|
||||
channel.FavIndex[favIndex] = -1;
|
||||
if (sortedFav && channel.GetPosition(favIndex+1) != -1)
|
||||
channel.SetPosition(favIndex+1, -1);
|
||||
channel.Favorites &= ~favMask;
|
||||
}
|
||||
|
||||
@@ -386,10 +393,10 @@ namespace ChanSort.Api
|
||||
if (sortedFav && !this.DataRoot.AllowGapsInFavNumbers)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var channel in favList.Channels.OrderBy(c => c.FavIndex[favIndex]))
|
||||
foreach (var channel in favList.Channels.OrderBy(c => c.GetPosition(favIndex + 1)))
|
||||
{
|
||||
if (channel.FavIndex[favIndex] != -1)
|
||||
channel.FavIndex[favIndex] = ++i;
|
||||
if (channel.GetPosition(favIndex+1) != -1)
|
||||
channel.SetPosition(favIndex+1, ++i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -419,7 +426,7 @@ namespace ChanSort.Api
|
||||
var refMask = (ulong)tvChannel.Favorites;
|
||||
for (int i = 0; supMask != 0; i++)
|
||||
{
|
||||
tvChannel.FavIndex[i] = (refMask & 0x01) == 0 ? -1 : tvChannel.NewProgramNr;
|
||||
tvChannel.SetPosition(i+1, (refMask & 0x01) == 0 ? -1 : tvChannel.NewProgramNr);
|
||||
supMask >>= 1;
|
||||
refMask >>= 1;
|
||||
}
|
||||
@@ -439,13 +446,13 @@ namespace ChanSort.Api
|
||||
bool changed = false;
|
||||
for (int fav = 0; fav < favCount; fav++)
|
||||
{
|
||||
var list = channelList.Channels.Where(c => c.FavIndex[fav] >= 0).OrderBy(c => c.FavIndex[fav]).ToList();
|
||||
var list = channelList.Channels.Where(c => c.GetPosition(fav+1) >= 0).OrderBy(c => c.GetPosition(fav+1)).ToList();
|
||||
int i = 1;
|
||||
foreach (var channel in list)
|
||||
{
|
||||
if (channel.FavIndex[fav] != i)
|
||||
if (channel.GetPosition(fav+1) != i)
|
||||
{
|
||||
channel.FavIndex[fav] = ++i;
|
||||
channel.SetPosition(fav+1, ++i);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,11 +72,11 @@ namespace ChanSort.Api
|
||||
/// <summary>
|
||||
/// current number of the channel in the various favorite lists (if individual sorting is supported)
|
||||
/// </summary>
|
||||
public List<int> FavIndex { get; }
|
||||
private List<int> FavIndex { get; }
|
||||
/// <summary>
|
||||
/// original number of the channel in the various favorite lists (if individual sorting is supported)
|
||||
/// </summary>
|
||||
public List<int> OldFavIndex { get; }
|
||||
private List<int> OldFavIndex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// predefined LCN (logical channel number) assigned by TV firmware or cable/sat operator
|
||||
@@ -330,7 +330,7 @@ namespace ChanSort.Api
|
||||
this.NewProgramNr = newPos;
|
||||
else
|
||||
{
|
||||
for (int i=this.FavIndex.Count; i<=subListIndex;i++)
|
||||
for (int i = this.FavIndex.Count; i < subListIndex; i++)
|
||||
this.FavIndex.Add(-1);
|
||||
this.FavIndex[subListIndex - 1] = newPos;
|
||||
int mask = 1 << (subListIndex - 1);
|
||||
@@ -352,7 +352,7 @@ namespace ChanSort.Api
|
||||
this.OldProgramNr = oldPos;
|
||||
else
|
||||
{
|
||||
for (int i = this.OldFavIndex.Count; i <= subListIndex; i++)
|
||||
for (int i = this.OldFavIndex.Count; i < subListIndex; i++)
|
||||
this.OldFavIndex.Add(-1);
|
||||
this.OldFavIndex[subListIndex - 1] = oldPos;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace ChanSort.Api
|
||||
private int insertProgramNr = 1;
|
||||
private int duplicateUidCount;
|
||||
private int duplicateProgNrCount;
|
||||
public int FavListCount { get; set; }
|
||||
|
||||
|
||||
public static List<string> DefaultVisibleColumns { get; set; } = new List<string>(); // initialized by MainForm
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace ChanSort.Api
|
||||
public bool CanHide => this.loader.Features.CanHideChannels;
|
||||
public bool CanEditFavListName => this.loader.Features.CanEditFavListNames;
|
||||
|
||||
public int FavListCount { get; private set; }
|
||||
|
||||
public DataRoot(SerializerBase loader)
|
||||
{
|
||||
this.loader = loader;
|
||||
@@ -108,14 +110,12 @@ namespace ChanSort.Api
|
||||
#region ValidateAfterLoad()
|
||||
public virtual void ValidateAfterLoad()
|
||||
{
|
||||
this.FavListCount = 0;
|
||||
for (ulong m = (ulong)this.loader.Features.SupportedFavorites; m != 0; m >>= 1)
|
||||
++this.FavListCount;
|
||||
|
||||
foreach (var list in this.ChannelLists)
|
||||
{
|
||||
if (list.FavListCount == 0)
|
||||
{
|
||||
for (ulong m = (ulong) this.loader.Features.SupportedFavorites; m != 0; m >>= 1)
|
||||
++list.FavListCount;
|
||||
}
|
||||
|
||||
if (list.IsMixedSourceFavoritesList)
|
||||
{
|
||||
loader.Features.SortedFavorites = true; // all mixed source favorite lists must support ordering
|
||||
@@ -144,18 +144,11 @@ namespace ChanSort.Api
|
||||
#region ApplyCurrentProgramNumbers()
|
||||
public void ApplyCurrentProgramNumbers()
|
||||
{
|
||||
int c = 0;
|
||||
if (this.MixedSourceFavorites || this.SortedFavorites)
|
||||
{
|
||||
for (ulong m = (ulong) this.SupportedFavorites; m != 0; m >>= 1)
|
||||
++c;
|
||||
}
|
||||
|
||||
foreach (var list in this.ChannelLists)
|
||||
{
|
||||
foreach (var channel in list.Channels)
|
||||
{
|
||||
for (int i = 0; i <= c; i++)
|
||||
for (int i = 0; i <= this.FavListCount; i++)
|
||||
channel.SetPosition(i, channel.GetOldPosition(i));
|
||||
}
|
||||
}
|
||||
@@ -247,9 +240,8 @@ namespace ChanSort.Api
|
||||
chan.NewProgramNr = -1;
|
||||
}
|
||||
|
||||
chan.OldProgramNr = chan.NewProgramNr;
|
||||
chan.OldFavIndex.Clear();
|
||||
chan.OldFavIndex.AddRange(chan.FavIndex);
|
||||
for (int j=0; j<=this.FavListCount; j++)
|
||||
chan.SetOldPosition(j, chan.GetPosition(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace ChanSort.Loader.Enigma2
|
||||
/// <summary>
|
||||
/// first two fields of the lamedb entry
|
||||
/// </summary>
|
||||
public string Prefix { get; set; }
|
||||
public string Prefix { get; set; } = "1:0";
|
||||
|
||||
/// <summary>
|
||||
/// For DVB-S it is the orbital position * 10 (e.g. 192 for Astra 19.2E) * 65536
|
||||
@@ -15,11 +15,11 @@ namespace ChanSort.Loader.Enigma2
|
||||
public int DvbNamespace { get; set; }
|
||||
|
||||
public int ServiceNumber { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// all fields after the DVB-namespace in the lamedb entry
|
||||
/// </summary>
|
||||
public string Suffix { get; set; }
|
||||
public string Suffix { get; set; } = ":0:0:0:";
|
||||
|
||||
/// <summary>
|
||||
/// #DESCRIPTION of the userbouquet entry
|
||||
|
||||
@@ -84,14 +84,14 @@ namespace ChanSort.Loader.Enigma2
|
||||
LoadBouquets(path, ref favIndex);
|
||||
|
||||
// load all unlisted userbouquet files
|
||||
foreach (var file in Directory.GetFiles(Path.GetDirectoryName(this.FileName), "userbouquet.*"))
|
||||
{
|
||||
var ext = Path.GetExtension(file);
|
||||
if (ext != ".tv" && ext != ".radio") // ignore .del, .bak and other irrelevant files
|
||||
continue;
|
||||
if (!this.favListFileNames.Contains(file))
|
||||
this.LoadUserBouquet(file, ref favIndex);
|
||||
}
|
||||
//foreach (var file in Directory.GetFiles(Path.GetDirectoryName(this.FileName), "userbouquet.*"))
|
||||
//{
|
||||
// var ext = Path.GetExtension(file);
|
||||
// if (ext != ".tv" && ext != ".radio") // ignore .del, .bak and other irrelevant files
|
||||
// continue;
|
||||
// if (!this.favListFileNames.Contains(file))
|
||||
// this.LoadUserBouquet(file, ref favIndex);
|
||||
//}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -188,7 +188,6 @@ namespace ChanSort.Loader.Enigma2
|
||||
ch.RecordIndex = chanId;
|
||||
ch.RecordOrder = chanId;
|
||||
ch.OldProgramNr = ++chanId;
|
||||
ch.NewProgramNr = chanId;
|
||||
ch.IsDeleted = false;
|
||||
ch.ServiceId = FromHex(parts[0]);
|
||||
ch.DvbNamespace = FromHex(parts[1]);
|
||||
@@ -254,7 +253,7 @@ namespace ChanSort.Loader.Enigma2
|
||||
#region LoadUserBoquet
|
||||
private void LoadUserBouquet(string file, ref int favIndex)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
if (!File.Exists(file) || this.favListFileNames.Contains(file))
|
||||
return;
|
||||
|
||||
using var r = new StreamReader(File.OpenRead(file), utf8WithoutBom);
|
||||
|
||||
@@ -194,7 +194,10 @@ namespace ChanSort.Loader.Grundig
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (XmlNode networkNode in digital["channels"].ChildNodes)
|
||||
var channels = digital["channels"];
|
||||
if (channels == null)
|
||||
return;
|
||||
foreach (XmlNode networkNode in channels.ChildNodes)
|
||||
{
|
||||
if (networkNode.LocalName != "network")
|
||||
continue;
|
||||
@@ -361,7 +364,7 @@ namespace ChanSort.Loader.Grundig
|
||||
if (ch.IsNameModified)
|
||||
att["name"].Value = ch.Name;
|
||||
for (int i=1; i<=4; i++)
|
||||
att["f"+i].Value = Math.Max(0, ch.FavIndex[i-1]).ToString(); // convert -1 to 0
|
||||
att["f"+i].Value = Math.Max(0, ch.GetPosition(i)).ToString(); // convert -1 to 0
|
||||
att["skp"].InnerText = ch.Skip ? "1" : "0";
|
||||
att["lck"].InnerText = ch.Lock ? "1" : "0";
|
||||
if ((ch.SignalSource & SignalSource.Digital) != 0)
|
||||
|
||||
@@ -442,7 +442,7 @@ namespace ChanSort.Loader.Hisense.ChannelDb
|
||||
var id = ((long) r.GetInt32(0) << 32) | (uint) r.GetInt32(1);
|
||||
var ci = this.channelsById.TryGet(id);
|
||||
if (ci != null)
|
||||
ci.OldFavIndex[i - 1] = r.GetInt32(2);
|
||||
ci.SetOldPosition(i, r.GetInt32(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -608,7 +608,7 @@ namespace ChanSort.Loader.Hisense.ChannelDb
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (ci.FavIndex[i] <= 0)
|
||||
if (ci.GetPosition(i+1) <= 0)
|
||||
{
|
||||
cmd.CommandText = $"delete from fav_{i + 1} where ui2_svc_id={ci.RecordIndex >> 32} and ui2_svc_rec_id={ci.RecordIndex & 0xFFFFFFFF}";
|
||||
cmd.ExecuteNonQuery();
|
||||
@@ -621,7 +621,7 @@ namespace ChanSort.Loader.Hisense.ChannelDb
|
||||
cmd.Parameters.Add("@name", DbType.String);
|
||||
cmd.Parameters.Add("@svcid", DbType.Int32);
|
||||
cmd.Parameters.Add("@recid", DbType.Int32);
|
||||
cmd.Parameters["@chnr"].Value = ci.FavIndex[i].ToString();
|
||||
cmd.Parameters["@chnr"].Value = ci.GetPosition(i+1).ToString();
|
||||
cmd.Parameters["@name"].Value = ci.Name;
|
||||
cmd.Parameters["@svcid"].Value = ci.RecordIndex >> 32;
|
||||
cmd.Parameters["@recid"].Value = ci.RecordIndex & 0xFFFF;
|
||||
@@ -640,7 +640,7 @@ namespace ChanSort.Loader.Hisense.ChannelDb
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (ci.FavIndex[i] <= 0)
|
||||
if (ci.GetPosition(i+1) <= 0)
|
||||
continue;
|
||||
|
||||
cmd.CommandText = $"insert into fav_{i + 1} (sortId, channelId, svlId, channelName, svlRecId, nwMask) values (@chnr,@chanid,@svcid,@name,@recid,@nwmask)";
|
||||
@@ -651,7 +651,7 @@ namespace ChanSort.Loader.Hisense.ChannelDb
|
||||
cmd.Parameters.Add("@name", DbType.String);
|
||||
cmd.Parameters.Add("@recid", DbType.Int32);
|
||||
cmd.Parameters.Add("@nwmask", DbType.Int32);
|
||||
cmd.Parameters["@chnr"].Value = ci.FavIndex[i];
|
||||
cmd.Parameters["@chnr"].Value = ci.GetPosition(i+1);
|
||||
cmd.Parameters["@chanid"].Value = ci.ChannelId;
|
||||
cmd.Parameters["@name"].Value = ci.Name;
|
||||
cmd.Parameters["@svcid"].Value = ci.RecordIndex >> 32;
|
||||
|
||||
@@ -358,7 +358,7 @@ left outer join Lcn l on l.ServiceId=fi.ServiceId and l.FavoriteId=fi.FavoriteId
|
||||
|
||||
int favListIdx = favListIdToFavIndex.TryGet(favListId, -1);
|
||||
if (favListIdx >= 0)
|
||||
ci.OldFavIndex[favListIdx] = r.GetInt32(2);
|
||||
ci.SetOldPosition(favListIdx+1, r.GetInt32(2));
|
||||
|
||||
ci.SetOldPosition(favListIdx + 1, r.GetInt32(2)); // 0=main nr, 1-4=fav 1-4
|
||||
if (favListIdx < 0)
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace ChanSort.Loader.Panasonic
|
||||
if (favIndex > 0)
|
||||
{
|
||||
this.Favorites |= (Favorites) (1 << i);
|
||||
this.OldFavIndex[i] = favIndex;
|
||||
this.SetOldPosition(i, favIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ order by s.ntype,major_channel
|
||||
cmd.Parameters["@progNr"].Value = channel.NewProgramNr;
|
||||
cmd.Parameters["@sname"].Value = channel.RawName;
|
||||
for (int fav = 0; fav < 4; fav++)
|
||||
cmd.Parameters["@fav" + (fav + 1)].Value = Math.Max(0, channel.FavIndex[fav]);
|
||||
cmd.Parameters["@fav" + (fav + 1)].Value = Math.Max(0, channel.GetPosition(fav+1));
|
||||
cmd.Parameters["@lock"].Value = channel.Lock;
|
||||
cmd.Parameters["@skip"].Value = channel.Skip;
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
@@ -901,7 +901,7 @@ namespace ChanSort.Loader.Philips
|
||||
var recordSize = 4;
|
||||
var recordCount = (dataSize - 4) / recordSize;
|
||||
|
||||
var favList = this.dvbsChannels.Channels.Where(c => c.FavIndex[0] != -1).OrderBy(c => c.FavIndex[0]).ToList();
|
||||
var favList = this.dvbsChannels.Channels.Where(c => c.GetPosition(1) != -1).OrderBy(c => c.GetPosition(1)).ToList();
|
||||
var favCount = favList.Count;
|
||||
var firstFavIndex = favCount == 0 ? -1 : (int)favList[0].RecordIndex;
|
||||
data.SetInt16(4, firstFavIndex);
|
||||
|
||||
@@ -432,7 +432,7 @@ namespace ChanSort.Loader.Philips
|
||||
foreach (var chan in rootList.Channels)
|
||||
{
|
||||
favChannels.Channels.Add(chan);
|
||||
for (int i=0; i<chan.FavIndex.Count; i++)
|
||||
for (int i=0; i<this.DataRoot.FavListCount; i++)
|
||||
chan.SetOldPosition(i+1, -1);
|
||||
}
|
||||
}
|
||||
@@ -547,7 +547,7 @@ namespace ChanSort.Loader.Philips
|
||||
|
||||
// ChannelMap_100 supports a single fav list and stores the favorite number directly here in the channel.
|
||||
// ChannelMap_105 and later always store the value 0 in the channel and instead use a separate Favorites.xml file.
|
||||
ch.SetupNode.Attributes["FavoriteNumber"].Value = setFavoriteNumber ? Math.Max(ch.FavIndex[0], 0).ToString() : "0";
|
||||
ch.SetupNode.Attributes["FavoriteNumber"].Value = setFavoriteNumber ? Math.Max(ch.GetPosition(1), 0).ToString() : "0";
|
||||
|
||||
if (ch.OldProgramNr != ch.NewProgramNr)
|
||||
{
|
||||
|
||||
@@ -188,7 +188,7 @@ namespace ChanSort.Loader.Samsung.Scm
|
||||
if (this.sortedFavorites == FavoritesIndexMode.Boolean) // D series
|
||||
favValue = (fav & mask) != 0 ? 1 : 0; // D series
|
||||
else if (this.sortedFavorites == FavoritesIndexMode.IndividuallySorted) // E series (and some F models with early firmware)
|
||||
favValue = (fav & mask) != 0 ? this.FavIndex[favIndex] : -1;
|
||||
favValue = (fav & mask) != 0 ? this.GetPosition(favIndex+1) : -1;
|
||||
else
|
||||
favValue = (fav & mask) != 0 ? this.NewProgramNr : -1; // F series (newer models/firmware), H series
|
||||
|
||||
|
||||
@@ -383,7 +383,7 @@ namespace ChanSort.Loader.Samsung.Zip
|
||||
if (pos >= 0)
|
||||
{
|
||||
channel.Favorites |= (Favorites) (1 << fav);
|
||||
channel.OldFavIndex[fav] = pos;
|
||||
channel.SetOldPosition(fav+1, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -634,7 +634,7 @@ namespace ChanSort.Loader.Samsung.Zip
|
||||
cmdDeleteFav.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
channel.FavIndex[i] = newPos;
|
||||
channel.SetPosition(i+1, newPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ namespace ChanSort.Loader.Sony
|
||||
for (int j = 0; j < 4 && j < favNumbers.Length; j++)
|
||||
{
|
||||
if (int.TryParse(favNumbers[j], out var favNr) && favNr > 0)
|
||||
chan.OldFavIndex[j] = favNr;
|
||||
chan.SetOldPosition(j+1, favNr);
|
||||
}
|
||||
}
|
||||
var muxId = int.Parse(svcData["MuxID"][i]) + idAdjustment;
|
||||
@@ -752,7 +752,7 @@ namespace ChanSort.Loader.Sony
|
||||
{
|
||||
var vals = value.Split(' ');
|
||||
for (int i = 0; i < 4; i++)
|
||||
vals[i] = ch.FavIndex[i] <= 0 ? "0" : ch.FavIndex[i].ToString();
|
||||
vals[i] = ch.GetPosition(i+1) <= 0 ? "0" : ch.GetPosition(i+1).ToString();
|
||||
return string.Join(" ", vals);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ namespace ChanSort.Loader.Toshiba
|
||||
{
|
||||
private readonly ChannelList channels = new ChannelList(SignalSource.All, "All");
|
||||
|
||||
private readonly HashSet<string> tableNames = new();
|
||||
|
||||
#region ctor()
|
||||
public SettingsDbSerializer(string inputFile) : base(inputFile)
|
||||
{
|
||||
@@ -32,6 +34,15 @@ namespace ChanSort.Loader.Toshiba
|
||||
this.Features.SupportedFavorites = 0;
|
||||
|
||||
this.DataRoot.AddChannelList(this.channels);
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Lock));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Skip));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Hidden));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Encrypted));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.PcrPid));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.VideoPid));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.AudioPid));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Satellite));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.ShortName));
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -63,12 +74,19 @@ namespace ChanSort.Loader.Toshiba
|
||||
string sysDataConnString = "Data Source=" + this.FileName;
|
||||
using var conn = new SQLiteConnection(sysDataConnString);
|
||||
conn.Open();
|
||||
|
||||
using var cmd = conn.CreateCommand();
|
||||
|
||||
this.RepairCorruptedDatabaseImage(cmd);
|
||||
|
||||
cmd.CommandText = "SELECT count(1) FROM sqlite_master WHERE type = 'table' and name='EASISerTable'";
|
||||
if (Convert.ToInt32(cmd.ExecuteScalar()) != 1)
|
||||
cmd.CommandText = "SELECT name FROM sqlite_master WHERE type = 'table'";
|
||||
using (var r = cmd.ExecuteReader())
|
||||
{
|
||||
while (r.Read())
|
||||
this.tableNames.Add(r.GetString(0).ToLowerInvariant());
|
||||
}
|
||||
|
||||
if (!this.tableNames.Contains("easisertable"))
|
||||
throw new FileLoadException("File doesn't contain the expected tables");
|
||||
|
||||
this.ReadSatellites(cmd);
|
||||
@@ -135,23 +153,27 @@ namespace ChanSort.Loader.Toshiba
|
||||
{
|
||||
int ixE = 0;
|
||||
int ixD = 3;
|
||||
int ixA = 8;
|
||||
int ixT = 9;
|
||||
int ixA = 9;
|
||||
int ixDC = 10;
|
||||
int ixT = 12;
|
||||
|
||||
cmd.CommandText = @"
|
||||
var hasTADTunerDataTable = this.tableNames.Contains("tadtunerdatatable");
|
||||
string analogTunerFields = hasTADTunerDataTable ? ",t.frequency_in_multiples_of_10Hz" : "";
|
||||
string analogTunerTable = hasTADTunerDataTable ? " left outer join TADTunerDataTable t on t.channel=ac.channel_no" : "";
|
||||
cmd.CommandText = $@"
|
||||
select
|
||||
e.m_handle, e.m_rsn, e.m_name_serialized,
|
||||
d.m_onid, d.m_tsid, d.m_id, d.m_type, d.m_name_serialized,
|
||||
d.m_onid, d.m_tsid, d.m_id, d.m_type, d.m_name_serialized, d.m_provider_serialized,
|
||||
a.m_name_serialized,
|
||||
t.frequency_in_multiples_of_10Hz,
|
||||
dc.frequency
|
||||
dc.frequency, dc.symbol_rate
|
||||
{analogTunerFields}
|
||||
from EASISerTable e
|
||||
left outer join DVBSerTable d on d.m_handle=e.m_handle
|
||||
left outer join AnalogSerTable a on a.m_handle=e.m_handle
|
||||
left outer join ChanDataTable dc on dc.handle=d.m_channel_no
|
||||
left outer join ChanDataTable ac on ac.handle=a.m_channel_no
|
||||
left outer join TADTunerDataTable t on t.channel=ac.channel_no";
|
||||
{analogTunerTable}";
|
||||
|
||||
using var r = cmd.ExecuteReader();
|
||||
while (r.Read())
|
||||
{
|
||||
@@ -166,12 +188,16 @@ left outer join TADTunerDataTable t on t.channel=ac.channel_no";
|
||||
channel.OriginalNetworkId = r.GetInt32(ixD + 0) & 0x1FFF;
|
||||
channel.TransportStreamId = r.GetInt32(ixD + 1) & 0x1FFF;
|
||||
channel.ServiceId = r.GetInt32(ixD + 2) & 0x1FFF;
|
||||
channel.ServiceType = r.GetInt32(ixD + 3);
|
||||
channel.ServiceType = r.GetInt32(ixD + 3) & 0x1FFF;
|
||||
channel.Provider = r.GetString(ixD + 5);
|
||||
channel.FreqInMhz = (decimal) r.GetInt32(ixDC + 0) / 1000;
|
||||
channel.SymbolRate = r.GetInt32(ixDC + 1);
|
||||
if (channel.FreqInMhz > 10000)
|
||||
channel.FreqInMhz = (int) channel.FreqInMhz;
|
||||
}
|
||||
|
||||
// analog
|
||||
if (!r.IsDBNull(ixA + 0))
|
||||
if (!r.IsDBNull(ixA + 0) && hasTADTunerDataTable)
|
||||
{
|
||||
channel.FreqInMhz = (decimal) r.GetInt32(ixT + 0) / 100000;
|
||||
}
|
||||
|
||||
@@ -479,7 +479,7 @@ namespace ChanSort.Ui
|
||||
this.tabSubList.TabPages[i].Text = this.DataRoot.GetFavListCaption(i - 1, true);
|
||||
this.tabSubList.EndUpdate();
|
||||
|
||||
if (!this.DataRoot.SortedFavorites || this.subListIndex >= favCount)
|
||||
if (!this.DataRoot.SortedFavorites || this.subListIndex > favCount)
|
||||
{
|
||||
this.tabSubList.SelectedTabPageIndex = 0;
|
||||
this.subListIndex = 0;
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace ChanSort.Ui
|
||||
|
||||
class ListOption
|
||||
{
|
||||
private DataRoot root;
|
||||
public ChannelList ChannelList { get; }
|
||||
public int PosIndex { get; }
|
||||
|
||||
@@ -125,6 +124,7 @@ namespace ChanSort.Ui
|
||||
this.edFile.Text = serializer.FileName;
|
||||
this.rbAuto.Enabled = this.rbManual.Enabled = true;
|
||||
ser.DataRoot.ApplyCurrentProgramNumbers();
|
||||
ser.DataRoot.ValidateAfterLoad();
|
||||
|
||||
this.comboSource.EditValue = null;
|
||||
this.comboSource.Properties.Items.Clear();
|
||||
@@ -132,13 +132,12 @@ namespace ChanSort.Ui
|
||||
{
|
||||
if (list.Channels.Count == 0)
|
||||
continue;
|
||||
if (list.IsMixedSourceFavoritesList)
|
||||
{
|
||||
for (int i = 0; i <= list.FavListCount; i++)
|
||||
this.comboSource.Properties.Items.Add(new ListOption(list, i, list + (i==0 ? "" : " - " + serializer.DataRoot.GetFavListCaption(i-1))));
|
||||
}
|
||||
else
|
||||
|
||||
if (!list.IsMixedSourceFavoritesList)
|
||||
this.comboSource.Properties.Items.Add(new ListOption(list, 0, list.Caption));
|
||||
|
||||
for (int i = 1; i <= serializer.DataRoot.FavListCount; i++)
|
||||
this.comboSource.Properties.Items.Add(new ListOption(list, i, list + " - " + serializer.DataRoot.GetFavListCaption(i-1)));
|
||||
}
|
||||
|
||||
this.comboTarget.EditValue = null;
|
||||
@@ -149,7 +148,7 @@ namespace ChanSort.Ui
|
||||
continue;
|
||||
if (list.IsMixedSourceFavoritesList)
|
||||
{
|
||||
for (int i = 0; i <= list.FavListCount; i++)
|
||||
for (int i = 0; i <= main.DataRoot.FavListCount; i++)
|
||||
this.comboTarget.Properties.Items.Add(new ListOption(list, i, list + (i==0 ? "" : " - " + main.DataRoot.GetFavListCaption(i-1))));
|
||||
}
|
||||
else
|
||||
@@ -341,7 +340,7 @@ namespace ChanSort.Ui
|
||||
switch (dlg.ShowDialog(this))
|
||||
{
|
||||
case DialogResult.OK:
|
||||
target.ChannelList.Channels.ForEach(ch => ch.NewProgramNr = -1);
|
||||
target.ChannelList.Channels.ForEach(ch => ch.SetPosition(target.PosIndex, -1));
|
||||
break;
|
||||
case DialogResult.Yes:
|
||||
//overwrite = true;
|
||||
@@ -355,7 +354,7 @@ namespace ChanSort.Ui
|
||||
}
|
||||
}
|
||||
|
||||
main.Editor.ApplyReferenceList(this.serializer.DataRoot, src.ChannelList, target.ChannelList, false, offset, FilterChannel, overwrite, this.cbConsecutive.Checked);
|
||||
main.Editor.ApplyReferenceList(this.serializer.DataRoot, src.ChannelList, src.PosIndex, target.ChannelList, target.PosIndex, false, offset, FilterChannel, overwrite, this.cbConsecutive.Checked);
|
||||
main.RefreshGrids();
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Test.Loader.M3u
|
||||
ed.DataRoot = ser.DataRoot;
|
||||
ed.ChannelList = lists[0];
|
||||
//ed.ApplyReferenceList(refSer.DataRoot);
|
||||
ed.ApplyReferenceList(refSer.DataRoot, refSer.DataRoot.ChannelLists.First(), lists[0], false, 0, null, true, false);
|
||||
ed.ApplyReferenceList(refSer.DataRoot, refSer.DataRoot.ChannelLists.First(), 0, lists[0], 0,false, 0, null, true, false);
|
||||
|
||||
Assert.AreEqual(1, chans[5].NewProgramNr);
|
||||
Assert.AreEqual(2, chans[4].NewProgramNr);
|
||||
|
||||
@@ -88,9 +88,9 @@ namespace Test.Loader.Philips
|
||||
var ch8 = list.Channels.FirstOrDefault(ch => ch.RecordIndex == 8);
|
||||
Assert.IsTrue(ch8.IsDeleted);
|
||||
|
||||
Assert.AreEqual(1, ch4.OldFavIndex[0]);
|
||||
Assert.AreEqual(2, ch7.OldFavIndex[0]);
|
||||
Assert.AreEqual(3, ch3.OldFavIndex[0]);
|
||||
Assert.AreEqual(1, ch4.GetOldPosition(1));
|
||||
Assert.AreEqual(2, ch7.GetOldPosition(1));
|
||||
Assert.AreEqual(3, ch3.GetOldPosition(1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
ChanSort Change Log
|
||||
===================
|
||||
|
||||
2021-03-13 (alpha)
|
||||
- Enigma2 lamedb / bouquets support for Linux based Set-Top-Boxes (Dreambox, VU+, Octagon, ...)
|
||||
- Toshiba settingsDB.db: support for lists without analog tuner data (missing TADTunerDataTable)
|
||||
- Grunding: failed to load lists where the <Digital> element did not contain a <channels> child element
|
||||
- W.I.P: reworking the reference list system so that a given flat list of channels can be applied to the
|
||||
main channel numbers or a particular favorite list.
|
||||
|
||||
2021-02-24
|
||||
- Philips ChannelMap\_45: TV did not remember last selected favorite list when first fav list was created by ChanSort.
|
||||
- Philips ChannelMap\_100 and later: "Channel" XML elements inside the DVB\*.xml files are now reordered by program nr.
|
||||
|
||||
Reference in New Issue
Block a user