2020-12-26

- LG WebOS 5: added warning that support is only experimental.
- Panasonic: Channel name editing is now supported for svl.bin files (unless there is no indicator what encoding to use)
- Hungarian translation: added missing files to .zip
This commit is contained in:
Horst Beham
2020-12-26 16:51:33 +01:00
parent 6584a666c6
commit e7bb88c554
7 changed files with 173 additions and 65 deletions

View File

@@ -1,6 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ChanSort.Api;
@@ -9,6 +7,11 @@ using Newtonsoft.Json.Linq;
namespace ChanSort.Loader.GlobalClone
{
/*
* LG's webOS 5 firmware has severe limitations (or bugs) regarding the import of channel lists (at the time of this writing, end of 2020).
* There have been a few reports about successful imports, but no conclusions about steps that guarantee success.
* More information can be found on https://github.com/PredatH0r/ChanSort/discussions/207
*/
internal class GcJsonSerializer : SerializerBase
{
private readonly string content;
@@ -16,14 +19,11 @@ namespace ChanSort.Loader.GlobalClone
string xmlSuffix;
private JObject doc;
//private readonly ChannelList tvList = new ChannelList(SignalSource.MaskAdInput | SignalSource.Tv, "TV");
//private readonly ChannelList radioList = new ChannelList(SignalSource.MaskAdInput | SignalSource.Radio, "Radio");
public GcJsonSerializer(string filename, string content) : base(filename)
{
this.content = content;
this.Features.DeleteMode = DeleteMode.FlagWithoutPrNr;
this.Features.DeleteMode = DeleteMode.NotSupported; //.FlagWithoutPrNr;
this.Features.ChannelNameEdit = ChannelNameEditMode.All;
this.Features.SupportedFavorites = 0;
this.Features.CanSaveAs = true;
@@ -40,11 +40,6 @@ namespace ChanSort.Loader.GlobalClone
this.DataRoot.AddChannelList(new ChannelList(SignalSource.DvbC | SignalSource.Radio, "DVB-C Radio"));
this.DataRoot.AddChannelList(new ChannelList(SignalSource.DvbS | SignalSource.Tv | SignalSource.Data, "DVB-S TV"));
this.DataRoot.AddChannelList(new ChannelList(SignalSource.DvbS | SignalSource.Radio, "DVB-S Radio"));
//this.DataRoot.AddChannelList(tvList);
//this.DataRoot.AddChannelList(radioList);
//foreach(var list in this.DataRoot.ChannelLists)
// list.VisibleColumnFieldNames.Add("Source");
}
@@ -71,6 +66,32 @@ namespace ChanSort.Loader.GlobalClone
this.doc = JObject.Parse(json);
LoadSatellites();
LoadChannels();
if (View.Default == null) // can't show dialog while unit-testing
return;
var dlg = View.Default.CreateActionBox("!!! WARNING !!!\n\n" +
"Support for LG webOS 5 channel lists is experimental only!\n" +
"There is a HIGH RISK that your TV will not import the list correctly and you need to run a new search or even reset the TV.\n" +
"Please read the information on github with steps that MAY lead to a successful import.\n" +
"Any feedback about failure or success is highly appreciated.");
dlg.AddAction("Read information about webOS 5 support on github.com", 1);
dlg.AddAction("I read the information, accept the risk and want to give it a try", 2);
dlg.AddAction("Cancel", 0);
while (true)
{
dlg.ShowDialog();
switch (dlg.SelectedAction)
{
case 0:
throw new FileLoadException("LG webOS 5 experimental support rejected");
case 1:
System.Diagnostics.Process.Start("https://github.com/PredatH0r/ChanSort/discussions/207");
break;
case 2:
return;
}
}
}
#region LoadSatellites()
@@ -246,49 +267,22 @@ namespace ChanSort.Loader.GlobalClone
node["skipped"] = ch.Skip;
node["locked"] = ch.Lock;
node["Invisible"] = ch.Hidden;
if (ch.NewProgramNr != Math.Max(ch.OldProgramNr, 0))
{
node["userEditChNumber"] = true;
node["userSelCHNo"] = true;
}
//node["disableUpdate"] = true; // experimental to prevent "DTV Auto Update" of channel numbers right after importing the list
// the only successfully imported file was one where these flags were NOT set by ChanSort
// these flags do get set when changing numbers through the TV's menu, but then prevent further modifications, e.g. through an import
//if (ch.NewProgramNr != Math.Max(ch.OldProgramNr, 0))
//{
// node["userEditChNumber"] = false;
// node["userSelCHNo"] = false;
//}
//node["disableUpdate"] = true; // No-Go! This blocked the whole list and required a factory reset. Regardless of the setting, the TV showed wrong numbers.
//node["factoryDefault"] = true; // an exported file after manually changing numbers through the TV-menu had all channels set to userEditChNumber=true, userSelCHNo=true, factoryDefault=true;
}
}
// it seems that channels must also be physically ordered by majorNumber
//var chList = this.doc["channelList"].Value<IList>();
//var copy = new ArrayList(chList);
//var comp = new ChannelOrderComparer(this.SourceIndexOrder);
//copy.Sort(comp);
//chList.Clear();
//foreach (var item in copy)
// chList.Add(item);
}
#endregion
//class ChannelOrderComparer : IComparer
//{
// private readonly IList<string> sourceIndexOrder;
// public ChannelOrderComparer(IList<string> sourceIndexOrder)
// {
// this.sourceIndexOrder = sourceIndexOrder;
// }
// public int Compare(object x, object y)
// {
// GcChannel<JToken> a = (GcChannel<JToken>)x;
// GcChannel<JToken> b = (GcChannel<JToken>)y;
// var i = sourceIndexOrder.IndexOf((string)a.Node["sourceIndex"]);
// var j = sourceIndexOrder.IndexOf((string)b.Node["sourceIndex"]);
// if (i != j)
// return i < j ? -1 : +1;
// return 0;
// }
//}
}
}

