From 63aefd0cad5b5e7c6c1558934b647cf4800550ae Mon Sep 17 00:00:00 2001 From: hbeham Date: Thu, 11 Apr 2013 01:38:37 +0200 Subject: [PATCH] - Added support for Toshiba *.zip channel list (chmgt.db, ... SQLite files) --- ChanSort.Api/Controller/SerializerBase.cs | 2 +- .../ChanSort.Loader.DbFile.csproj | 7 +- ChanSort.Loader.DbFile/DbChannel.cs | 145 +++++++++++ ChanSort.Loader.DbFile/DbSerializer.cs | 226 ++++++++++-------- ChanSort.Loader.DbFile/DbSerializerPlugin.cs | 4 +- ChanSort.Loader.ScmFile/ScmSerializer.cs | 2 +- ChanSort.Loader.TllFile/TllFileSerializer.cs | 2 +- ChanSort/MainForm.cs | 4 +- ChanSort/MainForm.de.resx | 2 +- ChanSort/MainForm.resx | 2 +- readme.txt | 9 +- 11 files changed, 285 insertions(+), 120 deletions(-) create mode 100644 ChanSort.Loader.DbFile/DbChannel.cs diff --git a/ChanSort.Api/Controller/SerializerBase.cs b/ChanSort.Api/Controller/SerializerBase.cs index 3786114..54f4be2 100644 --- a/ChanSort.Api/Controller/SerializerBase.cs +++ b/ChanSort.Api/Controller/SerializerBase.cs @@ -29,7 +29,7 @@ namespace ChanSort.Api public abstract string DisplayName { get; } public abstract void Load(); - public abstract void Save(string tvOutputFile, string csvOutputFile); + public abstract void Save(string tvOutputFile); public virtual Encoding DefaultEncoding { diff --git a/ChanSort.Loader.DbFile/ChanSort.Loader.DbFile.csproj b/ChanSort.Loader.DbFile/ChanSort.Loader.DbFile.csproj index bf71496..0d87214 100644 --- a/ChanSort.Loader.DbFile/ChanSort.Loader.DbFile.csproj +++ b/ChanSort.Loader.DbFile/ChanSort.Loader.DbFile.csproj @@ -54,8 +54,9 @@ false - - ..\DLL\SQLite.Designer.dll + + False + ..\DLL\ICSharpCode.SharpZipLib.dll @@ -64,13 +65,13 @@ - + diff --git a/ChanSort.Loader.DbFile/DbChannel.cs b/ChanSort.Loader.DbFile/DbChannel.cs new file mode 100644 index 0000000..e75e02a --- /dev/null +++ b/ChanSort.Loader.DbFile/DbChannel.cs @@ -0,0 +1,145 @@ +using System.Collections.Generic; +using System.Data.SQLite; +using System.Text; +using ChanSort.Api; + +namespace ChanSort.Loader.DbFile +{ + internal class DbChannel : ChannelInfo + { + private const int BITS_Tv = 0x10000; + private const int BITS_Radio = 0x20000; + private const int BITS_FavA = 0x100000; + private const int BITS_FavB = 0x200000; + private const int BITS_FavC = 0x400000; + private const int BITS_FavD = 0x800000; + private const int BITS_Locked = 0x20000000; + + internal int Bits; + + #region ctor() + internal DbChannel(SignalSource source, SQLiteDataReader r, IDictionary field, + DataRoot dataRoot, IDictionary encryptionInfo) + { + this.SignalSource = source; + this.RecordIndex = r.GetInt32(field["channel_handle"]); + + this.Bits = r.GetInt32(field["list_bits"]); + bool isTv = (Bits & BITS_Tv) != 0; + bool isRadio = (Bits & BITS_Radio) != 0; + bool isAnalog = (source & SignalSource.Analog) != 0; + if (isAnalog && !isTv) + { + this.IsDeleted = true; + return; + } + + if (isTv) this.SignalSource |= SignalSource.Tv; + if (isRadio) this.SignalSource |= SignalSource.Radio; + this.Lock = (Bits & BITS_Locked) != 0; + this.OldProgramNr = r.GetInt32(field["channel_number"]); + this.Favorites = this.ParseFavorites(Bits); + + if (isAnalog) + this.ReadAnalogData(r, field); + else + this.ReadDvbData(r, field, dataRoot, encryptionInfo); + } + #endregion + + #region ReadAnalogData() + private void ReadAnalogData(SQLiteDataReader r, IDictionary field) + { + this.Name = r.GetString(field["channel_label"]); + this.FreqInMhz = (decimal)r.GetInt32(field["frequency"]) / 1000000; + } + #endregion + + #region ReadDvbData() + protected void ReadDvbData(SQLiteDataReader r, IDictionary field, DataRoot dataRoot, + IDictionary encryptionInfo) + { + string longName, shortName; + this.GetChannelNames(r.GetString(field["channel_label"]), out longName, out shortName); + this.Name = longName; + this.ShortName = shortName; + this.RecordOrder = r.GetInt32(field["channel_order"]); + this.FreqInMhz = (decimal)r.GetInt32(field["frequency"]) / 1000; + int serviceType = r.GetInt32(field["dvb_service_type"]); + this.ServiceType = serviceType; + this.OriginalNetworkId = r.GetInt32(field["onid"]); + this.TransportStreamId = r.GetInt32(field["tsid"]); + this.ServiceId = r.GetInt32(field["sid"]); + int bits = r.GetInt32(field["list_bits"]); + this.Favorites = this.ParseFavorites(bits); + if ((this.SignalSource & SignalSource.Sat) != 0) + { + int satId = r.GetInt32(field["sat_id"]); + var sat = dataRoot.Satellites.TryGet(satId); + if (sat != null) + { + this.Satellite = sat.Name; + this.SatPosition = sat.OrbitalPosition; + int tpId = satId * 1000000 + (int)this.FreqInMhz; + var tp = dataRoot.Transponder.TryGet(tpId); + if (tp != null) + { + this.SymbolRate = tp.SymbolRate; + } + } + } + this.Encrypted = encryptionInfo.TryGet(this.Uid); + } + #endregion + + #region GetChannelNames() + private void GetChannelNames(string name, out string longName, out string shortName) + { + StringBuilder sbLong = new StringBuilder(); + StringBuilder sbShort = new StringBuilder(); + + bool inShort = false; + foreach (char c in name) + { + if (c == 0x86) + inShort = true; + else if (c == 0x87) + inShort = false; + if (c >= 0x80 && c <= 0x9F) + continue; + + if (inShort) + sbShort.Append(c); + sbLong.Append(c); + } + + longName = sbLong.ToString(); + shortName = sbShort.ToString(); + } + #endregion + + #region ParseFavorites() + private Favorites ParseFavorites(int bits) + { + Favorites fav = 0; + if ((bits & BITS_FavA) != 0) fav |= Favorites.A; + if ((bits & BITS_FavB) != 0) fav |= Favorites.B; + if ((bits & BITS_FavC) != 0) fav |= Favorites.C; + if ((bits & BITS_FavD) != 0) fav |= Favorites.D; + return fav; + } + #endregion + + #region UpdateRawData() + public override void UpdateRawData() + { + Bits &= ~(BITS_FavA | BITS_FavB | BITS_FavC | BITS_FavC | BITS_FavD | BITS_Locked); + if ((this.Favorites & Favorites.A) != 0) Bits |= BITS_FavA; + if ((this.Favorites & Favorites.B) != 0) Bits |= BITS_FavB; + if ((this.Favorites & Favorites.C) != 0) Bits |= BITS_FavC; + if ((this.Favorites & Favorites.D) != 0) Bits |= BITS_FavD; + if (this.Lock) Bits |= BITS_Locked; + } + #endregion + } +} diff --git a/ChanSort.Loader.DbFile/DbSerializer.cs b/ChanSort.Loader.DbFile/DbSerializer.cs index 1d84f4a..dd44fc4 100644 --- a/ChanSort.Loader.DbFile/DbSerializer.cs +++ b/ChanSort.Loader.DbFile/DbSerializer.cs @@ -1,20 +1,19 @@ using System; using System.Collections.Generic; +using System.Data; using System.Data.SQLite; using System.IO; -using System.Text; +using System.Windows.Forms; using ChanSort.Api; +using ICSharpCode.SharpZipLib.Zip; namespace ChanSort.Loader.DbFile { class DbSerializer : SerializerBase { - private const int BITS_Tv = 0x10000; - private const int BITS_FavA = 0x100000; - private const int BITS_FavB = 0x200000; - private const int BITS_FavC = 0x400000; - private const int BITS_FavD = 0x800000; - private const int BITS_Locked = 0x20000000; + private const string FILE_chmgt_db = "chmgt.db"; + private const string FILE_dvbSysData_db = "dvbSysData.db"; + private const string FILE_dvbMainData_db = "dvbMainData.db"; private readonly ChannelList atvChannels = new ChannelList(SignalSource.AnalogCT | SignalSource.TvAndRadio, "Analog"); private readonly ChannelList dtvTvChannels = new ChannelList(SignalSource.DvbCT | SignalSource.Tv, "DTV"); @@ -23,6 +22,8 @@ namespace ChanSort.Loader.DbFile private readonly ChannelList satRadioChannels = new ChannelList(SignalSource.DvbS | SignalSource.Radio, "Sat-Radio"); private readonly Dictionary channelInfoByUid = new Dictionary(); + private string tempDir; + #region ctor() public DbSerializer(string inputFile) : base(inputFile) { @@ -44,9 +45,9 @@ namespace ChanSort.Loader.DbFile #region Load() public override void Load() { - string baseDir = Path.GetDirectoryName(Path.GetDirectoryName(this.FileName)); - - string sysDataConnString = "Data Source=" + baseDir + "\\dvb_type001\\dvbSysData.db"; + this.UnzipDataFile(); + + string sysDataConnString = "Data Source=" + tempDir + FILE_dvbSysData_db; using (var conn = new SQLiteConnection(sysDataConnString)) { conn.Open(); @@ -57,7 +58,7 @@ namespace ChanSort.Loader.DbFile } } - string mainDataConnString = "Data Source=" + baseDir + "\\dvb_type001\\dvbMainData.db"; + string mainDataConnString = "Data Source=" + tempDir + FILE_dvbMainData_db; using (var conn = new SQLiteConnection(mainDataConnString)) { conn.Open(); @@ -67,7 +68,7 @@ namespace ChanSort.Loader.DbFile } } - string channelConnString = "Data Source=" + this.FileName; + string channelConnString = "Data Source=" + tempDir + FILE_chmgt_db; using (var conn = new SQLiteConnection(channelConnString)) { conn.Open(); @@ -81,6 +82,53 @@ namespace ChanSort.Loader.DbFile } #endregion + #region UnzipDataFile() + private void UnzipDataFile() + { + this.tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()) + "\\"; + Directory.CreateDirectory(tempDir); + Application.ApplicationExit += this.CleanTempFolder; + + using (ZipFile zip = new ZipFile(this.FileName)) + { + this.Expand(zip, "chmgt_type001/" + FILE_chmgt_db); + this.Expand(zip, "dvb_type001/" + FILE_dvbSysData_db); + this.Expand(zip, "dvb_type001/" + FILE_dvbMainData_db); + } + } + #endregion + + #region CleanTempFolder() + private void CleanTempFolder(object sender, EventArgs e) + { + try + { + foreach(var file in Directory.GetFiles(this.tempDir)) + File.Delete(file); + Directory.Delete(this.tempDir); + } + catch { } + } + #endregion + + #region Expand() + private void Expand(ZipFile zip, string path) + { + var entry = zip.GetEntry(path); + if (entry == null) + throw new FileLoadException("File not found inside .zip: " + path); + + byte[] buffer = new byte[65536]; + using (var input = zip.GetInputStream(entry)) + using (var output = new FileStream(this.tempDir + Path.GetFileName(path), FileMode.Create)) + { + int len; + while ((len = input.Read(buffer, 0, buffer.Length)) != 0) + output.Write(buffer, 0, len); + } + } + #endregion + #region ReadSatellites() private void ReadSatellites(SQLiteCommand cmd) { @@ -155,26 +203,13 @@ namespace ChanSort.Loader.DbFile using (var r = cmd.ExecuteReader()) { while (r.Read()) - ReadAnalogChannel(r, fields); + { + ChannelInfo channel = new DbChannel(SignalSource.Analog, r, fields, this.DataRoot, this.channelInfoByUid); + if (!channel.IsDeleted) + this.DataRoot.AddChannel(this.atvChannels, channel); + } } } - - private void ReadAnalogChannel(SQLiteDataReader r, IDictionary field) - { - var bits = r.GetInt32(field["list_bits"]); - if ((bits & BITS_Tv) == 0) - return; - - ChannelInfo channel = new ChannelInfo(SignalSource.Analog|SignalSource.Tv, - r.GetInt32(field["channel_handle"]), - r.GetInt32(field["channel_number"]), - r.GetString(field["channel_label"])); - - channel.FreqInMhz = (decimal) r.GetInt32(field["frequency"])/1000000; - channel.Favorites = this.ParseFavorites(bits); - - this.DataRoot.AddChannel(this.atvChannels, channel); - } #endregion #region ReadDtvChannels() @@ -203,58 +238,16 @@ namespace ChanSort.Loader.DbFile using (var r = cmd.ExecuteReader()) { while (r.Read()) - ReadDigitalChannel(r, fields, signalSource, tvChannels, radioChannels); - } - } - #endregion - - #region ReadDigitalChannel() - private void ReadDigitalChannel(SQLiteDataReader r, IDictionary field, SignalSource signalSource, ChannelList tvChannels, ChannelList radioChannels) - { - var name = r.GetString(field["channel_label"]); - string longName, shortName; - this.GetChannelNames(name, out longName, out shortName); - - ChannelInfo channel = new ChannelInfo(signalSource, - r.GetInt32(field["channel_handle"]), - r.GetInt32(field["channel_number"]), - longName); - channel.ShortName = shortName; - channel.RecordOrder = r.GetInt32(field["channel_order"]); - channel.FreqInMhz = (decimal)r.GetInt32(field["frequency"]) / 1000; - int serviceType = r.GetInt32(field["dvb_service_type"]); - if (serviceType == 1 || serviceType == 25) - channel.SignalSource |= SignalSource.Tv; - else if (serviceType == 2) - channel.SignalSource |= SignalSource.Radio; - channel.ServiceType = serviceType; - channel.OriginalNetworkId = r.GetInt32(field["onid"]); - channel.TransportStreamId = r.GetInt32(field["tsid"]); - channel.ServiceId = r.GetInt32(field["sid"]); - int bits = r.GetInt32(field["list_bits"]); - channel.Favorites = this.ParseFavorites(bits); - channel.Lock = (bits & BITS_Locked) != 0; - if ((signalSource & SignalSource.Sat) != 0) - { - int satId = r.GetInt32(field["sat_id"]); - var sat = this.DataRoot.Satellites.TryGet(satId); - if (sat != null) { - channel.Satellite = sat.Name; - channel.SatPosition = sat.OrbitalPosition; - int tpId = satId*1000000 + (int) channel.FreqInMhz; - var tp = this.DataRoot.Transponder.TryGet(tpId); - if (tp != null) + ChannelInfo channel = new DbChannel(signalSource, r, fields, this.DataRoot, this.channelInfoByUid); + if (!channel.IsDeleted) { - channel.SymbolRate = tp.SymbolRate; + var channelList = (channel.SignalSource & SignalSource.Radio) != 0 ? radioChannels : tvChannels; + this.DataRoot.AddChannel(channelList, channel); } } } - channel.Encrypted = this.channelInfoByUid.TryGet(channel.Uid); - - this.DataRoot.AddChannel(serviceType == 2 ? radioChannels : tvChannels, channel); } - #endregion #region GetQuery() @@ -282,48 +275,69 @@ namespace ChanSort.Loader.DbFile } #endregion - #region GetChannelNames() - private void GetChannelNames(string name, out string longName, out string shortName) + + #region Save() + public override void Save(string tvOutputFile) { - StringBuilder sbLong = new StringBuilder(); - StringBuilder sbShort = new StringBuilder(); - - bool inShort = false; - foreach (char c in name) + if (tvOutputFile != this.FileName) { - if (c == 0x86) - inShort = true; - else if (c == 0x87) - inShort = false; - if (c >= 0x80 && c <= 0x9F) - continue; - - if (inShort) - sbShort.Append(c); - sbLong.Append(c); + File.Copy(this.FileName, tvOutputFile); + this.FileName = tvOutputFile; } - longName = sbLong.ToString(); - shortName = sbShort.ToString(); + string channelConnString = "Data Source=" + this.tempDir + FILE_chmgt_db; + using (var conn = new SQLiteConnection(channelConnString)) + { + conn.Open(); + using (var cmd = conn.CreateCommand()) + { + using (var trans = conn.BeginTransaction()) + { + this.WriteChannels(cmd, "EuroATVChanList", this.atvChannels); + this.WriteChannels(cmd, "EuroDTVChanList", this.dtvTvChannels); + this.WriteChannels(cmd, "EuroDTVChanList", this.dtvRadioChannels); + this.WriteChannels(cmd, "EuroSATChanList", this.satTvChannels); + this.WriteChannels(cmd, "EuroSATChanList", this.satRadioChannels); + trans.Commit(); + } + } + } + + this.ZipFiles(); } #endregion - #region ParseFavorites() - private Favorites ParseFavorites(int bits) + #region WriteChannels() + private void WriteChannels(SQLiteCommand cmd, string table, ChannelList channelList) { - Favorites fav = 0; - if ((bits & BITS_FavA) != 0) fav |= Favorites.A; - if ((bits & BITS_FavB) != 0) fav |= Favorites.B; - if ((bits & BITS_FavC) != 0) fav |= Favorites.C; - if ((bits & BITS_FavD) != 0) fav |= Favorites.D; - return fav; + cmd.CommandText = "update " + table + " set channel_number=@nr, list_bits=@Bits where channel_handle=@id"; + cmd.Parameters.Add(new SQLiteParameter("@id", DbType.Int32)); + cmd.Parameters.Add(new SQLiteParameter("@nr", DbType.Int32)); + cmd.Parameters.Add(new SQLiteParameter("@Bits", DbType.Int32)); + cmd.Prepare(); + foreach (DbChannel channel in channelList.Channels) + { + channel.UpdateRawData(); + cmd.Parameters["@id"].Value = channel.RecordIndex; + cmd.Parameters["@nr"].Value = channel.NewProgramNr; + cmd.Parameters["@Bits"].Value = channel.Bits; + cmd.ExecuteNonQuery(); + } } #endregion - public override void Save(string tvOutputFile, string csvOutputFile) + #region ZipFiles() + private void ZipFiles() { - throw new NotImplementedException(); + const string entryName = "chmgt_type001/" + FILE_chmgt_db; + using (var zip = new ZipFile(this.FileName)) + { + zip.BeginUpdate(); + zip.Delete(entryName); + zip.Add(this.tempDir + "chmgt.db", entryName); + zip.CommitUpdate(); + } } - + #endregion } } diff --git a/ChanSort.Loader.DbFile/DbSerializerPlugin.cs b/ChanSort.Loader.DbFile/DbSerializerPlugin.cs index 222c588..be92301 100644 --- a/ChanSort.Loader.DbFile/DbSerializerPlugin.cs +++ b/ChanSort.Loader.DbFile/DbSerializerPlugin.cs @@ -4,8 +4,8 @@ namespace ChanSort.Loader.DbFile { public class DbSerializerPlugin : ISerializerPlugin { - public string PluginName { get { return "Toshiba chmgt.db"; } } - public string FileFilter { get { return "chmgt.db"; } } + public string PluginName { get { return "Toshiba *.zip"; } } + public string FileFilter { get { return "*.zip"; } } public SerializerBase CreateSerializer(string inputFile) { diff --git a/ChanSort.Loader.ScmFile/ScmSerializer.cs b/ChanSort.Loader.ScmFile/ScmSerializer.cs index 825f1cf..ab45873 100644 --- a/ChanSort.Loader.ScmFile/ScmSerializer.cs +++ b/ChanSort.Loader.ScmFile/ScmSerializer.cs @@ -498,7 +498,7 @@ namespace ChanSort.Loader.ScmFile #endregion #region Save() - public override void Save(string tvOutputFile, string csvOutputFile) + public override void Save(string tvOutputFile) { if (tvOutputFile != this.FileName) { diff --git a/ChanSort.Loader.TllFile/TllFileSerializer.cs b/ChanSort.Loader.TllFile/TllFileSerializer.cs index 882c2cc..6ef8df6 100644 --- a/ChanSort.Loader.TllFile/TllFileSerializer.cs +++ b/ChanSort.Loader.TllFile/TllFileSerializer.cs @@ -567,7 +567,7 @@ namespace ChanSort.Loader.TllFile #region Save() - public override void Save(string tvOutputFile, string csvOutputFile) + public override void Save(string tvOutputFile) { int newAnalogChannelCount; int newDvbctChannelCount; diff --git a/ChanSort/MainForm.cs b/ChanSort/MainForm.cs index 2157229..2d8b6b3 100644 --- a/ChanSort/MainForm.cs +++ b/ChanSort/MainForm.cs @@ -23,7 +23,7 @@ namespace ChanSort.Ui { public partial class MainForm : XtraForm { - public const string AppVersion = "v2013-04-09"; + public const string AppVersion = "v2013-04-11"; #region enum EditMode private enum EditMode @@ -528,7 +528,7 @@ namespace ChanSort.Ui if (!File.Exists(bakFile)) File.Copy(currentTvFile, bakFile); } - this.currentTvSerializer.Save(this.currentTvFile, this.currentCsvFile); + this.currentTvSerializer.Save(this.currentTvFile); } finally { diff --git a/ChanSort/MainForm.de.resx b/ChanSort/MainForm.de.resx index 9c3af8e..f1f0b0a 100644 --- a/ChanSort/MainForm.de.resx +++ b/ChanSort/MainForm.de.resx @@ -875,7 +875,7 @@ False - ChanSort {0} - Senderlisten Editor für LG und Samsung TV + ChanSort {0} - Senderlisten-Editor für Samsung, LG und Toshiba TVs Kindersicherung diff --git a/ChanSort/MainForm.resx b/ChanSort/MainForm.resx index 89edd26..cb569f1 100644 --- a/ChanSort/MainForm.resx +++ b/ChanSort/MainForm.resx @@ -852,7 +852,7 @@ CenterScreen - ChanSort {0} - Channel List Editor for LG and Samsung TVs + ChanSort {0} - Channel List Editor for Samsung, LG and Toshiba TVs dsChannels diff --git a/readme.txt b/readme.txt index f9abd66..23af8ea 100644 --- a/readme.txt +++ b/readme.txt @@ -1,10 +1,10 @@ -Version v2013-04-10a ======================================================== +Version v2013-04-11 ======================================================== This is a maintenance release based on version v2013-04-05, which brought a refurbished user interface and fixes for various usability issues. New: -- Added support for Toshiba *.db channel lists (read only so far) +- Added support for Toshiba *.zip channel lists (containing chmgt.db list) - Allow Pr #0 for analog channels Fixed: @@ -92,6 +92,11 @@ OTHER DEALINGS IN THE SOFTWARE. Change log ==================================================================== +2013-04-11 +- added support for Toshiba *.zip channel lists (containing chmgt.db list) +- allow Pr #0 for analog channels +- FIX: first channel list only got populated after switching between tabs + 2013-04-08 - Added support for Samsung F-Series. - Added online check for updated program version