mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-01-15 03:42:04 +01:00
- added support for Toshiba "settingsDB.db" lists
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -34,6 +35,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -45,6 +47,7 @@
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>..\Release\</OutputPath>
|
||||
@@ -56,6 +59,7 @@
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
@@ -72,9 +76,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DbChannel.cs" />
|
||||
<Compile Include="SettingsDbSerializer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="DbSerializer.cs" />
|
||||
<Compile Include="DbSerializerPlugin.cs" />
|
||||
<Compile Include="ChmgtDbSerializer.cs" />
|
||||
<Compile Include="ToshibaPlugin.cs" />
|
||||
<Service Include="{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -5,7 +5,7 @@ using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Toshiba
|
||||
{
|
||||
class DbSerializer : SerializerBase
|
||||
class ChmgtDbSerializer : SerializerBase
|
||||
{
|
||||
private const string FILE_chmgt_db = "\\chmgt_type001\\chmgt.db";
|
||||
private const string FILE_dvbSysData_db = "\\dvb_type001\\dvbSysData.db";
|
||||
@@ -19,7 +19,7 @@ namespace ChanSort.Loader.Toshiba
|
||||
private readonly Dictionary<string, bool> channelInfoByUid = new Dictionary<string, bool>();
|
||||
|
||||
#region ctor()
|
||||
public DbSerializer(string inputFile) : base(inputFile)
|
||||
public ChmgtDbSerializer(string inputFile) : base(inputFile)
|
||||
{
|
||||
DepencencyChecker.AssertVc2010RedistPackageX86Installed();
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Toshiba
|
||||
{
|
||||
public class DbSerializerPlugin : ISerializerPlugin
|
||||
{
|
||||
public string DllName { get; set; }
|
||||
public string PluginName => "Toshiba";
|
||||
public string FileFilter => "*.zip";
|
||||
|
||||
public SerializerBase CreateSerializer(string inputFile)
|
||||
{
|
||||
return new DbSerializer(inputFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
252
source/ChanSort.Loader.Toshiba/SettingsDbSerializer.cs
Normal file
252
source/ChanSort.Loader.Toshiba/SettingsDbSerializer.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SQLite;
|
||||
using System.IO;
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Toshiba
|
||||
{
|
||||
/*
|
||||
* This class loads Toshiba files stores as CLONE00001\settingsDB.db along with settingsDBBackup.db
|
||||
* Currently only channel renaming, reordering and deletion is supported.
|
||||
* We don't know yet how/where information about favorites and skip/lock/hide is stored.
|
||||
*
|
||||
* Also, there are SatTable and SatTxTable for satellites and transponders in the file, but it's unknown
|
||||
* how these tables are linked with EASISerTable / DVBSerTable / ...
|
||||
*/
|
||||
class SettingsDbSerializer : SerializerBase
|
||||
{
|
||||
private readonly ChannelList channels = new ChannelList(SignalSource.All, "All");
|
||||
|
||||
#region ctor()
|
||||
public SettingsDbSerializer(string inputFile) : base(inputFile)
|
||||
{
|
||||
DepencencyChecker.AssertVc2010RedistPackageX86Installed();
|
||||
|
||||
this.Features.ChannelNameEdit = ChannelNameEditMode.All;
|
||||
this.Features.DeleteMode = DeleteMode.Physically;
|
||||
this.Features.CanSkipChannels = false;
|
||||
this.Features.CanLockChannels = false;
|
||||
this.Features.CanHideChannels = false;
|
||||
this.Features.SupportedFavorites = 0;
|
||||
|
||||
this.DataRoot.AddChannelList(this.channels);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetDataFilePaths()
|
||||
public override IEnumerable<string> GetDataFilePaths()
|
||||
{
|
||||
var list = new List<string>();
|
||||
list.Add(this.FileName);
|
||||
var backupFile = GetBackupFilePath();
|
||||
if (File.Exists(backupFile))
|
||||
list.Add(backupFile);
|
||||
return list;
|
||||
}
|
||||
|
||||
private string GetBackupFilePath()
|
||||
{
|
||||
var dir = Path.GetDirectoryName(this.FileName);
|
||||
var name = Path.GetFileNameWithoutExtension(this.FileName);
|
||||
var ext = Path.GetExtension(this.FileName);
|
||||
var backupFile = Path.Combine(dir, name + "Backup" + ext);
|
||||
return backupFile;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Load()
|
||||
public override void Load()
|
||||
{
|
||||
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)
|
||||
throw new FileLoadException("File doesn't contain the expected tables");
|
||||
|
||||
this.ReadSatellites(cmd);
|
||||
this.ReadTransponders(cmd);
|
||||
this.ReadChannels(cmd);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RepairCorruptedDatabaseImage()
|
||||
private void RepairCorruptedDatabaseImage(SQLiteCommand cmd)
|
||||
{
|
||||
cmd.CommandText = "REINDEX";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadSatellites()
|
||||
private void ReadSatellites(SQLiteCommand cmd)
|
||||
{
|
||||
cmd.CommandText = "select m_id, m_name_serialized, m_orbital_position from SatTable";
|
||||
using var r = cmd.ExecuteReader();
|
||||
while (r.Read())
|
||||
{
|
||||
Satellite sat = new Satellite(r.GetInt32(0));
|
||||
string eastWest = "E";
|
||||
int pos = r.GetInt32(2);
|
||||
if (pos < 0)
|
||||
{
|
||||
pos = -pos;
|
||||
eastWest = "W";
|
||||
}
|
||||
sat.OrbitalPosition = $"{pos / 10}.{pos % 10}{eastWest}";
|
||||
sat.Name = r.GetString(1);
|
||||
this.DataRoot.AddSatellite(sat);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadTransponders()
|
||||
private void ReadTransponders(SQLiteCommand cmd)
|
||||
{
|
||||
cmd.CommandText = "select m_id, m_satellite_id, m_frequency, m_polarisation, m_symbol_rate from SatTxTable";
|
||||
using var r = cmd.ExecuteReader();
|
||||
while (r.Read())
|
||||
{
|
||||
int id = r.GetInt32(0);
|
||||
int satId = r.GetInt32(1);
|
||||
int freq = r.GetInt32(2);
|
||||
|
||||
if (this.DataRoot.Transponder.TryGet(id) != null)
|
||||
continue;
|
||||
Transponder tp = new Transponder(id);
|
||||
tp.FrequencyInMhz = (decimal)freq;
|
||||
tp.Polarity = r.GetInt32(3) == 0 ? 'H' : 'V';
|
||||
tp.Satellite = this.DataRoot.Satellites.TryGet(satId);
|
||||
tp.SymbolRate = r.GetInt32(4);
|
||||
this.DataRoot.AddTransponder(tp.Satellite, tp);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadChannels()
|
||||
private void ReadChannels(SQLiteCommand cmd)
|
||||
{
|
||||
int ixE = 0;
|
||||
int ixD = 3;
|
||||
int ixA = 8;
|
||||
int ixT = 9;
|
||||
int ixDC = 10;
|
||||
|
||||
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,
|
||||
a.m_name_serialized,
|
||||
t.frequency_in_multiples_of_10Hz,
|
||||
dc.frequency
|
||||
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";
|
||||
using var r = cmd.ExecuteReader();
|
||||
while (r.Read())
|
||||
{
|
||||
var handle = r.GetInt32(ixE + 0);
|
||||
var oldProgNr = r.GetInt32(ixE + 1);
|
||||
var name = r.GetString(ixE + 2);
|
||||
ChannelInfo channel = new ChannelInfo(0, handle, oldProgNr, name);
|
||||
|
||||
// DVB
|
||||
if (!r.IsDBNull(ixD + 0))
|
||||
{
|
||||
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.FreqInMhz = (decimal) r.GetInt32(ixDC + 0) / 1000;
|
||||
}
|
||||
|
||||
// analog
|
||||
if (!r.IsDBNull(ixA + 0))
|
||||
{
|
||||
channel.FreqInMhz = (decimal) r.GetInt32(ixT + 0) / 100000;
|
||||
}
|
||||
|
||||
if (!channel.IsDeleted)
|
||||
this.DataRoot.AddChannel(this.channels, channel);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Save()
|
||||
public override void Save(string tvOutputFile)
|
||||
{
|
||||
if (tvOutputFile != this.FileName)
|
||||
{
|
||||
File.Copy(this.FileName, tvOutputFile, true);
|
||||
this.FileName = tvOutputFile;
|
||||
}
|
||||
|
||||
string channelConnString = "Data Source=" + this.FileName;
|
||||
using var conn = new SQLiteConnection(channelConnString);
|
||||
conn.Open();
|
||||
using var cmd = conn.CreateCommand();
|
||||
using var cmd2 = conn.CreateCommand();
|
||||
using var trans = conn.BeginTransaction();
|
||||
|
||||
this.WriteChannels(cmd, cmd2, this.channels);
|
||||
trans.Commit();
|
||||
|
||||
this.RepairCorruptedDatabaseImage(cmd);
|
||||
conn.Close();
|
||||
|
||||
// copy settingsDB.db to settingsDBBackup.db
|
||||
var backupFile = GetBackupFilePath();
|
||||
File.Copy(this.FileName, backupFile, true);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WriteChannels()
|
||||
private void WriteChannels(SQLiteCommand cmd, SQLiteCommand cmdDelete, ChannelList channelList)
|
||||
{
|
||||
cmd.CommandText = "update EASISerTable set m_rsn=@nr, m_name_serialized=@name where m_handle=@handle";
|
||||
cmd.Parameters.Add(new SQLiteParameter("@handle", DbType.Int32));
|
||||
cmd.Parameters.Add(new SQLiteParameter("@nr", DbType.Int32));
|
||||
cmd.Parameters.Add(new SQLiteParameter("@name", DbType.String));
|
||||
cmd.Prepare();
|
||||
|
||||
cmdDelete.CommandText = @"
|
||||
delete from EASISerTable where m_handle=@handle;
|
||||
delete from DVBSerTable where m_handle=@handle;
|
||||
delete from AnalogSerTable where m_handle=@handle;
|
||||
";
|
||||
cmdDelete.Parameters.Add(new SQLiteParameter("@handle", DbType.Int32));
|
||||
|
||||
foreach (ChannelInfo channel in channelList.Channels)
|
||||
{
|
||||
if (channel.IsProxy) // ignore reference list proxy channels
|
||||
continue;
|
||||
|
||||
if (channel.IsDeleted)
|
||||
{
|
||||
cmdDelete.Parameters["@handle"].Value = channel.RecordIndex;
|
||||
cmdDelete.ExecuteNonQuery();
|
||||
}
|
||||
else
|
||||
{
|
||||
channel.UpdateRawData();
|
||||
cmd.Parameters["@handle"].Value = channel.RecordIndex;
|
||||
cmd.Parameters["@nr"].Value = channel.NewProgramNr;
|
||||
cmd.Parameters["@name"].Value = channel.Name;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
20
source/ChanSort.Loader.Toshiba/ToshibaPlugin.cs
Normal file
20
source/ChanSort.Loader.Toshiba/ToshibaPlugin.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.IO;
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Toshiba
|
||||
{
|
||||
public class ToshibaPlugin : ISerializerPlugin
|
||||
{
|
||||
public string DllName { get; set; }
|
||||
public string PluginName => "Toshiba";
|
||||
public string FileFilter => "*.zip;*.db";
|
||||
|
||||
public SerializerBase CreateSerializer(string inputFile)
|
||||
{
|
||||
if (Path.GetExtension(inputFile).ToLower() == ".db")
|
||||
return new SettingsDbSerializer(inputFile);
|
||||
else
|
||||
return new ChmgtDbSerializer(inputFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -534,7 +534,8 @@ namespace ChanSort.Ui
|
||||
catch (Exception ex)
|
||||
{
|
||||
serializer?.Dispose();
|
||||
errorMsgs.AppendLine($"{plugin.DllName} ({plugin.PluginName}): {ex}\n\n");
|
||||
var errMsg = ex is FileLoadException ? ex.Message : ex.ToString(); // FileLoadExceptions are normal when a Loader does not support a file. No stack trace needed
|
||||
errorMsgs.AppendLine($"{plugin.DllName} ({plugin.PluginName}): {errMsg}\n\n");
|
||||
if (ex is ArgumentException)
|
||||
{
|
||||
var msg = ex.ToString();
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Test.Loader.Toshiba
|
||||
private void TestChannelsAddedToCorrectLists(string fileName, SignalSource signalSource, int expectedTv, int expectedRadio, int dataProgramSid = 0, string dataProgramName = null)
|
||||
{
|
||||
var tempFile = TestUtils.DeploymentItem("Test.Loader.Toshiba\\TestFiles\\" + fileName);
|
||||
var plugin = new DbSerializerPlugin();
|
||||
var plugin = new ToshibaPlugin();
|
||||
var ser = plugin.CreateSerializer(tempFile);
|
||||
ser.Load();
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Test.Loader.Toshiba
|
||||
public void TestDeletingChannel()
|
||||
{
|
||||
var tempFile = TestUtils.DeploymentItem("Test.Loader.Toshiba\\TestFiles\\Toshiba-SL863G.zip");
|
||||
var plugin = new DbSerializerPlugin();
|
||||
var plugin = new ToshibaPlugin();
|
||||
var ser = plugin.CreateSerializer(tempFile);
|
||||
ser.Load();
|
||||
var data = ser.DataRoot;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
ChanSort Change Log
|
||||
===================
|
||||
|
||||
2021-01-23
|
||||
- Toshiba: added support for settingsDB.db lists
|
||||
|
||||
2021-01-17
|
||||
- Philips: added support for ChannelMap_45 format
|
||||
- Philips: fixed display of symbol rate and frequency (off by factor 1000 depending of list and DVB source)
|
||||
|
||||
Reference in New Issue
Block a user