View File

@@ -238,5 +238,18 @@ namespace ChanSort.Loader.Panasonic
shortName = sbShort.ToString();
}
#endregion
#region UpdateRawData()
public override void UpdateRawData()
{
if (IsNameModified)
{
var utf8 = Encoding.UTF8.GetBytes(this.Name);
this.RawName = new byte[utf8.Length + 1];
this.RawName[0] = 0x15; // DVB encoding ID for UTF8
Array.Copy(utf8, 0, this.RawName, 1, utf8.Length);
}
}
#endregion
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Drawing;
using System.IO;
using System.Text;
using ChanSort.Api;
@@ -253,9 +254,11 @@ order by s.ntype,major_channel
{
while (r.Read())
{
ChannelInfo channel = new DbChannel(r, fields, this.DataRoot, this.DefaultEncoding);
var channel = new DbChannel(r, fields, this.DataRoot, this.DefaultEncoding);
if (!channel.IsDeleted)
{
if (channel.RawName.Length > 0 && channel.RawName[0] == 0x15) // if there is a channel with a 0x15 encoding ID (UTF-8), we can allow editing channels
this.Features.ChannelNameEdit = ChannelNameEditMode.All;
var channelList = this.DataRoot.GetChannelList(channel.SignalSource);
this.DataRoot.AddChannel(channelList, channel);
}
@@ -324,10 +327,11 @@ order by s.ntype,major_channel
#region WriteChannels()
private void WriteChannels(SQLiteCommand cmd, ChannelList channelList)
{
cmd.CommandText = "update SVL set major_channel=@progNr, profile1index=@fav1, profile2index=@fav2, profile3index=@fav3, profile4index=@fav4, child_lock=@lock, skip=@skip where rowid=@rowid";
cmd.CommandText = "update SVL set major_channel=@progNr, sname=@sname, profile1index=@fav1, profile2index=@fav2, profile3index=@fav3, profile4index=@fav4, child_lock=@lock, skip=@skip where rowid=@rowid";
cmd.Parameters.Clear();
cmd.Parameters.Add(new SQLiteParameter("@rowid", DbType.Int32));
cmd.Parameters.Add(new SQLiteParameter("@progNr", DbType.Int32));
cmd.Parameters.Add(new SQLiteParameter("@sname", DbType.Binary));
cmd.Parameters.Add(new SQLiteParameter("@fav1", DbType.Int32));
cmd.Parameters.Add(new SQLiteParameter("@fav2", DbType.Int32));
cmd.Parameters.Add(new SQLiteParameter("@fav3", DbType.Int32));
@@ -342,8 +346,10 @@ order by s.ntype,major_channel
continue;
if (channel.IsDeleted && channel.OldProgramNr >= 0)
continue;
channel.UpdateRawData();
cmd.Parameters["@rowid"].Value = channel.RecordIndex;
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["@lock"].Value = channel.Lock;

View File

@@ -58,6 +58,7 @@ namespace ChanSort.Ui
button.Left = 10;
button.Height = ButtonHeight;
button.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
button.Padding = new Padding(20,button.Padding.Top, 20, button.Padding.Bottom);
button.Tag = result;
button.Click += button_Click;

View File

@@ -17,24 +17,28 @@ namespace Spike.LgWebOs5
{
basedir = args.Length > 0 ? args[0] : @"d:\sources\chansort\testfiles_lg";
using var stream = new FileStream("c:\\temp\\lg.csv", FileMode.Create);
using var stream = new FileStream(@"d:\sources\chansort\testfiles_lg\__webOS5\lg.csv", FileMode.Create);
using var csv = new StreamWriter(stream, Encoding.UTF8);
var sources = new[] { "All", "Analog", "DVB-T", "DVB-C", "DVB-S", "Others" };
var fields = ChanListStats.ColumnHeaders;
csv.Write("\t\t\t\t\t\t\t\t");
string skip = "";
for (int i = 0; i < fields.Length - 1; i++)
skip += "\t";
foreach(var src in sources)
csv.Write("\t" + src + skip);
bool detailed = true;
foreach (var src in sources)
{
csv.Write("\t" + src + Dup("\t", (detailed ? ChanListStats.ColumnHeadersLong.Length : ChanListStats.ColumnHeadersShort.Length) - 1));
detailed = false;
}
csv.WriteLine();
csv.Write("Path\tStatus\tModelName\tVersion\tDTVInfo\tBroadcastCountrySettings\tcountry\tFW info\t#channels");
detailed = true;
foreach (var source in sources)
{
foreach(var field in fields)
var fields = detailed ? ChanListStats.ColumnHeadersLong : ChanListStats.ColumnHeadersShort;
foreach (var field in fields)
csv.Write("\t" + field);
detailed = false;
}
csv.WriteLine();
@@ -183,10 +187,18 @@ namespace Spike.LgWebOs5
all += entry.Value;
}
sb.Append(all.ToString() + a + t + c + s + o);
sb.Append(all.ToString(true) + a + t + c + s + o);
return sb.ToString();
}
#endregion
private static string Dup(string str, int count)
{
var sb = new StringBuilder(str.Length * count);
for (int i = 0; i < count; i++)
sb.Append(str);
return sb.ToString();
}
}
#region class ChanListStats
@@ -204,20 +216,56 @@ namespace Spike.LgWebOs5
public bool deletedMajor0 = false;
public bool deletedMajorNon0 = false;
public static readonly string[] ColumnHeaders = {
public int UserEditChNumber;
public int UserSelChNo;
public int FactoryDefault;
public int Disabled;
public int Skipped;
public int Invisible;
public int Locked;
public int Deleted;
public int Discarded;
public int UserCustomize;
public int NumUnSel;
public int Lcn;
public static readonly string[] ColumnHeadersLong = {
"TV", "Radio",
// "Rad 0/4K", "BadSvcType",
"InOrder",
"InOrder/Gaps",
"Del0/!0",
"UserEdit",
"FactDef",
"LCN",
"DelDisbDisc",
"SLHU"
};
public static readonly string[] ColumnHeadersShort = {
"TV", "Radio",
// "Rad 0/4K", "BadSvcType",
"InOrder/Gaps",
"Del0/!0"
};
public override string ToString()
public override string ToString() => ToString(false);
public string ToString(bool full)
{
return
var part1 =
"\t" + Tv + "\t" + Radio
// + "\t" + Radio0 + "/" + Radio4k + "\t" + RadioMaskServiceTypeMismatch
+ "\t" + (inMajorOrder ? "J" : "N") + "/" + (hasGap ? "J" : "N")
+ "\t" + (deletedMajor0 ? "J" : "N") + "/" + (deletedMajorNon0 ? "J" : "N");
if (!full)
return part1;
return
part1
+ "\t" + UserEditChNumber + "/" + UserSelChNo
+ "\t" + FactoryDefault
+ "\t" + Lcn
+ "\t" + Deleted + "/" + Disabled + "/" + Discarded
+ "\t" + Skipped + "/" + Locked + "/" + Invisible + "/" + NumUnSel;
}
public void Add(dynamic ch)
@@ -260,11 +308,36 @@ namespace Spike.LgWebOs5
if (ch.deleted != null && (bool)ch.deleted)
{
++Deleted;
if (nr == 0)
deletedMajor0 = true;
else
deletedMajorNon0 = true;
}
if (ch.diabled != null && (bool)ch.disabled)
++Disabled;
if (ch.discarded != null && (bool)ch.discarded)
++Discarded;
if (ch.userEditChNumber != null && (bool) ch.userEditChNumber)
++UserEditChNumber;
if (ch.userSelCHNo != null && (bool) ch.userSelCHNo)
++UserSelChNo;
if (ch.factoryDefault != null && (bool) ch.factoryDefault)
++FactoryDefault;
if (ch.skipped != null && (bool) ch.skipped)
++Skipped;
if (ch.locked != null && (bool) ch.locked)
++Locked;
if (ch.Invisible != null && (bool) ch.Invisible)
++Invisible;
if (ch.NumUnSel != null && (bool) ch.NumUnSel)
++NumUnSel;
if (ch.validLCN != null && (bool) ch.validLCN)
++Lcn;
}
public static ChanListStats operator +(ChanListStats a, ChanListStats b)
@@ -279,6 +352,18 @@ namespace Spike.LgWebOs5
stats.hasGap = a.hasGap || b.hasGap;
stats.deletedMajor0 = a.deletedMajor0 || b.deletedMajor0;
stats.deletedMajorNon0 = a.deletedMajorNon0 || b.deletedMajorNon0;
stats.UserEditChNumber = a.UserEditChNumber + b.UserEditChNumber;
stats.UserSelChNo = a.UserSelChNo + b.UserSelChNo;
stats.FactoryDefault = a.FactoryDefault + b.FactoryDefault;
stats.Disabled = a.Disabled + b.Disabled;
stats.Skipped = a.Skipped + b.Skipped;
stats.Invisible = a.Invisible + b.Invisible;
stats.Deleted = a.Deleted + b.Deleted;
stats.Discarded = a.Discarded + b.Discarded;
stats.UserCustomize = a.UserCustomize + b.UserCustomize;
stats.NumUnSel = a.NumUnSel + b.NumUnSel;
stats.Lcn = a.Lcn + b.Lcn;
return stats;
}
}

