diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index f3fd8f42a..24c91e172 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -182,6 +182,24 @@ namespace MediaBrowser.Api.LiveTv
[ApiMember(Name = "MaxEndDate", Description = "Optional. The maximum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
public string MaxEndDate { get; set; }
+
+ [ApiMember(Name = "IsMovie", Description = "Optional filter for movies.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET,POST")]
+ public bool? IsMovie { get; set; }
+
+ [ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+ public int? StartIndex { get; set; }
+
+ [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+ public int? Limit { get; set; }
+
+ [ApiMember(Name = "SortBy", Description = "Optional. Specify one or more sort orders, comma delimeted. Options: Name, StartDate", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
+ public string SortBy { get; set; }
+
+ [ApiMember(Name = "SortOrder", Description = "Sort Order - Ascending,Descending", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public SortOrder? SortOrder { get; set; }
+
+ [ApiMember(Name = "Genres", Description = "The genres to return guide information for.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
+ public string Genres { get; set; }
}
[Route("/LiveTv/Programs/Recommended", "GET", Summary = "Gets available live tv epgs..")]
@@ -199,6 +217,9 @@ namespace MediaBrowser.Api.LiveTv
[ApiMember(Name = "HasAired", Description = "Optional. Filter by programs that have completed airing, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? HasAired { get; set; }
+
+ [ApiMember(Name = "IsMovie", Description = "Optional filter for movies.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
+ public bool? IsMovie { get; set; }
}
[Route("/LiveTv/Programs/{Id}", "GET", Summary = "Gets a live tv program")]
@@ -371,7 +392,7 @@ namespace MediaBrowser.Api.LiveTv
{
var query = new ProgramQuery
{
- ChannelIdList = (request.ChannelIds ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(),
+ ChannelIds = (request.ChannelIds ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(),
UserId = request.UserId,
HasAired = request.HasAired
};
@@ -396,6 +417,13 @@ namespace MediaBrowser.Api.LiveTv
query.MaxEndDate = DateTime.Parse(request.MaxEndDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime();
}
+ query.StartIndex = request.StartIndex;
+ query.Limit = request.Limit;
+ query.SortBy = (request.SortBy ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ query.SortOrder = request.SortOrder;
+ query.IsMovie = request.IsMovie;
+ query.Genres = (request.Genres ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+
var result = await _liveTvManager.GetPrograms(query, CancellationToken.None).ConfigureAwait(false);
return ToOptimizedSerializedResultUsingCache(result);
@@ -408,7 +436,8 @@ namespace MediaBrowser.Api.LiveTv
UserId = request.UserId,
IsAiring = request.IsAiring,
Limit = request.Limit,
- HasAired = request.HasAired
+ HasAired = request.HasAired,
+ IsMovie = request.IsMovie
};
var result = await _liveTvManager.GetRecommendedPrograms(query, CancellationToken.None).ConfigureAwait(false);
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index c8f618a03..dd6189bc5 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -239,6 +239,11 @@ namespace MediaBrowser.Controller.Entities
get { return this.GetImagePath(ImageType.Primary); }
}
+ public virtual bool IsInternetMetadataEnabled()
+ {
+ return ConfigurationManager.Configuration.EnableInternetProviders;
+ }
+
public virtual bool CanDelete()
{
var locationType = LocationType;
diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs
index 5aafc8eb3..00a42271b 100644
--- a/MediaBrowser.Controller/Entities/IHasImages.cs
+++ b/MediaBrowser.Controller/Entities/IHasImages.cs
@@ -184,6 +184,12 @@ namespace MediaBrowser.Controller.Entities
///
/// true if [always scan internal metadata path]; otherwise, false.
bool AlwaysScanInternalMetadataPath { get; }
+
+ ///
+ /// Determines whether [is internet metadata enabled].
+ ///
+ /// true if [is internet metadata enabled]; otherwise, false.
+ bool IsInternetMetadataEnabled();
}
public static class HasImagesExtensions
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
index 2f9673db2..0b07d8b6d 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Users;
@@ -11,7 +12,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Controller.LiveTv
{
- public class LiveTvProgram : BaseItem, ILiveTvItem
+ public class LiveTvProgram : BaseItem, ILiveTvItem, IHasLookupInfo
{
///
/// Gets the user data key.
@@ -220,5 +221,23 @@ namespace MediaBrowser.Controller.LiveTv
{
return false;
}
+
+ public override bool IsInternetMetadataEnabled()
+ {
+ if (IsMovie)
+ {
+ var options = (LiveTvOptions)ConfigurationManager.GetConfiguration("livetv");
+ return options.EnableMovieProviders;
+ }
+
+ return false;
+ }
+
+ public LiveTvProgramLookupInfo GetLookupInfo()
+ {
+ var info = GetItemLookupInfo();
+ info.IsMovie = IsMovie;
+ return info;
+ }
}
}
diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
index 4d7e5ee63..36f082b02 100644
--- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs
@@ -145,6 +145,12 @@ namespace MediaBrowser.Controller.LiveTv
/// true if this instance is premiere; otherwise, false.
public bool IsPremiere { get; set; }
+ ///
+ /// Gets or sets the production year.
+ ///
+ /// The production year.
+ public int? ProductionYear { get; set; }
+
public ProgramInfo()
{
Genres = new List();
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 678d7841c..06f18729b 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -293,6 +293,7 @@
+
diff --git a/MediaBrowser.Controller/Providers/LiveTvProgramLookupInfo.cs b/MediaBrowser.Controller/Providers/LiveTvProgramLookupInfo.cs
new file mode 100644
index 000000000..4e2c11c22
--- /dev/null
+++ b/MediaBrowser.Controller/Providers/LiveTvProgramLookupInfo.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace MediaBrowser.Controller.Providers
+{
+ public class LiveTvProgramLookupInfo : ItemLookupInfo
+ {
+ public Boolean IsMovie { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
index 32a9c8d12..0cd5eda0c 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
@@ -3,5 +3,6 @@
public class LiveTvOptions
{
public int? GuideDays { get; set; }
+ public bool EnableMovieProviders { get; set; }
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Model/LiveTv/ProgramQuery.cs b/MediaBrowser.Model/LiveTv/ProgramQuery.cs
index 2d15a4c4b..bbd396c33 100644
--- a/MediaBrowser.Model/LiveTv/ProgramQuery.cs
+++ b/MediaBrowser.Model/LiveTv/ProgramQuery.cs
@@ -1,4 +1,5 @@
-using System;
+using MediaBrowser.Model.Entities;
+using System;
namespace MediaBrowser.Model.LiveTv
{
@@ -7,11 +8,18 @@ namespace MediaBrowser.Model.LiveTv
///
public class ProgramQuery
{
+ public ProgramQuery()
+ {
+ ChannelIds = new string[] { };
+ SortBy = new string[] { };
+ Genres = new string[] { };
+ }
+
///
- /// Gets or sets the channel identifier.
+ /// Gets or sets the channel ids.
///
- /// The channel identifier.
- public string[] ChannelIdList { get; set; }
+ /// The channel ids.
+ public string[] ChannelIds { get; set; }
///
/// Gets or sets the user identifier.
@@ -19,19 +27,64 @@ namespace MediaBrowser.Model.LiveTv
/// The user identifier.
public string UserId { get; set; }
+ ///
+ /// The earliest date for which a program starts to return
+ ///
public DateTime? MinStartDate { get; set; }
+ ///
+ /// The latest date for which a program starts to return
+ ///
public DateTime? MaxStartDate { get; set; }
+ ///
+ /// The earliest date for which a program ends to return
+ ///
public DateTime? MinEndDate { get; set; }
+ ///
+ /// The latest date for which a program ends to return
+ ///
public DateTime? MaxEndDate { get; set; }
+ ///
+ /// Used to specific whether to return movies or not
+ ///
+ /// If set to null, all programs will be returned
+ public bool? IsMovie { get; set; }
+
+ ///
+ /// Skips over a given number of items within the results. Use for paging.
+ ///
+ public int? StartIndex { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this instance has aired.
+ ///
+ /// null if [has aired] contains no value, true if [has aired]; otherwise, false.
public bool? HasAired { get; set; }
- public ProgramQuery()
- {
- ChannelIdList = new string[] { };
- }
+ ///
+ /// The maximum number of items to return
+ ///
+ public int? Limit { get; set; }
+
+ ///
+ /// What to sort the results by
+ ///
+ /// The sort by.
+ public string[] SortBy { get; set; }
+
+ ///
+ /// The sort order to return results with
+ ///
+ /// The sort order.
+ public SortOrder? SortOrder { get; set; }
+
+ ///
+ /// Limit results to items containing specific genres
+ ///
+ /// The genres.
+ public string[] Genres { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs
index 907902123..9ba8e0e5f 100644
--- a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs
+++ b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs
@@ -25,5 +25,11 @@
///
/// The limit.
public int? Limit { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this instance is movie.
+ ///
+ /// null if [is movie] contains no value, true if [is movie]; otherwise, false.
+ public bool? IsMovie { get; set; }
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs b/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs
index 5a7ae7594..f17389615 100644
--- a/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs
+++ b/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs
@@ -7,14 +7,16 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
namespace MediaBrowser.Providers.LiveTv
{
- public class ProgramMetadataService : MetadataService
+ public class ProgramMetadataService : MetadataService
{
- public ProgramMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager)
+ public ProgramMetadataService(
+ IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager,
+ IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager)
+ : base(
+ serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager)
{
}
@@ -25,6 +27,7 @@ namespace MediaBrowser.Providers.LiveTv
/// The target.
/// The locked fields.
/// if set to true [replace data].
+ ///
protected override void MergeData(LiveTvProgram source, LiveTvProgram target, List lockedFields, bool replaceData, bool mergeMetadataSettings)
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index 0c1372e41..c9ae47ad0 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -312,7 +312,7 @@ namespace MediaBrowser.Providers.Manager
if (provider is IRemoteMetadataProvider)
{
- if (!ConfigurationManager.Configuration.EnableInternetProviders)
+ if (!item.IsInternetMetadataEnabled())
{
return false;
}
@@ -360,7 +360,7 @@ namespace MediaBrowser.Providers.Manager
if (provider is IRemoteImageProvider)
{
- if (!ConfigurationManager.Configuration.EnableInternetProviders)
+ if (!item.IsInternetMetadataEnabled())
{
return false;
}
@@ -515,7 +515,7 @@ namespace MediaBrowser.Providers.Manager
Type = MetadataPluginType.LocalMetadataProvider
}));
- if (ConfigurationManager.Configuration.EnableInternetProviders)
+ if (item.IsInternetMetadataEnabled())
{
// Fetchers
list.AddRange(providers.Where(i => (i is IRemoteMetadataProvider)).Select(i => new MetadataPlugin
@@ -547,7 +547,7 @@ namespace MediaBrowser.Providers.Manager
Type = MetadataPluginType.LocalImageProvider
}));
- var enableInternet = ConfigurationManager.Configuration.EnableInternetProviders;
+ var enableInternet = item.IsInternetMetadataEnabled();
// Fetchers
list.AddRange(imageProviders.Where(i => i is IDynamicImageProvider || (enableInternet && i is IRemoteImageProvider)).Select(i => new MetadataPlugin
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 2df8f8e3c..3b5103f20 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -108,6 +108,7 @@
+
diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
index 68cbf85e9..c23ed3786 100644
--- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
+++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
@@ -17,7 +17,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Movies
{
public class GenericMovieDbInfo
- where T : Video, new()
+ where T : BaseItem, new()
{
private readonly ILogger _logger;
private readonly IJsonSerializer _jsonSerializer;
diff --git a/MediaBrowser.Providers/Movies/LiveTvMovieDbProvider.cs b/MediaBrowser.Providers/Movies/LiveTvMovieDbProvider.cs
new file mode 100644
index 000000000..326450ad4
--- /dev/null
+++ b/MediaBrowser.Providers/Movies/LiveTvMovieDbProvider.cs
@@ -0,0 +1,43 @@
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Providers;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.Movies
+{
+ public class LiveTvMovieDbProvider : IRemoteMetadataProvider, IDisposable, IHasOrder
+ {
+ public Task> GetSearchResults(LiveTvProgramLookupInfo searchInfo, CancellationToken cancellationToken)
+ {
+ return MovieDbProvider.Current.GetMovieSearchResults(searchInfo, cancellationToken);
+ }
+
+ public Task> GetMetadata(LiveTvProgramLookupInfo info, CancellationToken cancellationToken)
+ {
+ return MovieDbProvider.Current.GetItemMetadata(info, cancellationToken);
+ }
+
+ public string Name
+ {
+ get { return "LiveTvMovieDbProvider"; }
+ }
+
+ public Task GetImageResponse(string url, CancellationToken cancellationToken)
+ {
+ return MovieDbProvider.Current.GetImageResponse(url, cancellationToken);
+ }
+
+ public void Dispose()
+ {
+ }
+
+ public int Order
+ {
+ get { return 1; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
index f5d5a6fb1..19b4939dd 100644
--- a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Dto;
@@ -47,6 +48,13 @@ namespace MediaBrowser.Providers.Movies
return true;
}
+ // Supports images for tv movies
+ var tvProgram = item as LiveTvProgram;
+ if (tvProgram != null && tvProgram.IsMovie)
+ {
+ return true;
+ }
+
// Don't support local trailers
return item is Movie || item is MusicVideo;
}
diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs
index b8f9a7fa2..48b7140f8 100644
--- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs
@@ -113,7 +113,7 @@ namespace MediaBrowser.Providers.Movies
}
public Task> GetItemMetadata(ItemLookupInfo id, CancellationToken cancellationToken)
- where T : Video, new()
+ where T : BaseItem, new()
{
var movieDb = new GenericMovieDbInfo(_logger, _jsonSerializer, _libraryManager);
diff --git a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs
index 758d0a6bd..7f804f9df 100644
--- a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs
+++ b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Entities;
@@ -108,6 +109,13 @@ namespace MediaBrowser.Providers.Omdb
}
}
+ // Supports images for tv movies
+ var tvProgram = item as LiveTvProgram;
+ if (tvProgram != null && tvProgram.IsMovie)
+ {
+ return true;
+ }
+
return item is Movie;
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 33f1a4dac..acff25e96 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -45,6 +45,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private readonly ILibraryManager _libraryManager;
private readonly ITaskManager _taskManager;
private readonly IJsonSerializer _jsonSerializer;
+ private readonly IProviderManager _providerManager;
private readonly IDtoService _dtoService;
private readonly ILocalizationManager _localization;
@@ -62,7 +63,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private readonly SemaphoreSlim _refreshSemaphore = new SemaphoreSlim(1, 1);
- public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer)
+ public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager)
{
_config = config;
_fileSystem = fileSystem;
@@ -73,6 +74,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
_taskManager = taskManager;
_localization = localization;
_jsonSerializer = jsonSerializer;
+ _providerManager = providerManager;
_dtoService = dtoService;
_userDataManager = userDataManager;
@@ -237,7 +239,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
foreach (var channel in internalResult.Items)
{
- var currentProgram = await GetCurrentProgram(channel.ExternalId, cancellationToken).ConfigureAwait(false);
+ var currentProgram = GetCurrentProgram(channel.ExternalId);
returnList.Add(_tvDtoService.GetChannelInfoDto(channel, currentProgram, user));
}
@@ -261,7 +263,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return _libraryManager.GetItemById(id) as LiveTvChannel;
}
- public async Task GetInternalProgram(string id, CancellationToken cancellationToken)
+ private LiveTvProgram GetInternalProgram(string id)
{
var guid = new Guid(id);
@@ -271,37 +273,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (obj != null)
{
- await RefreshIfNeeded(obj, cancellationToken).ConfigureAwait(false);
+ RefreshIfNeeded(obj);
}
return obj;
}
- private Task RefreshIfNeeded(IEnumerable programs, CancellationToken cancellationToken)
- {
- var list = programs.ToList();
-
- Task.Run(async () =>
- {
- foreach (var program in list)
- {
- await RefreshIfNeeded(program, CancellationToken.None).ConfigureAwait(false);
- }
-
- }, cancellationToken);
-
- return Task.FromResult(true);
- }
-
- private readonly Task _cachedTask = Task.FromResult(true);
- private Task RefreshIfNeeded(LiveTvProgram program, CancellationToken cancellationToken)
+ private void RefreshIfNeeded(LiveTvProgram program)
{
if (!_refreshedPrograms.ContainsKey(program.Id))
{
_refreshedPrograms.TryAdd(program.Id, true);
- return program.RefreshMetadata(cancellationToken);
+ _providerManager.QueueRefresh(program.Id, new MetadataRefreshOptions());
}
+ }
- return _cachedTask;
+ private void RefreshIfNeeded(IEnumerable programs)
+ {
+ foreach (var program in programs)
+ {
+ RefreshIfNeeded(program);
+ }
}
public async Task GetInternalRecording(string id, CancellationToken cancellationToken)
@@ -528,6 +519,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
item.ProviderImageUrl = info.ImageUrl;
item.RunTimeTicks = (info.EndDate - info.StartDate).Ticks;
item.StartDate = info.StartDate;
+ item.ProductionYear = info.ProductionYear;
return item;
}
@@ -607,7 +599,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public async Task GetProgram(string id, CancellationToken cancellationToken, User user = null)
{
- var program = await GetInternalProgram(id, cancellationToken).ConfigureAwait(false);
+ var program = GetInternalProgram(id);
var channel = GetChannel(program);
@@ -656,9 +648,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
programs = programs.Where(i => i.HasAired == val);
}
- if (query.ChannelIdList.Length > 0)
+ if (query.ChannelIds.Length > 0)
{
- var guids = query.ChannelIdList.Select(i => new Guid(i)).ToList();
+ var guids = query.ChannelIds.Select(i => new Guid(i)).ToList();
programs = programs.Where(i =>
{
@@ -672,7 +664,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
-
if (user != null)
{
// Avoid implicitly captured closure
@@ -680,6 +671,30 @@ namespace MediaBrowser.Server.Implementations.LiveTv
programs = programs.Where(i => i.IsVisible(currentUser));
}
+ // Apply genre filter
+ if (query.Genres.Length > 0)
+ {
+ programs = programs.Where(p => p.Genres.Any(g => query.Genres.Contains(g, StringComparer.OrdinalIgnoreCase)));
+ }
+
+ if (query.IsMovie.HasValue)
+ {
+ programs = programs.Where(p => p.IsMovie == query.IsMovie);
+ }
+
+ programs = _libraryManager.Sort(programs, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending)
+ .Cast();
+
+ if (query.StartIndex.HasValue)
+ {
+ programs = programs.Skip(query.StartIndex.Value);
+ }
+
+ if (query.Limit.HasValue)
+ {
+ programs = programs.Take(query.Limit.Value);
+ }
+
var programList = programs.ToList();
var returnArray = programList
@@ -691,7 +706,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
})
.ToArray();
- await RefreshIfNeeded(programList, cancellationToken).ConfigureAwait(false);
+ RefreshIfNeeded(programList);
await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
@@ -726,6 +741,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
programs = programs.Where(i => i.HasAired == val);
}
+ if (query.IsMovie.HasValue)
+ {
+ programs = programs.Where(p => p.IsMovie == query.IsMovie.Value);
+ }
+
var serviceName = ActiveService.Name;
var programList = programs.ToList();
@@ -747,7 +767,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
programList = programs.ToList();
- await RefreshIfNeeded(programList, cancellationToken).ConfigureAwait(false);
+ RefreshIfNeeded(programList);
var returnArray = programList.ToArray();
@@ -1233,7 +1253,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
var program = string.IsNullOrEmpty(i.ProgramId) ?
null :
- await GetInternalProgram(_tvDtoService.GetInternalProgramId(service.Name, i.ProgramId).ToString("N"), cancellationToken).ConfigureAwait(false);
+ GetInternalProgram(_tvDtoService.GetInternalProgramId(service.Name, i.ProgramId).ToString("N"));
var channel = string.IsNullOrEmpty(i.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, i.ChannelId));
@@ -1366,14 +1386,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
var channel = GetInternalChannel(id);
- var currentProgram = await GetCurrentProgram(channel.ExternalId, cancellationToken).ConfigureAwait(false);
+ var currentProgram = GetCurrentProgram(channel.ExternalId);
var dto = _tvDtoService.GetChannelInfoDto(channel, currentProgram, user);
return dto;
}
- private async Task GetCurrentProgram(string externalChannelId, CancellationToken cancellationToken)
+ private LiveTvProgram GetCurrentProgram(string externalChannelId)
{
var now = DateTime.UtcNow;
@@ -1385,7 +1405,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (program != null)
{
- await RefreshIfNeeded(program, cancellationToken).ConfigureAwait(false);
+ RefreshIfNeeded(program);
}
return program;
@@ -1444,7 +1464,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public async Task GetNewTimerDefaults(string programId, CancellationToken cancellationToken)
{
- var program = await GetInternalProgram(programId, cancellationToken).ConfigureAwait(false);
+ var program = GetInternalProgram(programId);
var programDto = await GetProgram(programId, cancellationToken).ConfigureAwait(false);
var defaults = await GetNewTimerDefaultsInternal(cancellationToken, program).ConfigureAwait(false);
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index 0805c9ce9..e5b1e5a8b 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -1389,5 +1389,7 @@
"LabelTagFilterMode": "Mode:",
"LabelTagFilterAllowModeHelp": "If allowed tags are used as part of a deeply nested folder structure, content that is tagged will require parent folders to be tagged as well.",
"HeaderThisUserIsCurrentlyDisabled": "This user is currently disabled",
- "MessageReenableUser": "See below to reenable"
+ "MessageReenableUser": "See below to reenable",
+ "LabelEnableInternetMetadataForTvPrograms": "Download internet metadata for:",
+ "OptionTVMovies": "TV Movies"
}
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index a7de0fa34..e80f94e15 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -495,7 +495,7 @@ namespace MediaBrowser.Server.Startup.Common
PlaylistManager = new PlaylistManager(LibraryManager, FileSystemManager, LibraryMonitor, LogManager.GetLogger("PlaylistManager"), UserManager);
RegisterSingleInstance(PlaylistManager);
- LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer);
+ LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, ProviderManager);
RegisterSingleInstance(LiveTvManager);
UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, PlaylistManager, CollectionManager, ServerConfigurationManager);