298 lines
12 KiB
C#

using DVBServices;
using skyscraper5.Data.PostgreSql;
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;
using skyscraper8.EPGCollectorPort.SkyscraperSide.Freesat;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Npgsql;
using NpgsqlTypes;
namespace skyscraper8.EPGCollectorPort.SkyscraperSide.MediaHighway2
{
internal interface IMhw2Storage
{
void InsertCategories(int networkId, int transportStreamId, MediaHighway2CategorySection categorySection);
void InsertChannels(int networkId, int transportStreamId, MediaHighway2ChannelSection channelSection);
bool TestForEvent(int networkId, int transportStreamId, Mhw2EventBinder binder);
void InsertEvent(int networkId, int transportStreamId, Mhw2EventBinder binder);
}
internal class Mhw2StorageImpl : IMhw2Storage
{
private readonly IMhw2Storage _storageEngine;
public Mhw2StorageImpl(object[] getPluginConnector)
{
object o = getPluginConnector[0];
switch (o)
{
case InMemoryPluginToken t1:
_storageEngine = new Mhw2StorageInMemory();
break;
case PostgresqlToken t2:
_storageEngine = new Mhw2StoragePostgresql(t2);
break;
default:
throw new NotImplementedException(o.GetType().FullName);
}
}
public void InsertCategories(int networkId, int transportStreamId, MediaHighway2CategorySection categorySection)
{
_storageEngine.InsertCategories(networkId, transportStreamId, categorySection);
}
public void InsertChannels(int networkId, int transportStreamId, MediaHighway2ChannelSection channelSection)
{
_storageEngine.InsertChannels(networkId, transportStreamId, channelSection);
}
public bool TestForEvent(int networkId, int transportStreamId, Mhw2EventBinder binder)
{
return _storageEngine.TestForEvent(networkId, transportStreamId, binder);
}
public void InsertEvent(int networkId, int transportStreamId, Mhw2EventBinder binder)
{
_storageEngine.InsertEvent(networkId, transportStreamId, binder);
}
}
internal class Mhw2StorageInMemory : IMhw2Storage
{
private Dictionary<Tuple<int, int>, MediaHighway2CategorySection> _categories;
public void InsertCategories(int networkId, int transportStreamId, MediaHighway2CategorySection categorySection)
{
if (_categories == null)
_categories = new Dictionary<Tuple<int, int>, MediaHighway2CategorySection>();
Tuple<int, int> x = new Tuple<int, int>(networkId, transportStreamId);
if (!_categories.ContainsKey(x))
{
_categories.Add(x, categorySection);
}
}
private Dictionary<Tuple<int, int>, MediaHighway2ChannelSection> _channels;
public void InsertChannels(int networkId, int transportStreamId, MediaHighway2ChannelSection channelSection)
{
if (_channels == null)
_channels = new Dictionary<Tuple<int, int>, MediaHighway2ChannelSection>();
Tuple<int, int> x = new Tuple<int, int>(networkId, transportStreamId);
if (!_categories.ContainsKey(x))
{
_channels.Add(x, channelSection);
}
}
private Dictionary<Tuple<int, int, int, DateTime>, Mhw2EventBinder> _events;
public bool TestForEvent(int networkId, int transportStreamId, Mhw2EventBinder binder)
{
if (_events == null)
return false;
Tuple<int, int, int, DateTime> coordinates = new Tuple<int, int, int, DateTime>(networkId, transportStreamId, binder.EventId, binder.StartTime);
return _events.ContainsKey(coordinates);
}
public void InsertEvent(int networkId, int transportStreamId, Mhw2EventBinder binder)
{
if (_events == null)
_events = new Dictionary<Tuple<int, int, int, DateTime>, Mhw2EventBinder>();
Tuple<int, int, int, DateTime> coordinates = new Tuple<int, int, int, DateTime>(networkId, transportStreamId, binder.EventId, binder.StartTime);
if (!_events.ContainsKey(coordinates))
{
_events.Add(coordinates, binder);
}
}
}
internal class Mhw2StoragePostgresql : IMhw2Storage
{
private readonly PostgresqlToken _postgresqlToken;
public Mhw2StoragePostgresql(PostgresqlToken postgresqlToken)
{
_postgresqlToken = postgresqlToken;
}
private HashSet<Tuple<int, int, int>> _knownCategories;
public void InsertCategories(int networkId, int transportStreamId, MediaHighway2CategorySection categorySection)
{
if (_knownCategories == null)
_knownCategories = new HashSet<Tuple<int, int, int>>();
foreach (MediaHighwayCategoryEntry category in categorySection.Categories)
{
Tuple<int, int, int> coordinate = new Tuple<int, int, int>(networkId, transportStreamId, category.Number);
if (!_knownCategories.Contains(coordinate))
{
_postgresqlToken.EnqueueTask(x => InsertCategory(x,networkId, transportStreamId, category));
_knownCategories.Add(coordinate);
}
}
}
private HashSet<Tuple<int, int, int, int, int>> _knownChannels;
public void InsertChannels(int networkId, int transportStreamId, MediaHighway2ChannelSection channelSection)
{
if (channelSection == null)
return;
if (_knownChannels == null)
_knownChannels = new HashSet<Tuple<int, int, int, int, int>>();
foreach (MediaHighwayChannelInfoEntry channel in channelSection.Channels)
{
Tuple<int, int, int, int, int> coordinate = new Tuple<int, int, int, int, int>(networkId, transportStreamId, channel.OriginalNetworkID, channel.TransportStreamID, channel.ServiceID);
if (!_knownChannels.Contains(coordinate))
{
_postgresqlToken.EnqueueTask(x => InsertChannel(x, networkId, transportStreamId, channel));
_knownChannels.Add(coordinate);
}
}
}
private HashSet<Tuple<int, int, int, DateTime>> _knownEvents;
public bool TestForEvent(int networkId, int transportStreamId, Mhw2EventBinder binder)
{
if (_knownEvents == null)
_knownEvents = new HashSet<Tuple<int, int, int, DateTime>>();
Tuple<int, int, int, DateTime> coordinates = new Tuple<int, int, int, DateTime>(networkId, transportStreamId, binder.EventId, binder.StartTime);
if (_knownEvents.Contains(coordinates))
return true;
NpgsqlConnection connection = _postgresqlToken.GetConnection();
connection.Open();
NpgsqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT dateadded FROM mediahighway2_events WHERE nid = @nid AND tsid = @tsid AND eid = @eid AND start_time = @stime";
command.Parameters.AddWithValue("@nid", NpgsqlDbType.Integer, networkId);
command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, transportStreamId);
command.Parameters.AddWithValue("@eid", NpgsqlDbType.Integer, binder.EventId);
command.Parameters.AddWithValue("@stime", NpgsqlDbType.Timestamp, binder.StartTime);
NpgsqlDataReader dataReader = command.ExecuteReader();
bool result = dataReader.Read();
if (result)
{
_knownEvents.Add(coordinates);
}
dataReader.Close();
command.Dispose();
connection.Close();
return result;
}
public void InsertEvent(int networkId, int transportStreamId, Mhw2EventBinder binder)
{
_postgresqlToken.EnqueueTask(x => InsertEventEx(x, networkId, transportStreamId, binder));
Tuple<int, int, int, DateTime> coordinates = new Tuple<int, int, int, DateTime>(networkId, transportStreamId, binder.EventId, binder.StartTime);
_knownEvents.Add(coordinates);
}
private void InsertEventEx(NpgsqlConnection connection, int networkId, int transportStreamId, Mhw2EventBinder binder)
{
NpgsqlCommand command = connection.CreateCommand();
command.CommandText =
"INSERT INTO mediahighway2_events VALUES (@nid,@tsid,@eid,@stime,DEFAULT,@ename,@category,@channel,@duration,@mcategory,@scategory,@description)";
command.Parameters.AddWithValue("@nid", NpgsqlDbType.Integer, networkId);
command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, transportStreamId);
command.Parameters.AddWithValue("@eid", NpgsqlDbType.Integer, binder.EventId);
command.Parameters.AddWithValue("@stime", NpgsqlDbType.Timestamp, binder.StartTime);
command.Parameters.AddWithValue("@ename", NpgsqlDbType.Text, SanitizeString(binder.EventName));
command.Parameters.AddWithValue("@category", NpgsqlDbType.Integer, binder.CategoryID);
command.Parameters.AddWithValue("@channel", NpgsqlDbType.Integer, binder.ChannelID);
command.Parameters.AddWithValue("@duration", NpgsqlDbType.Integer, Convert.ToInt32(binder.Duration.TotalSeconds));
command.Parameters.AddWithValue("@mcategory", NpgsqlDbType.Integer, binder.MainCategory);
command.Parameters.AddWithValue("@scategory", NpgsqlDbType.Integer, binder.SubCategory);
command.Parameters.AddWithValue("@description", NpgsqlDbType.Text, binder.ShortDescription);
command.ExecuteNonQuery();
}
private string SanitizeString(string ename)
{
if (ename.Contains("\0"))
{
int indexOf = ename.IndexOf("\0");
ename = ename.Substring(0, indexOf);
return ename;
}
return ename;
}
private void InsertChannel(NpgsqlConnection connection, int networkId, int transportStreamId, MediaHighwayChannelInfoEntry channel)
{
if (TestChannel(connection, networkId, transportStreamId, channel))
{
return;
}
NpgsqlCommand command = connection.CreateCommand();
command.CommandText = "INSERT INTO mediahighway2_channels VALUES (@snid,@stsid,@tonid,@ttsid,@tsid,@name,DEFAULT)";
command.Parameters.AddWithValue("@snid", NpgsqlDbType.Integer, networkId);
command.Parameters.AddWithValue("@stsid", NpgsqlDbType.Integer, transportStreamId);
command.Parameters.AddWithValue("@tonid", NpgsqlDbType.Integer, channel.OriginalNetworkID);
command.Parameters.AddWithValue("@ttsid", NpgsqlDbType.Integer, channel.TransportStreamID);
command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, channel.ServiceID);
command.Parameters.AddWithValue("@name", NpgsqlDbType.Text, channel.Name);
command.ExecuteNonQuery();
}
private bool TestChannel(NpgsqlConnection connection, int networkId, int transportStreamId, MediaHighwayChannelInfoEntry channel)
{
NpgsqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT dateadded FROM mediahighway2_channels WHERE src_nid = @snid AND src_tsid = @stsid AND tgt_onid = @tonid AND tgt_tsid = @ttsid AND tgt_sid = @tsid";
command.Parameters.AddWithValue("@snid", NpgsqlDbType.Integer, networkId);
command.Parameters.AddWithValue("@stsid", NpgsqlDbType.Integer, transportStreamId);
command.Parameters.AddWithValue("@tonid", NpgsqlDbType.Integer, channel.OriginalNetworkID);
command.Parameters.AddWithValue("@ttsid", NpgsqlDbType.Integer, channel.TransportStreamID);
command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, channel.ServiceID);
NpgsqlDataReader dataReader = command.ExecuteReader();
bool result = dataReader.Read();
dataReader.Close();
command.Dispose();
return result;
}
private void InsertCategory(NpgsqlConnection connection, int networkId, int transportStreamId, MediaHighwayCategoryEntry category)
{
if (TestCategory(connection, networkId, transportStreamId, category))
{
return;
}
NpgsqlCommand command = connection.CreateCommand();
command.CommandText = "INSERT INTO mediahighway2_categories VALUES (@nid,@tsid,@number,@description,DEFAULT)";
command.Parameters.AddWithValue("@nid", NpgsqlDbType.Integer, networkId);
command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, transportStreamId);
command.Parameters.AddWithValue("@number", NpgsqlDbType.Integer, category.Number);
command.Parameters.AddWithValue("@description", NpgsqlDbType.Text, category.Description);
command.ExecuteNonQuery();
}
private bool TestCategory(NpgsqlConnection connection, int networkId, int transportStreamId, MediaHighwayCategoryEntry category)
{
NpgsqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT dateadded FROM mediahighway2_categories WHERE nid = @nid AND tsid = @tsid AND number = @number";
command.Parameters.AddWithValue("@nid", NpgsqlDbType.Integer, networkId);
command.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, transportStreamId);
command.Parameters.AddWithValue("@number", NpgsqlDbType.Integer, category.Number);
NpgsqlDataReader dataReader = command.ExecuteReader();
bool result = dataReader.Read();
dataReader.Close();
command.Dispose();
return result;
}
}
}