- switched to Hisense SQLite file format

This commit is contained in:
hbeham
2015-11-21 19:34:30 +01:00
parent ada0a52637
commit 893579d615
15 changed files with 314 additions and 157 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
*.sdf
source/ChanSort.opensdf

View File

@@ -11,6 +11,7 @@ namespace ChanSort.Api
public bool DeviceSettings { get; set; }
public bool CanDeleteChannels { get; set; }
public bool CanHaveGaps { get; set; }
public bool EncryptedFlagEdit { get; set; }
public SupportedFeatures()
{

View File

@@ -74,7 +74,7 @@ namespace ChanSort.Loader.GlobalClone {
/// Looks up a localized string similar to ATTENTION:
///Please make sure that your webOS based TV is using a recent firmware version (LB600 and higher: 4.41.32, UB: 4.51.44).
///Older LG firmware for webOS based TV models does not handle the import of channel lists properly and randomly reorders channels.
///.
///(If your firmware is newer, you can ignore is message.).
/// </summary>
internal static string GcSerializer_webOsFirmwareWarning {
get {

View File

@@ -124,6 +124,7 @@ Soll ChanSort die störenden Dateien jetzt umbenennen?</value>
<data name="GcSerializer_webOsFirmwareWarning" xml:space="preserve">
<value>HINWEIS:
Bitte stellen Sie sicher, dass auf Ihrem webOS basierenden Gerät eine aktuelle Firmware installiert ist (LB600 und höher: 4.41.32, UB: 4.51.44).
Ältere Versionen können Senderlisten nicht korrekt einlesen und verändern diese willkürlich im laufenden Betrieb.</value>
Ältere Versionen können Senderlisten nicht korrekt einlesen und verändern diese willkürlich im laufenden Betrieb.
(Sie können diese Meldung ignorieren, wenn Ihre Firmwareversion aktueller ist.)</value>
</data>
</root>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
<!--
Microsoft ResX Schema
Version 1.3
@@ -58,46 +58,45 @@
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="GcSerializer_ReadModelInfo_ModelWarning" xml:space="preserve">
<value>Your TV will only import the GlobalClone file when there are no files named xx*.TLL in the same directory.
Do you want ChanSort to rename the conflicting files?</value>
@@ -106,6 +105,6 @@ Do you want ChanSort to rename the conflicting files?</value>
<value>ATTENTION:
Please make sure that your webOS based TV is using a recent firmware version (LB600 and higher: 4.41.32, UB: 4.51.44).
Older LG firmware for webOS based TV models does not handle the import of channel lists properly and randomly reorders channels.
</value>
(If your firmware is newer, you can ignore is message.)</value>
</data>
</root>

View File

@@ -35,6 +35,10 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite, Version=1.0.87.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\DLL\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />

View File

@@ -1,143 +1,201 @@
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Data;
using ChanSort.Api;
using System.Data.SQLite;
namespace ChanSort.Loader.Hisense
{
public class HisSerializer : SerializerBase
{
public override string DisplayName => "Hisense SQLite Loader";
private readonly ChannelList avbcChannels = new ChannelList(SignalSource.AnalogC | SignalSource.Tv, "Analog-C");
private readonly ChannelList dvbcChannels = new ChannelList(SignalSource.DvbC | SignalSource.Tv | SignalSource.Radio, "DVB-C");
private readonly ChannelList dvbtChannels = new ChannelList(SignalSource.DvbT | SignalSource.Tv | SignalSource.Radio, "DVB-T");
private readonly ChannelList dvbsChannels = new ChannelList(SignalSource.DvbS | SignalSource.Tv | SignalSource.Radio, "DVB-S");
private byte[] svlFileContent;
private byte[] tslFileContent;
private const int MaxFileSize = 4 << 20; // 4 MB
#region enums and bitmasks
private int tSize, cSize, sSize;
internal enum BroadcastType { Analog = 1, Dvb = 2 }
internal enum BroadcastMedium { DigTer = 1, DigCab = 2, DigSat = 3, AnaTer = 4, AnaCab = 5, AnaSat = 6 }
internal enum ServiceType { Tv = 1, Radio = 2, App = 3}
[Flags]
internal enum NwMask { Hide = 0, Skip = 1<<3, Fav1 = 1<<4, Fav2 = 1<<5, Fav3 = 1<<6, Fav4 = 1<<7, Lock = 1<<8 }
[Flags]
internal enum OptionMask { Rename = 1<<3, Move = 1<<10 }
[Flags]
internal enum HashCode { Name = 1<<0, ChannelId = 1<<1, BroadcastType = 1<<2, TsRecId = 1<<3, ProgNum = 1<<4, DvbShortName = 1<<5, Radio = 1<<10, Encrypted = 1<<11, Tv = 1<<13 }
[Flags]
internal enum DvbLinkageMask { Ts = 1<<2 }
#region DisplayName
public override string DisplayName => "Hisense HIS_SVL.BIN Loader";
#endregion
private const string ERR_fileTooBig = "The file size {0} is larger than the allowed maximum of {1}.";
private const string ERR_badFileFormat = "The content of the file doesn't match the expected format.";
private DataMapping svlMapping, tslMapping, dvbMapping;
private readonly Dictionary<int, Transponder> transponder = new Dictionary<int, Transponder>();
#region ctor()
public HisSerializer(string inputFile) : base(inputFile)
{
this.Features.ChannelNameEdit = ChannelNameEditMode.All;
this.ReadConfigurationFromIniFile();
this.DataRoot.AddChannelList(avbcChannels);
this.DataRoot.AddChannelList(dvbcChannels);
this.DataRoot.AddChannelList(dvbtChannels);
this.DataRoot.AddChannelList(dvbsChannels);
}
#endregion
#region ReadConfigurationFromIniFile()
private void ReadConfigurationFromIniFile()
{
string iniFile = this.GetType().Assembly.Location.ToLower().Replace(".dll", ".ini");
IniFile ini = new IniFile(iniFile);
this.svlMapping = new DataMapping(ini.GetSection("SVL_Record"));
this.svlMapping.DefaultEncoding = Encoding.UTF8;
this.tslMapping = new DataMapping(ini.GetSection("TSL_Record"));
this.tslMapping.DefaultEncoding = Encoding.UTF8;
this.dvbMapping = new DataMapping(ini.GetSection("DVB_Data"));
this.dvbMapping.DefaultEncoding = Encoding.UTF8;
var sec = ini.GetSection("Columns");
var fields = sec.GetString("DVB_T");
if (fields != null)
dvbtChannels.VisibleColumnFieldNames = fields.Trim().Split(',');
fields = sec.GetString("DVB_C");
if (fields != null)
dvbcChannels.VisibleColumnFieldNames = fields.Trim().Split(',');
fields = sec.GetString("DVB_S");
if (fields != null)
dvbsChannels.VisibleColumnFieldNames = fields.Trim().Split(',');
}
#endregion
#region Load()
public override void Load()
{
this.LoadTslFile(this.FileName.Replace("SVL", "TSL"));
this.LoadSvlFile(this.FileName);
}
#endregion
#region LoadTslFile()
private void LoadTslFile(string fileName)
{
long fileSize = new FileInfo(fileName).Length;
if (fileSize > MaxFileSize)
throw new FileLoadException(string.Format(ERR_fileTooBig, fileSize, MaxFileSize));
this.tslFileContent = File.ReadAllBytes(fileName);
int off = 0;
tSize = this.ReadHeader(tslFileContent, ref off);
cSize = this.ReadHeader(tslFileContent, ref off);
sSize = this.ReadHeader(tslFileContent, ref off);
this.ReadTransponder(ref off, tSize, 1, 1000000);
this.ReadTransponder(ref off, cSize, 2, 1000000);
this.ReadTransponder(ref off, sSize, 3, 1);
}
#endregion
#region ReadTransponder()
private void ReadTransponder(ref int off, int size, int table, int freqFactor)
{
int recordSize = tslMapping.Settings.GetInt("RecordSize");
if (size % recordSize != 0)
throw new FileLoadException(ERR_badFileFormat);
int count = size / recordSize;
if (count == 0)
return;
for (int i = 0; i < count; i++)
using (var conn = new SQLiteConnection("Data Source=" + this.FileName))
{
tslMapping.SetDataPtr(tslFileContent, off);
var id = (table << 16) + tslMapping.GetWord("ID");
var trans = new Transponder(id);
trans.FrequencyInMhz = (decimal)tslMapping.GetDword("Frequency") / freqFactor;
trans.SymbolRate = tslMapping.GetWord("SymbolRate");
this.transponder.Add(id, trans);
off += recordSize;
conn.Open();
using (var cmd = conn.CreateCommand())
{
this.RepairCorruptedDatabaseImage(cmd);
this.LoadSatelliteData(cmd);
this.LoadTslData(cmd);
this.LoadSvlData(cmd);
}
}
}
#endregion
#region RepairCorruptedDatabaseImage()
private void RepairCorruptedDatabaseImage(SQLiteCommand cmd)
{
cmd.CommandText = "REINDEX";
cmd.ExecuteNonQuery();
}
#endregion
#region LoadSatelliteData()
private void LoadSatelliteData(SQLiteCommand cmd)
{
cmd.CommandText = "select ui2_satl_rec_id, ui4_mask, i2_orb_pos, ac_sat_name from satl_x";
using (var r = cmd.ExecuteReader())
{
while (r.Read())
{
var sat = new Satellite(r.GetInt32(0));
var pos = r.GetInt16(2);
sat.OrbitalPosition = $"{(decimal)Math.Abs(pos)/10:n1}{(pos < 0 ? 'W' : 'E')}";
sat.Name = r.GetString(3);
this.DataRoot.AddSatellite(sat);
}
}
}
#endregion
#region LoadSvlFile()
#region LoadTslData()
private void LoadSvlFile(string fileName)
private void LoadTslData(SQLiteCommand cmd)
{
long fileSize = new FileInfo(fileName).Length;
if (fileSize > MaxFileSize)
throw new FileLoadException(string.Format(ERR_fileTooBig, fileSize, MaxFileSize));
this.svlFileContent = File.ReadAllBytes(this.FileName);
int off = 0;
this.LoadTslData(cmd, "tsl_x_data_ter_dig", ", ui4_freq", (t, r, i0) => { t.FrequencyInMhz = r.GetInt32(i0 + 0); });
tSize = this.ReadHeader(svlFileContent, ref off);
cSize = this.ReadHeader(svlFileContent, ref off);
sSize = this.ReadHeader(svlFileContent, ref off);
this.ReadChannelList(ref off, tSize, 1, dvbtChannels);
this.ReadChannelList(ref off, cSize, 2, dvbcChannels);
this.ReadChannelList(ref off, sSize, 3, dvbsChannels);
this.LoadTslData(cmd, "tsl_x_data_cab_dig", ", ui4_freq, ui3_sym_rate", (t, r, i0) =>
{
t.FrequencyInMhz = r.GetInt32(i0 + 0);
t.SymbolRate = r.GetInt32(i0 + 1);
});
this.LoadTslData(cmd, "tsl_x_data_sat_dig", ", ui4_freq, ui4_sym_rate", (t, r, i0) =>
{
t.FrequencyInMhz = r.GetInt32(i0 + 0);
t.SymbolRate = r.GetInt32(i0 + 1);
});
}
private void LoadTslData(SQLiteCommand cmd, string joinTable, string joinFields, Action<Transponder, SQLiteDataReader, int> enhanceTransponderInfo)
{
cmd.CommandText = "select tsl_x.ui2_tsl_rec_id, `t_desc.ui2_on_id`, `t_desc.ui2_ts_id`, `t_ref.ui2_satl_rec_id` " + joinFields
+ " from tsl_x inner join " + joinTable + " on " + joinTable + ".ui2_tsl_rec_id=tsl_x.ui2_tsl_rec_id"
//+ $" where `t_desc.e_bcst_type` in ({(int)BroadcastType.Analog},{(int)BroadcastType.Dvb}) "
//+ $" and `tdesc.e_bcst_medium` in ({(int)BroadcastMedium.DigTer},{(int)BroadcastMedium.DigCab},{(int)BroadcastMedium.DigSat},{(int)BroadcastMedium.AnaCab})"
;
using (var r = cmd.ExecuteReader())
{
while (r.Read())
{
var trans = new Transponder(r.GetInt16(0));
trans.OriginalNetworkId = r.GetInt16(1);
trans.TransportStreamId = r.GetInt16(2);
trans.Satellite = this.DataRoot.Satellites.TryGet(r.GetInt32(3));
enhanceTransponderInfo(trans, r, 4);
this.DataRoot.AddTransponder(trans.Satellite, trans);
}
}
}
#endregion
#region LoadSvlData()
private void LoadSvlData(SQLiteCommand cmd)
{
this.LoadSvlData(cmd, "svl_x_data_analog", "", (ci, r, i0) => { });
this.LoadSvlData(cmd, "svl_x_data_dvb", ", b_free_ca_mode", (ci, r, i0) => { ci.Encrypted = r.GetBoolean(i0 + 0); });
}
private void LoadSvlData(SQLiteCommand cmd, string joinTable, string joinFields, Action<ChannelInfo, SQLiteDataReader, int> enhanceChannelInfo)
{
cmd.CommandText = "select svl_x.ui2_svl_rec_id, ui4_channel_id, ui2_tsl_rec_id, e_brdcst_type, e_serv_type, ac_name, ui4_nw_mask, ui4_hashcode " + joinFields
+ " from svl_x inner join " + joinTable + " on " + joinTable + ".ui2_svl_rec_id=svl_x.ui2_svl_rec_id"
//+ $" where `e_brdcst_type` in ({(int)BroadcastType.Analog},{(int)BroadcastType.Dvb}) "
;
using (var r = cmd.ExecuteReader())
{
while (r.Read())
{
var id = r.GetInt16(0);
var hashcode = (HashCode)r.GetInt32(7);
var progNr = (hashcode & HashCode.ProgNum) == 0 || r.IsDBNull(1) ? -1 : r.GetInt32(1) >> 2;
var trans = this.DataRoot.Transponder.TryGet(r.GetInt16(2));
var bcast = (BroadcastType)r.GetInt16(3);
var stype = (ServiceType) r.GetInt16(4);
var name = (hashcode & HashCode.Name) == 0 || r.IsDBNull(5) ? "" : r.GetString(5);
var ssource = trans == null || bcast == BroadcastType.Analog ? SignalSource.Analog : SignalSource.Digital;
ssource |= stype == ServiceType.Radio ? SignalSource.Radio : SignalSource.Tv;
int idx = name.IndexOf("\0");
if (idx >= 0)
name = name.Substring(0, idx);
var ci = new ChannelInfo(ssource, id, progNr, name);
if (trans != null)
{
ci.Transponder = trans;
ci.OriginalNetworkId = trans.OriginalNetworkId;
ci.TransportStreamId = trans.TransportStreamId;
ci.SymbolRate = trans.SymbolRate;
ci.FreqInMhz = trans.FrequencyInMhz;
}
var nwMask = (NwMask)r.GetInt32(6);
ci.Skip = (nwMask & NwMask.Skip) != 0;
ci.Lock = (nwMask & NwMask.Lock) != 0;
ci.Hidden = (nwMask & NwMask.Hide) != 0;
ci.Favorites |= (Favorites) ((int)(nwMask & (NwMask.Fav1 | NwMask.Fav2 | NwMask.Fav3 | NwMask.Fav4)) >> 4);
if (stype == ServiceType.App)
ci.ServiceTypeName = "Data";
enhanceChannelInfo(ci, r, 8);
var list = this.DataRoot.GetChannelList(ssource);
this.DataRoot.AddChannel(list, ci);
}
}
}
#endregion
#if false
#region ReadHeader()
private int ReadHeader(byte[] data, ref int off)
{
@@ -293,13 +351,81 @@ namespace ChanSort.Loader.Hisense
}
#endregion
#endif
// Saving ====================================
#region Save()
public override void Save(string tvOutputFile)
{
using (var conn = new SQLiteConnection("Data Source=" + this.FileName))
{
conn.Open();
using (var trans = conn.BeginTransaction())
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = trans;
try
{
foreach (var list in this.DataRoot.ChannelLists)
{
foreach (var ci in list.Channels)
this.UpdateChannel(cmd, ci);
}
trans.Commit();
}
catch
{
trans.Rollback();
throw;
}
}
}
}
#endregion
#region UpdateChannel()
private void UpdateChannel(SQLiteCommand cmd, ChannelInfo ci)
{
if (ci.NewProgramNr != ci.OldProgramNr)
{
if (ci.NewProgramNr >= 0)
{
cmd.CommandText = "update svl_x set channel_id=@chnr, ui4_option_mask=ui4_option_mask|" + ((int) OptionMask.Move) + " where ui2_svl_rec_id=@id";
cmd.Parameters.Clear();
cmd.Parameters.Add("@id", DbType.Int16);
cmd.Parameters.Add("@chnr", DbType.Int32);
cmd.Parameters["@id"].Value = ci.RecordIndex;
cmd.Parameters["@chnr"].Value = ci.NewProgramNr;
cmd.ExecuteNonQuery();
}
else
{
// TODO: delete channel .. HOW?!?
}
}
if (ci.IsNameModified)
{
cmd.CommandText = "update svl_x set name=@name, ui4_option_mask=ui4_option_mask|" + ((int)OptionMask.Rename) + " where ui2_svl_rec_id=@id";
cmd.Parameters.Clear();
cmd.Parameters.Add("@id", DbType.Int16);
cmd.Parameters.Add("@name", DbType.String);
cmd.Parameters["@id"].Value = ci.RecordIndex;
cmd.Parameters["@name"].Value = ci.Name;
cmd.ExecuteNonQuery();
}
cmd.CommandText = "update svl_x set ui4_nw_mask=(ui4_nw_mask & 0xFFFFF0F)|@fav where ui2_svl_rec_id=@id";
cmd.Parameters.Clear();
cmd.Parameters.Add("@id", DbType.Int16);
cmd.Parameters.Add("@fav", DbType.Int32);
cmd.Parameters["@id"].Value = ci.RecordIndex;
cmd.Parameters["@fav"].Value = ((int)ci.Favorites & 0x0F) << 4;
cmd.ExecuteNonQuery();
}
#endregion
}
}

View File

@@ -12,8 +12,8 @@ namespace ChanSort.Loader.Hisense
#if HISENSE_ENABLED
public class HisSerializerPlugin : ISerializerPlugin
{
public string PluginName => "Hisense HIS_*.bin";
public string FileFilter => "HIS_SVL.BIN";
public string PluginName => "Hisense *.sqlite";
public string FileFilter => "*.sqlite";
#region CreateSerializer()
public SerializerBase CreateSerializer(string inputFile)

View File

@@ -309,6 +309,7 @@ namespace ChanSort.Loader.Panasonic
this.Features.ChannelNameEdit = ChannelNameEditMode.None; // due to the chaos with binary data inside the "sname" string column, writing back a name has undesired side effects
this.Features.CanHaveGaps = false;
this.Features.EncryptedFlagEdit = true;
this.DataRoot.SortedFavorites = true;
this.DataRoot.AddChannelList(this.avbtChannels);

View File

@@ -41,6 +41,7 @@
map-CableD = 320
map-SateD = 168
map-AstraHDPlusD = 212
map-CyfraPlusD = 172
Favorites = 5
SortedFavorites = 1
@@ -53,6 +54,7 @@
map-CableD = 320
map-SateD = 168
map-AstraHDPlusD = 212
map-CyfraPlusD = 172
Favorites = 5
SortedFavorites = 2

View File

@@ -32,7 +32,8 @@ namespace ChanSort.Loader.SamsungJ
#endregion
#region DisplayName
public override string DisplayName { get { return "Samsung J-Series .zip Loader"; } }
public override string DisplayName => "Samsung J-Series .zip Loader";
#endregion
@@ -181,7 +182,7 @@ namespace ChanSort.Loader.SamsungJ
{
Satellite sat = new Satellite(r.GetInt32(0));
int pos = Math.Abs(r.GetInt32(2));
sat.OrbitalPosition = string.Format("{0}.{1}{2}", pos / 10, pos % 10, r.GetInt32(3) == 1 ? "E" : "W");
sat.OrbitalPosition = $"{pos/10}.{pos%10}{(r.GetInt32(3) == 1 ? "E" : "W")}";
sat.Name = ReadUtf16(r, 1);
this.DataRoot.AddSatellite(sat);
}
@@ -274,7 +275,7 @@ namespace ChanSort.Loader.SamsungJ
{
while (r.Read())
{
var tp = this.transponderByFreq != null ? this.transponderByFreq.TryGet(r.GetInt32(2)) : null;
var tp = this.transponderByFreq?.TryGet(r.GetInt32(2));
var channel = new DbChannel(r, fields, this.DataRoot, providers, sat, tp);
if (!channel.IsDeleted)
{
@@ -496,12 +497,21 @@ namespace ChanSort.Loader.SamsungJ
private static SQLiteCommand PrepareDeleteCommand(SQLiteConnection conn, bool digital)
{
var cmd = conn.CreateCommand();
cmd.CommandText = "delete from SRV where srvId=@id";
cmd.CommandText = "select count(1) from sqlite_master where upper(name)='SRV_DVB_EXT' and type='table'";
bool hasDvbExt = (long) cmd.ExecuteScalar() > 0;
cmd.CommandText += "; delete from SRV_FAV where srvId=@id";
if (digital)
cmd.CommandText += "; delete from SRV_DVB where srvId=@id; delete from SRV_DVB_EXT where srvId=@id";
{
if (hasDvbExt)
cmd.CommandText += "; delete from SRV_DVB_EXT where srvId=@id";
cmd.CommandText += "; delete from SRV_DVB where srvId=@id";
}
else
cmd.CommandText += "; delete from SRV_ANL where srvId=@id";
cmd.CommandText += "; delete from SRV_FAV where srvId=@id";
cmd.CommandText = "delete from SRV where srvId=@id";
cmd.Parameters.Add(new SQLiteParameter("@id", DbType.Int64));
cmd.Prepare();

View File

@@ -4,9 +4,9 @@ namespace ChanSort.Loader.SamsungJ
{
public class DbSerializerPlugin : ISerializerPlugin
{
public string PluginName { get { return "Samsung J-Series"; } }
public string FileFilter { get { return "channel_list_t*.zip"; } }
public string PluginName => "Samsung J-Series (*.zip)";
public string FileFilter => "*.zip"; // "channel_list_t*.zip";
public SerializerBase CreateSerializer(string inputFile)
{
return new DbSerializer(inputFile);

View File

@@ -4,9 +4,9 @@ namespace ChanSort.Loader.Toshiba
{
public class DbSerializerPlugin : ISerializerPlugin
{
public string PluginName { get { return "Toshiba *.zip"; } }
public string FileFilter { get { return "*.zip"; } }
public string PluginName => "Toshiba *.zip";
public string FileFilter => "Hotel*.zip";
public SerializerBase CreateSerializer(string inputFile)
{
return new DbSerializer(inputFile);

View File

@@ -25,7 +25,7 @@ namespace ChanSort.Ui
{
public partial class MainForm : XtraForm
{
public const string AppVersion = "v2015-09-19";
public const string AppVersion = "v2015-10-15";
private const int MaxMruEntries = 10;
@@ -234,6 +234,7 @@ namespace ChanSort.Ui
//this.SetControlsEnabled(!this.dataRoot.IsEmpty);
this.UpdateFavoritesEditor(this.dataRoot.SupportedFavorites);
this.colEncrypted.OptionsColumn.AllowEdit = this.currentTvSerializer.Features.EncryptedFlagEdit;
if (this.dataRoot.Warnings.Length > 0 && this.miShowWarningsAfterLoad.Checked)
this.BeginInvoke((Action)this.ShowFileInformation);

View File

@@ -1,6 +1,17 @@
ChanSort Change Log
===================
TBA
- Toshiba file detection changed from *.zip to Hotel*.zip
- Samsung J series file detection changed from channel_list_t*.zip to *.zip
- Added comment to info screen when opening LG LB/UB series GlobalClone list
2015-10-15
- Samsung J series: fixed error when saving certain lists which don't
contain an "SRV_DVB_EXT" table.
- Panasonic: allow to edit the "Encrypted" flag, which is sometimes
set incorrectly during the channel search.
2015-09-19
- Samsung J series: fixed deleting of channels
- LG GlobalClone: modified channel names were not written to the file