From c0f606683a045e463f518ec466b9fc9a85f8d4fd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 29 Jan 2014 11:16:24 -0500 Subject: [PATCH] convert programs and channels to new providers --- .../Providers/ILocalImageProvider.cs | 18 ++- MediaBrowser.Providers/BaseXmlProvider.cs | 6 + .../LiveTv/ChannelMetadataService.cs | 37 +++++ .../LiveTv/ChannelProviderFromXml.cs | 91 ------------ .../LiveTv/ChannelXmlProvider.cs | 59 ++++++++ .../LiveTv/ProgramMetadataService.cs | 41 ++++++ .../Manager/ItemImageProvider.cs | 23 ++- .../MediaBrowser.Providers.csproj | 4 +- .../People/PersonXmlProvider.cs | 5 - .../Library/LibraryManager.cs | 6 +- .../LiveTv/ChannelImageProvider.cs | 135 ++++++------------ .../LiveTv/ProgramImageProvider.cs | 135 ++++++------------ 12 files changed, 263 insertions(+), 297 deletions(-) create mode 100644 MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs delete mode 100644 MediaBrowser.Providers/LiveTv/ChannelProviderFromXml.cs create mode 100644 MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs create mode 100644 MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs diff --git a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs index 30f2136059..5c3ebd9acf 100644 --- a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs +++ b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.IO; +using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller.Providers @@ -28,19 +29,20 @@ namespace MediaBrowser.Controller.Providers public interface IDynamicImageProvider : ILocalImageProvider { /// - /// Gets the images. + /// Gets the supported images. /// /// The item. - /// List{DynamicImageInfo}. - List GetImageInfos(IHasImages item); + /// IEnumerable{ImageType}. + IEnumerable GetSupportedImages(IHasImages item); /// /// Gets the image. /// /// The item. - /// The information. + /// The type. + /// The cancellation token. /// Task{DynamicImageResponse}. - Task GetImage(IHasImages item, DynamicImageInfo info); + Task GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken); } public class DynamicImageInfo @@ -54,5 +56,11 @@ namespace MediaBrowser.Controller.Providers public string Path { get; set; } public Stream Stream { get; set; } public ImageFormat Format { get; set; } + public bool HasImage { get; set; } + + public void SetFormatFromMimeType(string mimeType) + { + + } } } diff --git a/MediaBrowser.Providers/BaseXmlProvider.cs b/MediaBrowser.Providers/BaseXmlProvider.cs index 71043df514..eab5bb574e 100644 --- a/MediaBrowser.Providers/BaseXmlProvider.cs +++ b/MediaBrowser.Providers/BaseXmlProvider.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller.Providers; using System; +using System.IO; using System.Threading; namespace MediaBrowser.Providers @@ -24,5 +25,10 @@ namespace MediaBrowser.Providers return FileSystem.GetLastWriteTimeUtc(path) > date; } + + public bool HasLocalMetadata(IHasMetadata item) + { + return File.Exists(GetXmlPath(item.Path)); + } } } diff --git a/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs b/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs new file mode 100644 index 0000000000..dd44ba7aae --- /dev/null +++ b/MediaBrowser.Providers/LiveTv/ChannelMetadataService.cs @@ -0,0 +1,37 @@ +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.Providers; +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 ChannelMetadataService : MetadataService + { + private readonly ILibraryManager _libraryManager; + + public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo) + { + _libraryManager = libraryManager; + } + + /// + /// Merges the specified source. + /// + protected override void MergeData(LiveTvChannel source, LiveTvChannel target, List lockedFields, bool replaceData, bool mergeMetadataSettings) + { + ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); + } + + protected override Task SaveItem(LiveTvChannel item, ItemUpdateType reason, CancellationToken cancellationToken) + { + return _libraryManager.UpdateItem(item, reason, cancellationToken); + } + } +} diff --git a/MediaBrowser.Providers/LiveTv/ChannelProviderFromXml.cs b/MediaBrowser.Providers/LiveTv/ChannelProviderFromXml.cs deleted file mode 100644 index 8ee2553d03..0000000000 --- a/MediaBrowser.Providers/LiveTv/ChannelProviderFromXml.cs +++ /dev/null @@ -1,91 +0,0 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Logging; -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Providers.LiveTv -{ - class ChannelProviderFromXml : BaseMetadataProvider - { - private readonly IFileSystem _fileSystem; - - public ChannelProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem) - : base(logManager, configurationManager) - { - _fileSystem = fileSystem; - } - - /// - /// Supportses the specified item. - /// - /// The item. - /// true if XXXX, false otherwise - public override bool Supports(BaseItem item) - { - return item is LiveTvChannel; - } - - /// - /// Gets the priority. - /// - /// The priority. - public override MetadataProviderPriority Priority - { - get { return MetadataProviderPriority.Second; } - } - - private const string XmlFileName = "channel.xml"; - protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo) - { - var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName)); - - if (xml == null) - { - return false; - } - - return _fileSystem.GetLastWriteTimeUtc(xml) > item.DateLastSaved; - } - - /// - /// Fetches metadata and returns true or false indicating if any work that requires persistence was done - /// - /// The item. - /// if set to true [force]. - /// The cancellation token. - /// Task{System.Boolean}. - public override async Task FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) - { - cancellationToken.ThrowIfCancellationRequested(); - - var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName)); - - if (metadataFile != null) - { - var path = metadataFile.FullName; - - await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - new BaseItemXmlParser(Logger).Fetch((LiveTvChannel)item, path, cancellationToken); - } - finally - { - XmlParsingResourcePool.Release(); - } - - SetLastRefreshed(item, DateTime.UtcNow, providerInfo); - return true; - } - - return false; - } - } -} diff --git a/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs b/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs new file mode 100644 index 0000000000..544685f661 --- /dev/null +++ b/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs @@ -0,0 +1,59 @@ +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Logging; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Providers.LiveTv +{ + public class ChannelXmlProvider : BaseXmlProvider, ILocalMetadataProvider + { + private readonly ILogger _logger; + + public ChannelXmlProvider(IFileSystem fileSystem, ILogger logger) + : base(fileSystem) + { + _logger = logger; + } + + public async Task> GetMetadata(string path, CancellationToken cancellationToken) + { + path = GetXmlPath(path); + + var result = new MetadataResult(); + + await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + + try + { + var item = new LiveTvChannel(); + + new BaseItemXmlParser(_logger).Fetch(item, path, cancellationToken); + result.HasMetadata = true; + result.Item = item; + } + catch (FileNotFoundException) + { + result.HasMetadata = false; + } + finally + { + XmlParsingResourcePool.Release(); + } + + return result; + } + + public string Name + { + get { return "Media Browser Xml"; } + } + + protected override string GetXmlPath(string path) + { + return Path.Combine(path, "channel.xml"); + } + } +} diff --git a/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs b/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs new file mode 100644 index 0000000000..da032eb8f0 --- /dev/null +++ b/MediaBrowser.Providers/LiveTv/ProgramMetadataService.cs @@ -0,0 +1,41 @@ +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.Providers; +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 + { + private readonly ILibraryManager _libraryManager; + + public ProgramMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager) + : base(serverConfigurationManager, logger, providerManager, providerRepo) + { + _libraryManager = libraryManager; + } + + /// + /// Merges the specified source. + /// + /// The source. + /// 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); + } + + protected override Task SaveItem(LiveTvProgram item, ItemUpdateType reason, CancellationToken cancellationToken) + { + return _libraryManager.UpdateItem(item, reason, cancellationToken); + } + } +} diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index d455a08dbe..e8bae1d2fa 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -87,27 +87,22 @@ namespace MediaBrowser.Providers.Manager try { - var images = provider.GetImageInfos(item); + var images = provider.GetSupportedImages(item); - foreach (var image in images) + foreach (var imageType in images) { - if (!item.HasImage(image.Type)) + if (!item.HasImage(imageType)) { - var imageSource = await provider.GetImage(item, image).ConfigureAwait(false); + var response = await provider.GetImage(item, imageType, cancellationToken).ConfigureAwait(false); - // See if the provider returned an image path or a stream - if (!string.IsNullOrEmpty(imageSource.Path)) + if (response.HasImage) { - item.SetImagePath(image.Type, imageSource.Path); - } - else - { - var mimeType = "image/" + imageSource.Format.ToString().ToLower(); + var mimeType = "image/" + response.Format.ToString().ToLower(); - await _providerManager.SaveImage((BaseItem)item, imageSource.Stream, mimeType, image.Type, null, Guid.NewGuid().ToString(), cancellationToken).ConfigureAwait(false); - } + await _providerManager.SaveImage((BaseItem)item, response.Stream, mimeType, imageType, null, Guid.NewGuid().ToString(), cancellationToken).ConfigureAwait(false); - result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; + result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; + } } } } diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index db8de8a165..b44d3608e1 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -67,6 +67,9 @@ + + + @@ -84,7 +87,6 @@ - diff --git a/MediaBrowser.Providers/People/PersonXmlProvider.cs b/MediaBrowser.Providers/People/PersonXmlProvider.cs index 9da53e8278..900b7956c8 100644 --- a/MediaBrowser.Providers/People/PersonXmlProvider.cs +++ b/MediaBrowser.Providers/People/PersonXmlProvider.cs @@ -55,10 +55,5 @@ namespace MediaBrowser.Providers.People { return Path.Combine(path, "person.xml"); } - - public bool HasLocalMetadata(IHasMetadata item) - { - return File.Exists(GetXmlPath(item.Path)); - } } } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 04344553fc..17b5ea4244 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1462,13 +1462,13 @@ namespace MediaBrowser.Server.Implementations.Library var semaphore = _fileLocks.GetOrAdd(path, key => new SemaphoreSlim(1, 1)); - var directoryWatchers = _libraryMonitorFactory(); + var libraryMonitor = _libraryMonitorFactory(); await semaphore.WaitAsync().ConfigureAwait(false); try { - directoryWatchers.ReportFileSystemChangeBeginning(path); + libraryMonitor.ReportFileSystemChangeBeginning(path); saver.Save(item, CancellationToken.None); } catch (Exception ex) @@ -1477,7 +1477,7 @@ namespace MediaBrowser.Server.Implementations.Library } finally { - directoryWatchers.ReportFileSystemChangeComplete(path, false); + libraryMonitor.ReportFileSystemChangeComplete(path, false); semaphore.Release(); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs index c1d8d796b9..9fdca568e6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs @@ -1,154 +1,111 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; using System; -using System.IO; +using System.Collections.Generic; using System.Linq; -using System.Net; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv { - public class ChannelImageProvider : BaseMetadataProvider + public class ChannelImageProvider : IDynamicImageProvider, IHasChangeMonitor { private readonly ILiveTvManager _liveTvManager; - private readonly IProviderManager _providerManager; - private readonly IFileSystem _fileSystem; private readonly IHttpClient _httpClient; + private readonly ILogger _logger; - public ChannelImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, ILiveTvManager liveTvManager, IProviderManager providerManager, IFileSystem fileSystem, IHttpClient httpClient) - : base(logManager, configurationManager) + public ChannelImageProvider(ILiveTvManager liveTvManager, IHttpClient httpClient, ILogger logger) { _liveTvManager = liveTvManager; - _providerManager = providerManager; - _fileSystem = fileSystem; _httpClient = httpClient; + _logger = logger; } - public override bool Supports(BaseItem item) + public IEnumerable GetSupportedImages(IHasImages item) { - return item is LiveTvChannel; + return new[] { ImageType.Primary }; } - protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo) + public async Task GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken) { - return !item.HasImage(ImageType.Primary); - } + var liveTvItem = (LiveTvChannel)item; - public override async Task FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) - { - if (item.HasImage(ImageType.Primary)) + var imageResponse = new DynamicImageResponse(); + + if (!string.IsNullOrEmpty(liveTvItem.ProviderImagePath)) { - SetLastRefreshed(item, DateTime.UtcNow, providerInfo); - return true; + imageResponse.Path = liveTvItem.ProviderImagePath; + imageResponse.HasImage = true; } - - var changed = true; - - try - { - changed = await DownloadImage((LiveTvChannel)item, cancellationToken).ConfigureAwait(false); - } - catch (HttpException ex) - { - // Don't fail the provider on a 404 - if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound) - { - throw; - } - } - - if (changed) - { - SetLastRefreshed(item, DateTime.UtcNow, providerInfo); - } - - return changed; - } - - private async Task DownloadImage(LiveTvChannel item, CancellationToken cancellationToken) - { - Stream imageStream = null; - string contentType = null; - - if (!string.IsNullOrEmpty(item.ProviderImagePath)) - { - contentType = "image/" + Path.GetExtension(item.ProviderImagePath).ToLower(); - imageStream = _fileSystem.GetFileStream(item.ProviderImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true); - } - else if (!string.IsNullOrEmpty(item.ProviderImageUrl)) + else if (!string.IsNullOrEmpty(liveTvItem.ProviderImageUrl)) { var options = new HttpRequestOptions { CancellationToken = cancellationToken, - Url = item.ProviderImageUrl + Url = liveTvItem.ProviderImageUrl }; var response = await _httpClient.GetResponse(options).ConfigureAwait(false); - if (!response.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) + if (response.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) { - Logger.Error("Provider did not return an image content type."); - return false; + imageResponse.HasImage = true; + imageResponse.Stream = response.Content; + imageResponse.SetFormatFromMimeType(response.ContentType); + } + else + { + _logger.Error("Provider did not return an image content type."); } - - imageStream = response.Content; - contentType = response.ContentType; } - else if (item.HasProviderImage ?? true) + else if (liveTvItem.HasProviderImage ?? true) { - var service = _liveTvManager.Services.FirstOrDefault(i => string.Equals(i.Name, item.ServiceName, StringComparison.OrdinalIgnoreCase)); + var service = _liveTvManager.Services.FirstOrDefault(i => string.Equals(i.Name, liveTvItem.ServiceName, StringComparison.OrdinalIgnoreCase)); if (service != null) { try { - var response = await service.GetChannelImageAsync(item.ExternalId, cancellationToken).ConfigureAwait(false); + var response = await service.GetChannelImageAsync(liveTvItem.ExternalId, cancellationToken).ConfigureAwait(false); if (response != null) { - imageStream = response.Stream; - contentType = "image/" + response.Format.ToString().ToLower(); + imageResponse.HasImage = true; + imageResponse.Stream = response.Stream; + imageResponse.Format = response.Format; } } catch (NotImplementedException) { - return false; } } } - if (imageStream != null) - { - // Dummy up the original url - var url = item.ServiceName + item.ExternalId; - - await _providerManager.SaveImage(item, imageStream, contentType, ImageType.Primary, null, url, cancellationToken).ConfigureAwait(false); - return true; - } - - return false; + return imageResponse; } - public override MetadataProviderPriority Priority + public string Name { - get { return MetadataProviderPriority.Second; } + get { return "Live TV Service Provider"; } } - public override ItemUpdateType ItemUpdateType + public bool Supports(IHasImages item) { - get - { - return ItemUpdateType.ImageUpdate; - } + return item is LiveTvChannel; + } + + public int Order + { + get { return 0; } + } + + public bool HasChanged(IHasMetadata item, DateTime date) + { + return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalDays >= 1; } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs index 3bf2712d43..117cb1da70 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs @@ -1,154 +1,111 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; using System; -using System.IO; +using System.Collections.Generic; using System.Linq; -using System.Net; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.LiveTv { - public class ProgramImageProvider : BaseMetadataProvider + public class ProgramImageProvider : IDynamicImageProvider, IHasChangeMonitor { private readonly ILiveTvManager _liveTvManager; - private readonly IProviderManager _providerManager; - private readonly IFileSystem _fileSystem; private readonly IHttpClient _httpClient; + private readonly ILogger _logger; - public ProgramImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, ILiveTvManager liveTvManager, IProviderManager providerManager, IFileSystem fileSystem, IHttpClient httpClient) - : base(logManager, configurationManager) + public ProgramImageProvider(ILiveTvManager liveTvManager, IHttpClient httpClient, ILogger logger) { _liveTvManager = liveTvManager; - _providerManager = providerManager; - _fileSystem = fileSystem; _httpClient = httpClient; + _logger = logger; } - public override bool Supports(BaseItem item) + public IEnumerable GetSupportedImages(IHasImages item) { - return item is LiveTvProgram; + return new[] { ImageType.Primary }; } - protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo) + public async Task GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken) { - return !item.HasImage(ImageType.Primary); - } + var liveTvItem = (LiveTvProgram)item; - public override async Task FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) - { - if (item.HasImage(ImageType.Primary)) + var imageResponse = new DynamicImageResponse(); + + if (!string.IsNullOrEmpty(liveTvItem.ProviderImagePath)) { - SetLastRefreshed(item, DateTime.UtcNow, providerInfo); - return true; + imageResponse.Path = liveTvItem.ProviderImagePath; + imageResponse.HasImage = true; } - - var changed = true; - - try - { - changed = await DownloadImage((LiveTvProgram)item, cancellationToken).ConfigureAwait(false); - } - catch (HttpException ex) - { - // Don't fail the provider on a 404 - if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound) - { - throw; - } - } - - if (changed) - { - SetLastRefreshed(item, DateTime.UtcNow, providerInfo); - } - - return changed; - } - - private async Task DownloadImage(LiveTvProgram item, CancellationToken cancellationToken) - { - Stream imageStream = null; - string contentType = null; - - if (!string.IsNullOrEmpty(item.ProviderImagePath)) - { - contentType = "image/" + Path.GetExtension(item.ProviderImagePath).ToLower(); - imageStream = _fileSystem.GetFileStream(item.ProviderImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true); - } - else if (!string.IsNullOrEmpty(item.ProviderImageUrl)) + else if (!string.IsNullOrEmpty(liveTvItem.ProviderImageUrl)) { var options = new HttpRequestOptions { CancellationToken = cancellationToken, - Url = item.ProviderImageUrl + Url = liveTvItem.ProviderImageUrl }; var response = await _httpClient.GetResponse(options).ConfigureAwait(false); - if (!response.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) + if (response.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) { - Logger.Error("Provider did not return an image content type."); - return false; + imageResponse.HasImage = true; + imageResponse.Stream = response.Content; + imageResponse.SetFormatFromMimeType(response.ContentType); + } + else + { + _logger.Error("Provider did not return an image content type."); } - - imageStream = response.Content; - contentType = response.ContentType; } - else if (item.HasProviderImage ?? true) + else if (liveTvItem.HasProviderImage ?? true) { - var service = _liveTvManager.Services.FirstOrDefault(i => string.Equals(i.Name, item.ServiceName, StringComparison.OrdinalIgnoreCase)); + var service = _liveTvManager.Services.FirstOrDefault(i => string.Equals(i.Name, liveTvItem.ServiceName, StringComparison.OrdinalIgnoreCase)); if (service != null) { try { - var response = await service.GetProgramImageAsync(item.ExternalId, item.ExternalChannelId, cancellationToken).ConfigureAwait(false); + var response = await service.GetProgramImageAsync(liveTvItem.ExternalId, liveTvItem.ExternalChannelId, cancellationToken).ConfigureAwait(false); if (response != null) { - imageStream = response.Stream; - contentType = "image/" + response.Format.ToString().ToLower(); + imageResponse.HasImage = true; + imageResponse.Stream = response.Stream; + imageResponse.Format = response.Format; } } catch (NotImplementedException) { - return false; } } } - if (imageStream != null) - { - // Dummy up the original url - var url = item.ServiceName + item.ExternalId; - - await _providerManager.SaveImage(item, imageStream, contentType, ImageType.Primary, null, url, cancellationToken).ConfigureAwait(false); - return true; - } - - return false; + return imageResponse; } - public override MetadataProviderPriority Priority + public string Name { - get { return MetadataProviderPriority.Second; } + get { return "Live TV Service Provider"; } } - public override ItemUpdateType ItemUpdateType + public bool Supports(IHasImages item) { - get - { - return ItemUpdateType.ImageUpdate; - } + return item is LiveTvProgram; + } + + public int Order + { + get { return 0; } + } + + public bool HasChanged(IHasMetadata item, DateTime date) + { + return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalHours >= 12; } } }