mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-01-12 10:22:04 +01:00
- put file name in Sqlite connect string in quotes - improvements to Mediatek Philips 120+125/Sony serializer (physically reorder XML nodes, use flags stored in Java serialized blob) - selecting a RefList changed the current working directory, which prevented .ini files to be found by loaders
272 lines
9.0 KiB
C#
272 lines
9.0 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Microsoft.Data.Sqlite;
|
|
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");
|
|
|
|
private readonly HashSet<string> tableNames = new();
|
|
|
|
#region ctor()
|
|
public SettingsDbSerializer(string inputFile) : base(inputFile)
|
|
{
|
|
this.Features.ChannelNameEdit = ChannelNameEditMode.All;
|
|
this.Features.DeleteMode = DeleteMode.Physically;
|
|
this.Features.CanSkipChannels = false;
|
|
this.Features.CanLockChannels = false;
|
|
this.Features.CanHideChannels = false;
|
|
this.Features.FavoritesMode = FavoritesMode.None;
|
|
|
|
this.DataRoot.AddChannelList(this.channels);
|
|
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Lock));
|
|
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Skip));
|
|
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Hidden));
|
|
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Encrypted));
|
|
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.PcrPid));
|
|
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.VideoPid));
|
|
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.AudioPid));
|
|
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Satellite));
|
|
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.ShortName));
|
|
}
|
|
#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}\";Pooling=False";
|
|
using var conn = new SqliteConnection(sysDataConnString);
|
|
conn.Open();
|
|
|
|
using var cmd = conn.CreateCommand();
|
|
|
|
this.RepairCorruptedDatabaseImage(cmd);
|
|
|
|
cmd.CommandText = "SELECT name FROM sqlite_master WHERE type = 'table'";
|
|
using (var r = cmd.ExecuteReader())
|
|
{
|
|
while (r.Read())
|
|
this.tableNames.Add(r.GetString(0).ToLowerInvariant());
|
|
}
|
|
|
|
if (!this.tableNames.Contains("easisertable"))
|
|
throw LoaderException.TryNext("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 = 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 = 9;
|
|
int ixDC = 10;
|
|
int ixT = 12;
|
|
|
|
var hasTADTunerDataTable = this.tableNames.Contains("tadtunerdatatable");
|
|
string analogTunerFields = hasTADTunerDataTable ? ",t.frequency_in_multiples_of_10Hz" : "";
|
|
string analogTunerTable = hasTADTunerDataTable ? " left outer join TADTunerDataTable t on t.channel=ac.channel_no" : "";
|
|
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, d.m_provider_serialized,
|
|
a.m_name_serialized,
|
|
dc.frequency, dc.symbol_rate
|
|
{analogTunerFields}
|
|
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
|
|
{analogTunerTable}";
|
|
|
|
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) & 0x7FFF;
|
|
channel.TransportStreamId = r.GetInt32(ixD + 1) & 0x7FFF;
|
|
channel.ServiceId = r.GetInt32(ixD + 2) & 0x1FFF;
|
|
channel.ServiceType = r.GetInt32(ixD + 3) & 0x1FFF;
|
|
channel.Provider = r.GetString(ixD + 5);
|
|
channel.FreqInMhz = (decimal) r.GetInt32(ixDC + 0) / 1000;
|
|
channel.SymbolRate = r.GetInt32(ixDC + 1);
|
|
if (channel.FreqInMhz > 10000)
|
|
channel.FreqInMhz = (int) channel.FreqInMhz;
|
|
}
|
|
|
|
// analog
|
|
if (!r.IsDBNull(ixA + 0) && hasTADTunerDataTable)
|
|
{
|
|
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 channelConnString = $"Data Source=\"{this.FileName}\";Pooling=False";
|
|
using (var conn = new SqliteConnection(channelConnString))
|
|
{
|
|
conn.Open();
|
|
using var trans = conn.BeginTransaction();
|
|
using var cmd = conn.CreateCommand();
|
|
using var cmd2 = conn.CreateCommand();
|
|
|
|
this.WriteChannels(cmd, cmd2, this.channels);
|
|
trans.Commit();
|
|
|
|
cmd.Transaction = null;
|
|
this.RepairCorruptedDatabaseImage(cmd);
|
|
}
|
|
|
|
// 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("@handle", SqliteType.Integer);
|
|
cmd.Parameters.Add("@nr", SqliteType.Integer);
|
|
cmd.Parameters.Add("@name", SqliteType.Text);
|
|
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("@handle", SqliteType.Integer);
|
|
cmdDelete.Prepare();
|
|
|
|
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
|
|
}
|
|
}
|