mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-02-28 01:00:43 +01:00
- switched to Hisense SQLite file format
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
*.sdf
|
||||
source/ChanSort.opensdf
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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" />
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user