mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-01-20 06:12:03 +01:00
- added loader for TCL/Thomson Channel_List_*.tar with DtvData.db and satellite.db inside
- fixed text input in "Favorites" column (for lists that only have favorite markers and not individual numbers) - converted source code to use SDK/MSBuild project files (for future migration to .NET 7 or 8)
This commit is contained in:
@@ -233,14 +233,9 @@ namespace ChanSort.Api
|
||||
Favorites favMask = 0;
|
||||
foreach (Favorites fav in Enum.GetValues(typeof (Favorites)))
|
||||
{
|
||||
foreach (char c in value)
|
||||
{
|
||||
if (c == fav.ToString()[0])
|
||||
{
|
||||
favMask |= fav;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var favChar = fav.ToString()[0];
|
||||
if (value.IndexOf(favChar) >= 0)
|
||||
favMask |= fav;
|
||||
}
|
||||
return favMask;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
{
|
||||
public class Crc16
|
||||
{
|
||||
#region static IBM/Modbus implementation
|
||||
|
||||
// CRC-16-IBM aka Modbus, LSB first (right shift) with polynomial 0x8005
|
||||
private static readonly ushort[] CrcTable = {
|
||||
private static readonly ushort[] CrcTable =
|
||||
{
|
||||
0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
|
||||
0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
|
||||
0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
|
||||
@@ -35,22 +38,72 @@
|
||||
0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
|
||||
0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
|
||||
0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
|
||||
0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 };
|
||||
0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040
|
||||
};
|
||||
|
||||
public static ushort Calc(byte[] data, int startOffset = 0, int length = -1)
|
||||
public static ushort Modbus(byte[] data, int startOffset = 0, int length = -1)
|
||||
{
|
||||
if (length == -1)
|
||||
length = data.Length;
|
||||
length = data.Length - startOffset;
|
||||
|
||||
ushort crc = 0xFFFF;
|
||||
while (--length >= 0)
|
||||
{
|
||||
byte temp = (byte)(data[startOffset++] ^ crc);
|
||||
var temp = (byte)(data[startOffset++] ^ crc);
|
||||
crc >>= 8;
|
||||
crc ^= CrcTable[temp];
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region static CCITT implementation
|
||||
|
||||
private static Crc16 ccitt;
|
||||
/// <summary>
|
||||
/// Unreflected (most significant bit first) CRC16-CCITT with polynomial 0x1021 and initial value 0xFFFF
|
||||
/// </summary>
|
||||
public static Crc16 CCITT => ccitt ??= new Crc16(0x1021, 0xffff);
|
||||
#endregion
|
||||
|
||||
private readonly ushort[] table = new ushort[256];
|
||||
private readonly ushort init;
|
||||
|
||||
public Crc16(ushort poly, ushort init = 0)
|
||||
{
|
||||
InitTable(poly);
|
||||
this.init = init;
|
||||
}
|
||||
|
||||
private void InitTable(ushort poly)
|
||||
{
|
||||
for (int i = 0; i < table.Length; ++i)
|
||||
{
|
||||
var temp = (ushort)0;
|
||||
var a = (ushort)(i << 8);
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
if (((temp ^ a) & 0x8000) != 0)
|
||||
temp = (ushort)((temp << 1) ^ poly);
|
||||
else
|
||||
temp <<= 1;
|
||||
a <<= 1;
|
||||
}
|
||||
|
||||
table[i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
public ushort Calc(byte[] data, int startOffset = 0, int length = -1)
|
||||
{
|
||||
var crc = init;
|
||||
if (length < 0)
|
||||
length = data.Length - startOffset;
|
||||
var end = startOffset + length;
|
||||
for (int i = startOffset; i < end; i++)
|
||||
crc = (ushort)((crc << 8) ^ table[(crc >> 8) ^ (0xff & data[i])]);
|
||||
return crc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
public static Crc32 Normal = new Crc32(true, NormalPoly);
|
||||
public static Crc32 Reversed = new Crc32(false, NormalPoly);
|
||||
private static readonly byte[] BitReversedBytes = new byte[256];
|
||||
internal static readonly byte[] BitReversedBytes = new byte[256];
|
||||
|
||||
private readonly uint[] crc32Table;
|
||||
private readonly bool msbFirst;
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace ChanSort.Loader.Philips
|
||||
//if (length > 0x0140000)
|
||||
// length = 0x0140000;
|
||||
|
||||
var actualCrc = Crc16.Calc(data, 0, length);
|
||||
var actualCrc = Crc16.Modbus(data, 0, length);
|
||||
if (actualCrc != expectedCrc)
|
||||
{
|
||||
var msg = $"chanLst.bin: stored CRC for {entry.Key} is {expectedCrc:X4} but calculated {actualCrc:X4}";
|
||||
@@ -160,7 +160,7 @@ namespace ChanSort.Loader.Philips
|
||||
var length = data.Length;
|
||||
if (VersionMajor < 12 && length > 0x6000)
|
||||
length = 0x6000; // there might be another cap at 0x013FA000 + 0x6000 in some versions
|
||||
var crc = Crc16.Calc(data, 0, length);
|
||||
var crc = Crc16.Modbus(data, 0, length);
|
||||
var off = entry.Value;
|
||||
content[off] = (byte) crc;
|
||||
content[off + 1] = (byte) (crc >> 8);
|
||||
|
||||
16
source/ChanSort.Loader.TCL/ChanSort.Loader.TCL.csproj
Normal file
16
source/ChanSort.Loader.TCL/ChanSort.Loader.TCL.csproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.1" />
|
||||
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ChanSort.Api\ChanSort.Api.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
355
source/ChanSort.Loader.TCL/DtvDataSerializer.cs
Normal file
355
source/ChanSort.Loader.TCL/DtvDataSerializer.cs
Normal file
@@ -0,0 +1,355 @@
|
||||
using System.Text;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using ChanSort.Api;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.Tar;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Readers;
|
||||
using SharpCompress.Writers.Tar;
|
||||
|
||||
namespace ChanSort.Loader.TCL
|
||||
{
|
||||
/*
|
||||
* This class loads TCL / Thomson .tar files containing DtvData.db and satellite.db SQLite databases.
|
||||
*
|
||||
* None of the sample files contained more than a single input source (DVB-C/T/S), so for the time being this loader puts everything into a single list
|
||||
*/
|
||||
class DtvDataSerializer : SerializerBase
|
||||
{
|
||||
private readonly ChannelList channels = new (SignalSource.All, "All");
|
||||
private string dtvFile;
|
||||
private string crcFile;
|
||||
|
||||
private readonly HashSet<string> tableNames = new();
|
||||
private readonly StringBuilder protocol = new();
|
||||
|
||||
#region ctor()
|
||||
public DtvDataSerializer(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 = true;
|
||||
this.Features.FavoritesMode = FavoritesMode.Flags;
|
||||
this.Features.MaxFavoriteLists = 1;
|
||||
|
||||
this.DataRoot.AddChannelList(this.channels);
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Skip));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Encrypted));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.AudioPid));
|
||||
channels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Provider));
|
||||
channels.VisibleColumnFieldNames.Add(nameof(ChannelInfo.Source));
|
||||
}
|
||||
#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()
|
||||
{
|
||||
using var tar = TarArchive.Open(this.FileName);
|
||||
var rdr = tar.ExtractAllEntries();
|
||||
this.TempPath = Path.Combine(Path.GetTempPath(), "ChanSort_" + DateTime.Now.ToString("yyyyMMdd-HHmmss"));
|
||||
Directory.CreateDirectory(this.TempPath);
|
||||
rdr.WriteAllToDirectory(this.TempPath, new ExtractionOptions { ExtractFullPath=true });
|
||||
|
||||
this.crcFile = Path.Combine(this.TempPath, "database", "cloneCRC.bin");
|
||||
var dbDir = Path.Combine(this.TempPath, "database", "userdata");
|
||||
this.dtvFile = Path.Combine(dbDir, "DtvData.db");
|
||||
var satFile = Path.Combine(dbDir, "satellite.db");
|
||||
|
||||
if (!File.Exists(dtvFile) || !File.Exists(satFile))
|
||||
throw LoaderException.TryNext("DtvData.db or satellite.db missing");
|
||||
|
||||
ValidateCrc(satFile);
|
||||
|
||||
string satConnString = $"Data Source={satFile};Pooling=False";
|
||||
using (var conn = new SqliteConnection(satConnString))
|
||||
{
|
||||
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("sateliteinfotbl") || !this.tableNames.Contains("transponderinfotbl"))
|
||||
throw LoaderException.TryNext("File doesn't contain the expected tables");
|
||||
|
||||
this.ReadSatellites(cmd);
|
||||
}
|
||||
|
||||
string dtvConnString = $"Data Source={dtvFile};Pooling=False";
|
||||
using (var conn = new SqliteConnection(dtvConnString))
|
||||
{
|
||||
conn.Open();
|
||||
using var cmd = conn.CreateCommand();
|
||||
this.RepairCorruptedDatabaseImage(cmd);
|
||||
|
||||
this.ReadTransponders(cmd);
|
||||
this.ReadChannels(cmd);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ValidateCrc()
|
||||
private void ValidateCrc(string satFile)
|
||||
{
|
||||
if (!File.Exists(crcFile))
|
||||
return;
|
||||
|
||||
var crcData = File.ReadAllBytes(crcFile);
|
||||
var crc = Crc16.CCITT;
|
||||
|
||||
var data = File.ReadAllBytes(dtvFile);
|
||||
var actual = crc.Calc(data);
|
||||
var expected = BitConverter.ToUInt16(crcData, 2);
|
||||
if (actual != expected)
|
||||
{
|
||||
var msg = $"Invalid CRC16-CCITT check sum for {dtvFile}. Expected {expected:X4} but calculated {actual:X4}";
|
||||
protocol.AppendLine(msg);
|
||||
//throw LoaderException.Fail(msg);
|
||||
}
|
||||
|
||||
data = File.ReadAllBytes(satFile);
|
||||
actual = crc.Calc(data);
|
||||
expected = BitConverter.ToUInt16(crcData, 4);
|
||||
if (actual != expected)
|
||||
{
|
||||
var msg = $"Invalid CRC16-CCITT check sum for {satFile}. Expected {expected:X4} but calculated {actual:X4}";
|
||||
protocol.AppendLine(msg);
|
||||
//throw LoaderException.Fail(msg);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RepairCorruptedDatabaseImage()
|
||||
private void RepairCorruptedDatabaseImage(SqliteCommand cmd)
|
||||
{
|
||||
cmd.CommandText = "REINDEX";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadSatellites()
|
||||
private void ReadSatellites(SqliteCommand cmd)
|
||||
{
|
||||
cmd.CommandText = "select SateliteID, SateliteName, Longitude from SateliteInfoTbl";
|
||||
using var r = cmd.ExecuteReader();
|
||||
while (r.Read())
|
||||
{
|
||||
Satellite sat = new Satellite(r.GetInt32(0));
|
||||
string eastWest = "E";
|
||||
int pos = r.IsDBNull(2) ? 0 : r.GetInt32(2);
|
||||
if (pos != 0)
|
||||
{
|
||||
if (pos < 0)
|
||||
{
|
||||
pos = -pos;
|
||||
eastWest = "W";
|
||||
}
|
||||
|
||||
sat.OrbitalPosition = $"{pos / 100}.{pos % 100}{eastWest}";
|
||||
}
|
||||
|
||||
sat.Name = r.GetString(1);
|
||||
this.DataRoot.AddSatellite(sat);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadTransponders()
|
||||
private void ReadTransponders(SqliteCommand cmd)
|
||||
{
|
||||
//cmd.CommandText = "select TransponderId, SateliteId, Freq, Polarisation, SymbolRate from TransponderInfoTbl";
|
||||
cmd.CommandText = "select u16MuxTblID, SatTblID, Freq, null, SymbolRate, TransportStreamId, OriginalNetworkId from MuxInfoTbl";
|
||||
using var r = cmd.ExecuteReader();
|
||||
while (r.Read())
|
||||
{
|
||||
int id = r.GetInt32(0);
|
||||
int satId = r.IsDBNull(1) ? -1 : 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 / 1000;
|
||||
//tp.Polarity = r.GetInt32(3) == 0 ? 'H' : 'V';
|
||||
tp.Satellite = this.DataRoot.Satellites.TryGet(satId);
|
||||
tp.SymbolRate = r.GetInt32(4);
|
||||
tp.TransportStreamId = r.GetInt32(5);
|
||||
tp.OriginalNetworkId = r.GetInt32(6);
|
||||
this.DataRoot.AddTransponder(tp.Satellite, tp);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadChannels()
|
||||
private void ReadChannels(SqliteCommand cmd)
|
||||
{
|
||||
cmd.CommandText = $@"
|
||||
select
|
||||
p.u32Index, p.ProgNum, p.ServiceName, p.ShortServiceName, p.ServiceID, p.VideoType, p.PCRPID, p.VideoPID, p.unlockedFlag, p.LCN, p.LCNAssignmentType, p.EditFlag,
|
||||
m.OriginalNetworkId, m.TransportStreamId, m.Freq, m.SymbolRate,
|
||||
c.RouteName
|
||||
from ProgramInfoTbl p
|
||||
left outer join MuxInfoTbl m on m.u16MuxTblID=p.u16MuxTblID
|
||||
left outer join CurCIOPSerType c on c.u8DtvRoute=p.u8DtvRoute
|
||||
";
|
||||
|
||||
using var r = cmd.ExecuteReader();
|
||||
while (r.Read())
|
||||
{
|
||||
var handle = r.GetInt32(0);
|
||||
var oldProgNr = r.GetInt32(1);
|
||||
if (oldProgNr == 65535)
|
||||
continue;
|
||||
|
||||
var name = r.GetString(2)?.TrimEnd(' ', '\0');
|
||||
ChannelInfo channel = new ChannelInfo(0, handle, oldProgNr, name);
|
||||
channel.ShortName = r.GetString(3).TrimEnd(' ', '\0');
|
||||
channel.ServiceId = r.GetInt32(4);
|
||||
var vtype = r.GetInt32(5);
|
||||
channel.ServiceTypeName = vtype == 1 ? "SD-TV" : vtype == 4 ? "HD-TV" : vtype == 6 ? "UHD-TV" : null;
|
||||
channel.PcrPid = r.GetInt32(6);
|
||||
channel.VideoPid = r.GetInt32(7);
|
||||
channel.Hidden = r.GetBoolean(8);
|
||||
var edit = r.GetInt32(11);
|
||||
channel.Favorites = (edit & 0x01) != 0 ? Favorites.A : 0;
|
||||
channel.AddDebug($"LCN={r.GetValue(9)}, AT={r.GetValue(10)}, Edit={edit:x4}");
|
||||
|
||||
// DVB
|
||||
var ixD = 12;
|
||||
var ixC = ixD + 4;
|
||||
if (!r.IsDBNull(ixD))
|
||||
{
|
||||
channel.OriginalNetworkId = r.GetInt32(ixD + 0);
|
||||
channel.TransportStreamId = r.GetInt32(ixD + 1);
|
||||
channel.FreqInMhz = (decimal) r.GetInt32(ixD + 2) / 1000;
|
||||
channel.SymbolRate = r.GetInt32(ixD + 3);
|
||||
if (channel.FreqInMhz > 10000)
|
||||
channel.FreqInMhz = (int) channel.FreqInMhz;
|
||||
channel.Source = r.GetString(ixC);
|
||||
}
|
||||
|
||||
if (!channel.IsDeleted)
|
||||
this.DataRoot.AddChannel(this.channels, channel);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Save()
|
||||
public override void Save()
|
||||
{
|
||||
string channelConnString = $"Data Source={dtvFile};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);
|
||||
}
|
||||
|
||||
UpdateCrc();
|
||||
|
||||
WriteToTar();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WriteChannels()
|
||||
private void WriteChannels(SqliteCommand cmd, SqliteCommand cmdDelete, ChannelList channelList)
|
||||
{
|
||||
cmd.CommandText = "update PrograminfoTbl set ProgNum=@nr, ServiceName=@name, unlockedFlag=@hide, EditFlag=(EditFlag & 0xFFFFFFFE) | @editflag where u32Index=@handle";
|
||||
cmd.Parameters.Add("@handle", SqliteType.Integer);
|
||||
cmd.Parameters.Add("@nr", SqliteType.Integer);
|
||||
cmd.Parameters.Add("@name", SqliteType.Text);
|
||||
cmd.Parameters.Add("@hide", SqliteType.Integer);
|
||||
cmd.Parameters.Add("@editflag", SqliteType.Integer);
|
||||
cmd.Prepare();
|
||||
|
||||
cmdDelete.CommandText = @"delete from PrograminfoTbl where u32Index=@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.Parameters["@hide"].Value = channel.Hidden;
|
||||
cmd.Parameters["@editflag"].Value = channel.Favorites == 0 ? 0 : 0x0001;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdateCrc
|
||||
private void UpdateCrc()
|
||||
{
|
||||
// update cloneCRC.bin in temp folder
|
||||
var dtvData = File.ReadAllBytes(dtvFile);
|
||||
var crc = Crc16.CCITT.Calc(dtvData);
|
||||
var crcData = File.ReadAllBytes(this.crcFile);
|
||||
crcData[2] = (byte)(crc & 0xFF);
|
||||
crcData[3] = (byte)(crc >> 8);
|
||||
File.WriteAllBytes(crcFile, crcData);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WriteToTar()
|
||||
private void WriteToTar()
|
||||
{
|
||||
// delete old .tar file and create a new one from temp dir
|
||||
File.Delete(this.FileName);
|
||||
using var tar = TarArchive.Create();
|
||||
tar.AddAllFromDirectory(this.TempPath);
|
||||
tar.SaveTo(this.FileName, new TarWriterOptions(CompressionType.None, true));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
16
source/ChanSort.Loader.TCL/TclPlugin.cs
Normal file
16
source/ChanSort.Loader.TCL/TclPlugin.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.TCL
|
||||
{
|
||||
public class TclPlugin : ISerializerPlugin
|
||||
{
|
||||
public string DllName { get; set; }
|
||||
public string PluginName => "TCL";
|
||||
public string FileFilter => "*.tar";
|
||||
|
||||
public SerializerBase CreateSerializer(string inputFile)
|
||||
{
|
||||
return new DtvDataSerializer(inputFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,8 +181,8 @@ left outer join ChanDataTable ac on ac.handle=a.m_channel_no
|
||||
// DVB
|
||||
if (!r.IsDBNull(ixD + 0))
|
||||
{
|
||||
channel.OriginalNetworkId = r.GetInt32(ixD + 0) & 0x1FFF;
|
||||
channel.TransportStreamId = r.GetInt32(ixD + 1) & 0x1FFF;
|
||||
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);
|
||||
|
||||
@@ -101,6 +101,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test.Loader.CmdbBin", "Test
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChanSort.Loader.Unsupported", "ChanSort.Loader.Unsupported\ChanSort.Loader.Unsupported.csproj", "{D7C32DAE-5D77-46A0-BC16-C95D9C7EFDD5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChanSort.Loader.TCL", "ChanSort.Loader.TCL\ChanSort.Loader.TCL.csproj", "{460D9527-F7EF-4277-9382-FB609A44D66A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
All_Debug|Any CPU = All_Debug|Any CPU
|
||||
@@ -1228,6 +1230,36 @@ Global
|
||||
{D7C32DAE-5D77-46A0-BC16-C95D9C7EFDD5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{D7C32DAE-5D77-46A0-BC16-C95D9C7EFDD5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D7C32DAE-5D77-46A0-BC16-C95D9C7EFDD5}.Release|x86.Build.0 = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Debug|x86.Build.0 = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Release|x86.ActiveCfg = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.All_Release|x86.Build.0 = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.NoDevExpress_Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.NoDevExpress_Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.NoDevExpress_Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.NoDevExpress_Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.NoDevExpress_Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.NoDevExpress_Debug|x86.Build.0 = Debug|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{460D9527-F7EF-4277-9382-FB609A44D66A}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\Solution.props"/>
|
||||
<Import Project="..\Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
@@ -142,6 +142,7 @@
|
||||
<ProjectReference Include="..\ChanSort.Loader.SatcoDX\ChanSort.Loader.SatcoDX.csproj" />
|
||||
<ProjectReference Include="..\ChanSort.Loader.Sharp\ChanSort.Loader.Sharp.csproj" />
|
||||
<ProjectReference Include="..\ChanSort.Loader.Sony\ChanSort.Loader.Sony.csproj" />
|
||||
<ProjectReference Include="..\ChanSort.Loader.TCL\ChanSort.Loader.TCL.csproj" />
|
||||
<ProjectReference Include="..\ChanSort.Loader.Toshiba\ChanSort.Loader.Toshiba.csproj" />
|
||||
<ProjectReference Include="..\ChanSort.Loader.Unsupported\ChanSort.Loader.Unsupported.csproj" />
|
||||
<ProjectReference Include="..\ChanSort.Loader.VDR\ChanSort.Loader.VDR.csproj" />
|
||||
|
||||
376
source/ChanSort/MainForm.Designer.cs
generated
376
source/ChanSort/MainForm.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -72,6 +72,9 @@ namespace ChanSort.Ui
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
//this.repositoryItemCheckedComboBoxEdit1.SetFlags(typeof(Favorites));
|
||||
//this.repositoryItemCheckedComboBoxEdit2.SetFlags(typeof(Favorites));
|
||||
|
||||
base.DoubleBuffered = true;
|
||||
|
||||
var version = this.GetType().Assembly.GetName().Version;
|
||||
@@ -516,6 +519,7 @@ namespace ChanSort.Ui
|
||||
regex += "]*";
|
||||
this.repositoryItemCheckedComboBoxEdit1.Mask.EditMask = regex;
|
||||
this.repositoryItemCheckedComboBoxEdit2.Mask.EditMask = regex;
|
||||
|
||||
this.repositoryItemCheckedComboBoxEdit1.ReadOnly = this.repositoryItemCheckedComboBoxEdit2.ReadOnly = favorites == 0;
|
||||
|
||||
this.tabSubList.BeginUpdate();
|
||||
@@ -2374,11 +2378,26 @@ namespace ChanSort.Ui
|
||||
|
||||
private void gview_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e)
|
||||
{
|
||||
var channel = (ChannelInfo) e.Row;
|
||||
if (e.Column.FieldName == "Position")
|
||||
e.Value = channel.GetPosition(this.subListIndex);
|
||||
else if (e.Column.FieldName == "OldPosition")
|
||||
e.Value = channel.GetOldPosition(this.subListIndex);
|
||||
var field = e.Column.FieldName;
|
||||
|
||||
if (e.IsGetData)
|
||||
{
|
||||
var channel = (ChannelInfo)e.Row;
|
||||
if (field == "Position")
|
||||
e.Value = channel.GetPosition(this.subListIndex);
|
||||
else if (field == "OldPosition")
|
||||
e.Value = channel.GetOldPosition(this.subListIndex);
|
||||
else if (field == colFavorites.FieldName)
|
||||
e.Value = GetFavString(channel.Favorites);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.Column.FieldName == colFavorites.FieldName)
|
||||
{
|
||||
var channel = (ChannelInfo)e.Row;
|
||||
channel.Favorites = ChannelInfo.ParseFavString(e.Value?.ToString() ?? "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -2561,19 +2580,6 @@ namespace ChanSort.Ui
|
||||
|
||||
#endregion
|
||||
|
||||
#region gviewLeft_CustomColumnDisplayText
|
||||
|
||||
private void gviewLeft_CustomColumnDisplayText(object sender, CustomColumnDisplayTextEventArgs e)
|
||||
{
|
||||
if (e.Column == this.colOutFav)
|
||||
{
|
||||
if (e.Value is Favorites fav)
|
||||
e.DisplayText = GetFavString(fav);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region gviewLeft_RowCellStyle
|
||||
|
||||
private void gviewLeft_RowCellStyle(object sender, RowCellStyleEventArgs e)
|
||||
@@ -2743,11 +2749,6 @@ namespace ChanSort.Ui
|
||||
if ((int) e.Value == -1)
|
||||
e.DisplayText = string.Empty;
|
||||
}
|
||||
else if (e.Column == this.colFavorites)
|
||||
{
|
||||
if (e.Value is Favorites fav)
|
||||
e.DisplayText = GetFavString(fav);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,12 @@
|
||||
ChanSort Change Log
|
||||
===================
|
||||
|
||||
TBA
|
||||
2023-01-03
|
||||
- added support for TCL / Thomson \*.tar channel lists (containing DtvData.db and satellite.db)
|
||||
- fixed text input for "Favorites" column (where applicable)
|
||||
- fixed: menu "settings / allow editing predefined lists (DANGEROUS)" unlocked the edit functions
|
||||
in the user interface, but changes to those lists were not saved to disk.
|
||||
- changed build process to use MSBuild project files (to allow future switch to .NET 7 or 8)
|
||||
|
||||
2022-12-04
|
||||
- fixed: various .xml file formats could not be loaded anymore
|
||||
|
||||
@@ -7,32 +7,31 @@ set languages=cs de es hu pl pt ro ru tr
|
||||
set curdate=%date:~6,4%-%date:~3,2%-%date:~0,2%
|
||||
set target=%cd%\..\..\ChanSort_%curdate%
|
||||
set DXversion=22.1
|
||||
set framework=net48
|
||||
set bindir=debug\%framework%
|
||||
mkdir "%target%" 2>nul
|
||||
rem del /s /q "%target%\*"
|
||||
xcopy /idy debug\ChanSort.exe* "%target%"
|
||||
xcopy /idy debug\ChanSort.*.dll "%target%"
|
||||
xcopy /idy debug\ChanSort.ico "%target%"
|
||||
xcopy /idy debug\ChanSort.*.ini "%target%"
|
||||
|
||||
xcopy /idy debug\Microsoft.Data.Sqlite.dll "%target%"
|
||||
xcopy /idy debug\SQLitePCLRaw.*.dll "%target%"
|
||||
xcopy /idy debug\System.Memory.dll "%target%"
|
||||
xcopy /idy debug\System.Runtime.CompilerServices.Unsafe.dll "%target%"
|
||||
xcopy /idy %bindir%\ChanSort.exe* "%target%"
|
||||
xcopy /idy %bindir%\ChanSort.*.dll "%target%"
|
||||
xcopy /idy %bindir%\ChanSort.ico "%target%"
|
||||
xcopy /idy %bindir%\ChanSort.*.ini "%target%"
|
||||
|
||||
xcopy /idy %bindir%\Microsoft.*.dll "%target%"
|
||||
xcopy /idy %bindir%\SQLitePCLRaw.*.dll "%target%"
|
||||
mkdir "%target%\runtimes" 2>nul
|
||||
rem xcopy /sidy debug\runtimes\* "%target%\runtimes"
|
||||
xcopy /idys packages\SQLitePCLRaw.lib.e_sqlite3.2.1.2\runtimes\win-arm "%target%\runtimes\win-arm"
|
||||
xcopy /idys packages\SQLitePCLRaw.lib.e_sqlite3.2.1.2\runtimes\win-arm64 "%target%\runtimes\win-arm64"
|
||||
xcopy /idys packages\SQLitePCLRaw.lib.e_sqlite3.2.1.2\runtimes\win-x86 "%target%\runtimes\win-x86"
|
||||
xcopy /idys packages\SQLitePCLRaw.lib.e_sqlite3.2.1.2\runtimes\win-x64 "%target%\runtimes\win-x64"
|
||||
|
||||
xcopy /idy debug\Newtonsoft.Json.dll "%target%"
|
||||
xcopy /idy debug\Lookup.csv "%target%"
|
||||
xcopy /idy %bindir%\SharpCompress.dll "%target%"
|
||||
xcopy /idy %bindir%\System.*.dll "%target%"
|
||||
xcopy /idy %bindir%\Newtonsoft.Json.dll "%target%"
|
||||
xcopy /idy %bindir%\Lookup.csv "%target%"
|
||||
xcopy /idy DLL\* "%target%"
|
||||
del "%target%\*nunit*.dll"
|
||||
for %%l in (%languages%) do (
|
||||
mkdir "%target%\%%l" 2>nul
|
||||
xcopy /sidy debug\%%l\ChanSort.* "%target%\%%l"
|
||||
xcopy /sidy %bindir%\%%l\ChanSort.* "%target%\%%l"
|
||||
)
|
||||
mkdir "%target%\ReferenceLists" 2>nul
|
||||
xcopy /sidy ChanSort\ReferenceLists\* "%target%\ReferenceLists"
|
||||
|
||||
Reference in New Issue
Block a user