diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 230a797756..66053041cd 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -348,6 +348,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings { info.Genres = details.genres.Where(g => !string.IsNullOrWhiteSpace(g)).ToList(); info.IsNews = details.genres.Contains("news", StringComparer.OrdinalIgnoreCase); + + if (info.Genres.Contains("children", StringComparer.OrdinalIgnoreCase)) + { + info.IsKids = true; + } } return info; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs new file mode 100644 index 0000000000..b3c8bce262 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -0,0 +1,97 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts +{ + public abstract class BaseTunerHost + { + protected readonly IConfigurationManager Config; + protected readonly ILogger Logger; + + private readonly ConcurrentDictionary _channelCache = + new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + + public BaseTunerHost(IConfigurationManager config, ILogger logger) + { + Config = config; + Logger = logger; + } + + protected abstract Task> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken); + public abstract string Type { get; } + + public async Task> GetChannels(TunerHostInfo tuner, bool enableCache, CancellationToken cancellationToken) + { + ChannelCache cache = null; + + if (enableCache && _channelCache.TryGetValue(tuner.Id, out cache)) + { + if ((DateTime.UtcNow - cache.Date) < TimeSpan.FromMinutes(60)) + { + return cache.Channels.ToList(); + } + } + + var result = await GetChannelsInternal(tuner, cancellationToken).ConfigureAwait(false); + + cache = cache ?? new ChannelCache(); + + cache.Date = DateTime.UtcNow; + cache.Channels = result.ToList(); + + _channelCache.AddOrUpdate(tuner.Id, cache, (k, v) => cache); + + return cache.Channels.ToList(); + } + + private List GetTunerHosts() + { + return GetConfiguration().TunerHosts + .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) + .ToList(); + } + + public async Task> GetChannels(CancellationToken cancellationToken) + { + var list = new List(); + + var hosts = GetTunerHosts(); + + foreach (var host in hosts) + { + try + { + var channels = await GetChannels(host, true, cancellationToken).ConfigureAwait(false); + var newChannels = channels.Where(i => !list.Any(l => string.Equals(i.Id, l.Id, StringComparison.OrdinalIgnoreCase))).ToList(); + + list.AddRange(newChannels); + } + catch (Exception ex) + { + Logger.ErrorException("Error getting channel list", ex); + } + } + + return list; + } + + protected LiveTvOptions GetConfiguration() + { + return Config.GetConfiguration("livetv"); + } + + private class ChannelCache + { + public DateTime Date; + public List Channels; + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 7607d5b9db..a07ccd3a48 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -17,19 +17,15 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { - public class HdHomerunHost : ITunerHost + public class HdHomerunHost : BaseTunerHost, ITunerHost { private readonly IHttpClient _httpClient; - private readonly ILogger _logger; private readonly IJsonSerializer _jsonSerializer; - private readonly IConfigurationManager _config; - public HdHomerunHost(IHttpClient httpClient, ILogger logger, IJsonSerializer jsonSerializer, IConfigurationManager config) + public HdHomerunHost(IConfigurationManager config, ILogger logger, IHttpClient httpClient, IJsonSerializer jsonSerializer) : base(config, logger) { _httpClient = httpClient; - _logger = logger; _jsonSerializer = jsonSerializer; - _config = config; } public string Name @@ -37,7 +33,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun get { return "HD Homerun"; } } - public string Type + public override string Type { get { return DeviceType; } } @@ -49,46 +45,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun private const string ChannelIdPrefix = "hdhr_"; - private List GetTunerHosts() - { - return GetConfiguration().TunerHosts - .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) - .ToList(); - } - - public async Task> GetChannels(CancellationToken cancellationToken) - { - var list = new List(); - - var hosts = GetTunerHosts(); - - var ipAddresses = new List(); - - foreach (var host in hosts) - { - var ip = GetApiUrl(host, false); - - if (ipAddresses.Contains(ip, StringComparer.OrdinalIgnoreCase)) - { - continue; - } - - try - { - list.AddRange(await GetChannels(host, cancellationToken).ConfigureAwait(false)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting channel list", ex); - } - - ipAddresses.Add(ip); - } - - return list; - } - - private async Task> GetChannels(TunerHostInfo info, CancellationToken cancellationToken) + protected override async Task> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { var options = new HttpRequestOptions { @@ -198,7 +155,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun } catch (Exception ex) { - _logger.ErrorException("Error getting tuner info", ex); + Logger.ErrorException("Error getting tuner info", ex); } } @@ -263,11 +220,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun public bool DRM { get; set; } } - private LiveTvOptions GetConfiguration() - { - return _config.GetConfiguration("livetv"); - } - private MediaSourceInfo GetMediaSource(TunerHostInfo info, string channelId, string profile) { int? width = null; @@ -425,7 +377,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun public async Task Validate(TunerHostInfo info) { - await GetChannels(info, CancellationToken.None).ConfigureAwait(false); + await GetChannels(info, false, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index ec05cefd5c..0dc170cfdd 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -15,9 +15,13 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts { - public class M3UTunerHost : ITunerHost + public class M3UTunerHost : BaseTunerHost, ITunerHost { - public string Type + public M3UTunerHost(IConfigurationManager config, ILogger logger) : base(config, logger) + { + } + + public override string Type { get { return "m3u"; } } @@ -27,47 +31,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts get { return "M3U Tuner"; } } - private readonly IConfigurationManager _config; - private readonly ILogger _logger; - - public M3UTunerHost(IConfigurationManager config, ILogger logger) - { - _config = config; - _logger = logger; - } - - private List GetTunerHosts() - { - return GetConfiguration().TunerHosts - .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) - .ToList(); - } - - public async Task> GetChannels(CancellationToken cancellationToken) - { - var list = new List(); - - var urls = GetTunerHosts().Select(i => i.Url) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Distinct(StringComparer.OrdinalIgnoreCase); - - foreach (var url in urls) - { - try - { - list.AddRange(await GetChannels(url, cancellationToken).ConfigureAwait(false)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting channel list", ex); - } - } - - return list; - } - - private Task> GetChannels(string url, CancellationToken cancellationToken) + protected override async Task> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { + var url = info.Url; var urlHash = url.GetMD5().ToString("N"); int position = 0; @@ -135,7 +101,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts } } file.Close(); - return Task.FromResult((IEnumerable)channels); + return channels; } public Task> GetTunerInfos(CancellationToken cancellationToken) @@ -155,11 +121,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return Task.FromResult(list); } - private LiveTvOptions GetConfiguration() - { - return _config.GetConfiguration("livetv"); - } - public async Task GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) { var urlHash = info.Url.GetMD5().ToString("N"); @@ -170,7 +131,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts channelId = channelId.Substring(urlHash.Length); - var channels = await GetChannels(info.Url, cancellationToken).ConfigureAwait(false); + var channels = await GetChannels(info, true, cancellationToken).ConfigureAwait(false); var m3uchannels = channels.Cast(); var channel = m3uchannels.FirstOrDefault(c => c.Id == channelId); if (channel != null) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 2571f9b2cb..824f3e856c 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -231,6 +231,7 @@ +