mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-01-15 03:42:04 +01:00
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:
@@ -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;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user