- added Italian translation

- updated Polish translation
- added support for a Hisense HIS_SVL variant with different file structure
- Samsung IP-TV lists allow editing stream and logo URLs
This commit is contained in:
Horst Beham
2023-08-14 10:46:10 +02:00
parent e561f71441
commit 3ed2e28ac0
52 changed files with 3337 additions and 513 deletions

View File

@@ -26,6 +26,7 @@
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.IO.Compression" />
</ItemGroup>
<ItemGroup>
@@ -38,6 +39,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Buffers" Version="4.5.1" />
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />

View File

@@ -1,11 +1,18 @@
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using ChanSort.Api;
namespace ChanSort.Loader.Samsung.Zip
{
internal class DbChannel : ChannelInfo
{
private dynamic jsonMeta;
private Encoding encoding;
public bool JsonModified { get; private set; }
#region ctor()
internal DbChannel(IDataReader r, IDictionary<string, int> field, DbSerializer loader, Dictionary<long, string> providers, Satellite sat, Transponder tp)
{
@@ -40,9 +47,10 @@ namespace ChanSort.Loader.Samsung.Zip
if ((this.SignalSource & SignalSource.Dvb) != 0)
this.ReadDvbData(r, field, loader, providers);
else
else if ((this.SignalSource & SignalSource.Analog) != 0)
this.ReadAnalogData(r, field);
if (field.ContainsKey("jsonMeta"))
this.ReadIpData(r, field, loader);
base.IsDeleted = this.OldProgramNr == -1;
}
@@ -72,5 +80,62 @@ namespace ChanSort.Loader.Samsung.Zip
this.AddDebug(r.GetInt32(field["lcn"]).ToString());
}
#endregion
#region ReadIpData()
private void ReadIpData(IDataReader r, IDictionary<string, int> field, DbSerializer loader)
{
var json = loader.ReadUtf16(r, field["jsonMeta"]);
if (json != null)
{
var s = JsonSerializer.Create();
dynamic obj = s.Deserialize(new JsonTextReader(new StringReader(json)));
this.encoding = loader.DefaultEncoding;
this.jsonMeta = obj;
this.JsonDefaultUrl = obj?.default_url;
this.JsonLogoUrl = obj?.logo_url;
}
}
#endregion
#region JsonDefaultUrl
public string JsonDefaultUrl
{
get => jsonMeta?.default_url;
set
{
if (jsonMeta == null || value == (string)jsonMeta.default_url.Value)
return;
jsonMeta.default_url = value;
JsonModified = true;
}
}
#endregion
#region JsonLogoUrl
public string JsonLogoUrl
{
get => jsonMeta?.logo_url;
set
{
if (jsonMeta == null || value == (string)jsonMeta.logo_url.Value)
return;
jsonMeta.logo_url = value;
JsonModified = true;
}
}
#endregion
#region GetRawJson()
public byte[] GetRawJson()
{
var s = JsonSerializer.Create();
using var w = new StringWriter();
s.Serialize(new JsonTextWriter(w), this.jsonMeta);
w.Flush();
var rawJson = Encoding.BigEndianUnicode.GetBytes(w.ToString());
return rawJson;
}
#endregion
}
}

View File

@@ -261,6 +261,8 @@ namespace ChanSort.Loader.Samsung.Zip
};
if (fileType == FileType.ChannelDbDvb)
fieldNames.AddRange(new[] {"onid", "tsid", "vidPid", "provId", "cast(shrtSrvName as blob) shrtSrvName", "lcn"}); // SRV_DVB
if (fileType == FileType.ChannelDbIp)
fieldNames.AddRange(new [] {"cast(jsonMeta as blob) jsonMeta"});
var sql = this.BuildQuery(table, fieldNames);
var fields = this.GetFieldMap(fieldNames);
@@ -303,7 +305,7 @@ namespace ChanSort.Loader.Samsung.Zip
{
list.VisibleColumnFieldNames = new List<string>
{
"OldPosition", "Position", "PrNr", "Name", "Favorites", "SymbolRate"
"OldPosition", "Position", "PrNr", "Name", "Favorites", "SymbolRate", "+JsonDefaultUrl", "+JsonLogoUrl"
};
}
return list;
@@ -542,8 +544,9 @@ namespace ChanSort.Loader.Samsung.Zip
using var cmdInsertFav = PrepareInsertFavCommand(conn);
using var cmdUpdateFav = PrepareUpdateFavCommand(conn);
using var cmdDeleteFav = PrepareDeleteFavCommand(conn);
using var cmdUpdateIp = (channelList.SignalSource & SignalSource.Ip) != 0 ? PrepareUpdateIpCommand(conn) : null;
Editor.SequentializeFavPos(channelList, 5);
this.WriteChannels(cmdUpdateSrv, cmdDeleteSrv, cmdInsertFav, cmdUpdateFav, cmdDeleteFav, channelList);
this.WriteChannels(cmdUpdateSrv, cmdDeleteSrv, cmdInsertFav, cmdUpdateFav, cmdDeleteFav, cmdUpdateIp, channelList);
trans.Commit();
}
@@ -573,6 +576,16 @@ namespace ChanSort.Loader.Samsung.Zip
return cmd;
}
private SqliteCommand PrepareUpdateIpCommand(SqliteConnection conn)
{
var cmd = conn.CreateCommand();
cmd.CommandText = "update SRV_IP set jsonMeta=@jsonMeta where srvId=@id";
cmd.Parameters.Add("@id", SqliteType.Integer);
cmd.Parameters.Add("@jsonMeta", SqliteType.Blob);
cmd.Prepare();
return cmd;
}
private SqliteCommand PrepareDeleteCommand(SqliteConnection conn, bool digital)
{
var cmd = conn.CreateCommand();
@@ -623,7 +636,7 @@ namespace ChanSort.Loader.Samsung.Zip
#endregion
#region WriteChannels()
private void WriteChannels(SqliteCommand cmdUpdateSrv, SqliteCommand cmdDeleteSrv, SqliteCommand cmdInsertFav, SqliteCommand cmdUpdateFav, SqliteCommand cmdDeleteFav,
private void WriteChannels(SqliteCommand cmdUpdateSrv, SqliteCommand cmdDeleteSrv, SqliteCommand cmdInsertFav, SqliteCommand cmdUpdateFav, SqliteCommand cmdDeleteFav, SqliteCommand cmdUpdateIp,
ChannelList channelList, bool analog = false)
{
bool canUpdateNames = this.Features.ChannelNameEdit != ChannelNameEditMode.None;
@@ -652,6 +665,13 @@ namespace ChanSort.Loader.Samsung.Zip
cmdUpdateSrv.Parameters["@srvname"].Value = channel.Name == null ? (object)DBNull.Value : encoding.GetString(Encoding.Unicode.GetBytes(channel.Name)); // convert string => UTF16LE => string with flipped byte order (looking "Chinese")
cmdUpdateSrv.ExecuteNonQuery();
if (cmdUpdateIp != null && channel.JsonModified)
{
cmdUpdateIp.Parameters["@id"].Value = channel.RecordIndex;
cmdUpdateIp.Parameters["@jsonMeta"].Value = channel.GetRawJson();
cmdUpdateIp.ExecuteNonQuery();
}
// update favorites
for (int i=0, mask=1; i<5; i++, mask <<= 1)
{