View File

@@ -1,6 +1,11 @@
ChanSort Change Log
===================
2020-12-26
- LG WebOS 5: added warning that support is only experimental.
- Panasonic: Channel name editing is now supported for svl.bin files (unless there is no indicator what encoding to use)
- Hungarian translation: added missing files to .zip
2020-12-05
- Philips: Fixed error saving the Favorite.xml file (effects Philips "ChannelMap_105" and later file format versions)
- added Hungarian translation (credits to Istvan Krisko)

View File

@@ -3,7 +3,7 @@ setlocal
setlocal enabledelayedexpansion
cd /d %~dp0
set languages=cs de es pl pt ru tr
set languages=cs de es hu pl pt ru tr
set curdate=%date:~6,4%-%date:~3,2%-%date:~0,2%
set target=%cd%\..\..\ChanSort_%curdate%
set DXversion=20.1
@@ -82,8 +82,12 @@ goto:eof
:copyLangDll
set source="C:\Program Files (x86)\DevExpress %DXversion%\Components\Bin\Framework\%2\DevExpress.%1.v%DXversion%.resources.dll"
if exist %source% xcopy /idy %source% "%target%\%2"
set source="d:\downloads\DevExpress\DevExpressLocalizedResources_20%DXversion%_%2\DevExpress.%1.v%DXversion%.resources.dll"
if exist %source% xcopy /idy %source% "%target%\%2"
set source="C:\Program Files (x86)\DevExpress %DXversion%\Components\Bin\Framework\%2\DevExpress.%1.v%DXversion%.Core.resources.dll"
if exist %source% xcopy /idy %source% "%target%\%2"
set source="d:\downloads\DevExpress\DevExpressLocalizedResources_20%DXversion%_%2\DevExpress.%1.v%DXversion%.Core.resources.dll"
if exist %source% xcopy /idy %source% "%target%\%2"
goto:eof
:error