diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 4fd8fbfd19..5234dda187 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Drawing; @@ -67,6 +68,19 @@ namespace MediaBrowser.Api.Images public string Id { get; set; } } + [Route("/LiveTV/Channels/{Id}/Images/{Type}", "GET")] + [Route("/LiveTV/Channels/{Id}/Images/{Type}/{Index}", "GET")] + [Api(Description = "Gets an item image")] + public class GetChannelImage : ImageRequest + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Channel Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + /// /// Class UpdateItemImageIndex /// @@ -341,10 +355,12 @@ namespace MediaBrowser.Api.Images private readonly IDtoService _dtoService; private readonly IImageProcessor _imageProcessor; + private readonly ILiveTvManager _liveTv; + /// /// Initializes a new instance of the class. /// - public ImageService(IUserManager userManager, ILibraryManager libraryManager, IApplicationPaths appPaths, IProviderManager providerManager, IItemRepository itemRepo, IDtoService dtoService, IImageProcessor imageProcessor) + public ImageService(IUserManager userManager, ILibraryManager libraryManager, IApplicationPaths appPaths, IProviderManager providerManager, IItemRepository itemRepo, IDtoService dtoService, IImageProcessor imageProcessor, ILiveTvManager liveTv) { _userManager = userManager; _libraryManager = libraryManager; @@ -353,6 +369,7 @@ namespace MediaBrowser.Api.Images _itemRepo = itemRepo; _dtoService = dtoService; _imageProcessor = imageProcessor; + _liveTv = liveTv; } /// @@ -492,6 +509,13 @@ namespace MediaBrowser.Api.Images } } + public object Get(GetChannelImage request) + { + var item = _liveTv.GetChannel(request.Id); + + return GetImage(request, item); + } + /// /// Gets the specified request. /// diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index d2574063b4..68cfc9c444 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -30,6 +30,18 @@ namespace MediaBrowser.Api.LiveTv public string UserId { get; set; } } + [Route("/LiveTv/Channels/{Id}", "GET")] + [Api(Description = "Gets a live tv channel")] + public class GetChannel : IReturn + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Channel Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + [Route("/LiveTv/Recordings", "GET")] [Api(Description = "Gets available live tv recordings.")] public class GetRecordings : IReturn> @@ -101,6 +113,13 @@ namespace MediaBrowser.Api.LiveTv return ToOptimizedResult(result.ToList()); } + public object Get(GetChannel request) + { + var result = _liveTvManager.GetChannel(request.Id); + + return ToOptimizedResult(_liveTvManager.GetChannelInfoDto(result)); + } + public object Get(GetRecordings request) { var result = GetRecordingsAsync(request).Result; diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index a31b6af0e2..0b7b48f47e 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -307,7 +307,7 @@ namespace MediaBrowser.Api.Playback.Progressive } } - return new ImageService(UserManager, LibraryManager, ApplicationPaths, null, ItemRepository, DtoService, ImageProcessor) + return new ImageService(UserManager, LibraryManager, ApplicationPaths, null, ItemRepository, DtoService, ImageProcessor, null) { Logger = Logger, RequestContext = RequestContext, diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 8535ac9965..5ec2f2c4a1 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -37,9 +37,8 @@ namespace MediaBrowser.Controller.LiveTv /// /// Gets the channel. /// - /// Name of the service. - /// The channel identifier. + /// The identifier. /// Channel. - Channel GetChannel(string serviceName, string channelId); + Channel GetChannel(string id); } } diff --git a/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs b/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs index b6691eca3b..8e4c958701 100644 --- a/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/ChannelInfoDto.cs @@ -19,6 +19,12 @@ namespace MediaBrowser.Model.LiveTv /// The identifier. public string Id { get; set; } + /// + /// Gets or sets the channel identifier. + /// + /// The channel identifier. + public string ChannelId { get; set; } + /// /// Gets or sets the logo image tag. /// @@ -42,5 +48,11 @@ namespace MediaBrowser.Model.LiveTv /// /// The type of the channel. public ChannelType ChannelType { get; set; } + + /// + /// Gets or sets the type. + /// + /// The type. + public string Type { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs index 4ab6e55c8c..e1a918fd2e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs @@ -33,12 +33,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo) { - if (item.HasImage(ImageType.Primary)) - { - return false; - } - - return base.NeedsRefreshInternal(item, providerInfo); + return !item.HasImage(ImageType.Primary); } public override async Task FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 9e1c6c4acb..8ea4ff1d3f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -70,9 +70,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv Name = info.Name, ServiceName = info.ServiceName, ChannelType = info.ChannelType, - Id = info.ChannelId, + ChannelId = info.ChannelId, Number = info.ChannelNumber, - PrimaryImageTag = GetLogoImageTag(info) + PrimaryImageTag = GetLogoImageTag(info), + Type = info.GetType().Name, + Id = info.Id.ToString("N") }; } @@ -113,9 +115,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv }).ThenBy(i => i.Name); } - public Channel GetChannel(string serviceName, string channelId) + public Channel GetChannel(string id) { - return _channels.FirstOrDefault(i => string.Equals(i.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase) && string.Equals(i.ChannelId, channelId, StringComparison.OrdinalIgnoreCase)); + var guid = new Guid(id); + + return _channels.FirstOrDefault(i => i.Id == guid); } internal async Task RefreshChannels(IProgress progress, CancellationToken cancellationToken) @@ -125,36 +129,44 @@ namespace MediaBrowser.Server.Implementations.LiveTv var tasks = _services.Select(i => i.GetChannelsAsync(currentCancellationToken)); + progress.Report(10); + var results = await Task.WhenAll(tasks).ConfigureAwait(false); - var allChannels = results.SelectMany(i => i); + var allChannels = results.SelectMany(i => i).ToList(); - var channnelTasks = allChannels.Select(i => GetChannel(i, cancellationToken)); + var list = new List(); - var channelEntities = await Task.WhenAll(channnelTasks).ConfigureAwait(false); + var numComplete = 0; - _channels = channelEntities.ToList(); + foreach (var channel in allChannels) + { + try + { + var item = await GetChannel(channel, cancellationToken).ConfigureAwait(false); + + list.Add(item); + } + catch (OperationCanceledException) + { + throw; + } + catch (Exception ex) + { + _logger.ErrorException("Error getting channel information for {0}", ex, channel.Name); + } + + numComplete++; + double percent = numComplete; + percent /= allChannels.Count; + + progress.Report(90 * percent + 10); + } + + _channels = list; } private async Task GetChannel(ChannelInfo channelInfo, CancellationToken cancellationToken) - { - try - { - return await GetChannelInternal(channelInfo, cancellationToken).ConfigureAwait(false); - } - catch (OperationCanceledException) - { - throw; - } - catch (Exception ex) - { - _logger.ErrorException("Error getting channel information for {0}", ex, channelInfo.Name); - - return null; - } - } - - private async Task GetChannelInternal(ChannelInfo channelInfo, CancellationToken cancellationToken) { var path = Path.Combine(_appPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(channelInfo.ServiceName), _fileSystem.GetValidFilename(channelInfo.Name));