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, MediaHighway2CategorySection> _categories; public void InsertCategories(int networkId, int transportStreamId, MediaHighway2CategorySection categorySection) { if (_categories == null) _categories = new Dictionary, MediaHighway2CategorySection>(); Tuple x = new Tuple(networkId, transportStreamId); if (!_categories.ContainsKey(x)) { _categories.Add(x, categorySection); } } private Dictionary, MediaHighway2ChannelSection> _channels; public void InsertChannels(int networkId, int transportStreamId, MediaHighway2ChannelSection channelSection) { if (_channels == null) _channels = new Dictionary, MediaHighway2ChannelSection>(); Tuple x = new Tuple(networkId, transportStreamId); if (!_categories.ContainsKey(x)) { _channels.Add(x, channelSection); } } private Dictionary, Mhw2EventBinder> _events; public bool TestForEvent(int networkId, int transportStreamId, Mhw2EventBinder binder) { if (_events == null) return false; Tuple coordinates = new Tuple(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, Mhw2EventBinder>(); Tuple coordinates = new Tuple(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> _knownCategories; public void InsertCategories(int networkId, int transportStreamId, MediaHighway2CategorySection categorySection) { if (_knownCategories == null) _knownCategories = new HashSet>(); foreach (MediaHighwayCategoryEntry category in categorySection.Categories) { Tuple coordinate = new Tuple(networkId, transportStreamId, category.Number); if (!_knownCategories.Contains(coordinate)) { _postgresqlToken.EnqueueTask(x => InsertCategory(x,networkId, transportStreamId, category)); _knownCategories.Add(coordinate); } } } private HashSet> _knownChannels; public void InsertChannels(int networkId, int transportStreamId, MediaHighway2ChannelSection channelSection) { if (channelSection == null) return; if (_knownChannels == null) _knownChannels = new HashSet>(); foreach (MediaHighwayChannelInfoEntry channel in channelSection.Channels) { Tuple coordinate = new Tuple(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> _knownEvents; public bool TestForEvent(int networkId, int transportStreamId, Mhw2EventBinder binder) { if (_knownEvents == null) _knownEvents = new HashSet>(); Tuple coordinates = new Tuple(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 coordinates = new Tuple(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; } } }