Sfoglia il codice sorgente

added separate tvdb series images provider

Luke Pulverenti 12 anni fa
parent
commit
c702fb2179

+ 1 - 0
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -75,6 +75,7 @@
     <Compile Include="Library\ILibraryPrescanTask.cs" />
     <Compile Include="Providers\Movies\MovieDbImagesProvider.cs" />
     <Compile Include="Providers\TV\TvdbPrescanTask.cs" />
+    <Compile Include="Providers\TV\TvdbSeriesImageProvider.cs" />
     <Compile Include="Session\ISessionManager.cs" />
     <Compile Include="Drawing\ImageExtensions.cs" />
     <Compile Include="Drawing\ImageHeader.cs" />

+ 5 - 87
MediaBrowser.Controller/Providers/TV/RemoteSeriesProvider.cs

@@ -228,15 +228,13 @@ namespace MediaBrowser.Controller.Providers.TV
 
             cancellationToken.ThrowIfCancellationRequested();
 
-            var status = ProviderRefreshStatus.Success;
-
             if (!string.IsNullOrEmpty(seriesId))
             {
                 series.SetProviderId(MetadataProviders.Tvdb, seriesId);
 
                 var seriesDataPath = GetSeriesDataPath(ConfigurationManager.ApplicationPaths, seriesId);
 
-                status = await FetchSeriesData(series, seriesId, seriesDataPath, cancellationToken).ConfigureAwait(false);
+                await FetchSeriesData(series, seriesId, seriesDataPath, cancellationToken).ConfigureAwait(false);
             }
 
             BaseProviderInfo data;
@@ -247,8 +245,8 @@ namespace MediaBrowser.Controller.Providers.TV
             }
 
             data.Data = GetComparisonData(item);
-            
-            SetLastRefreshed(item, DateTime.UtcNow, status);
+
+            SetLastRefreshed(item, DateTime.UtcNow);
             return true;
         }
 
@@ -260,10 +258,8 @@ namespace MediaBrowser.Controller.Providers.TV
         /// <param name="seriesDataPath">The series data path.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task{System.Boolean}.</returns>
-        private async Task<ProviderRefreshStatus> FetchSeriesData(Series series, string seriesId, string seriesDataPath, CancellationToken cancellationToken)
+        private async Task FetchSeriesData(Series series, string seriesId, string seriesDataPath, CancellationToken cancellationToken)
         {
-            var status = ProviderRefreshStatus.Success;
-
             var files = Directory.EnumerateFiles(seriesDataPath, "*.xml", SearchOption.TopDirectoryOnly).Select(Path.GetFileName).ToArray();
 
             var seriesXmlFilename = ConfigurationManager.Configuration.PreferredMetadataLanguage.ToLower() + ".xml";
@@ -299,24 +295,6 @@ namespace MediaBrowser.Controller.Providers.TV
                     await _providerManager.SaveToLibraryFilesystem(series, Path.Combine(series.MetaLocation, LocalMetaFileName), ms, cancellationToken).ConfigureAwait(false);
                 }
             }
-
-            // Process images
-            var imagesXmlPath = Path.Combine(seriesDataPath, "banners.xml");
-
-            try
-            {
-                var xmlDoc = new XmlDocument();
-                xmlDoc.Load(imagesXmlPath);
-
-                await FetchImages(series, xmlDoc, cancellationToken).ConfigureAwait(false);
-            }
-            catch (HttpException)
-            {
-                // Have the provider try again next time, but don't let it fail here
-                status = ProviderRefreshStatus.CompletedWithErrors;
-            }
-
-            return status;
         }
 
         /// <summary>
@@ -329,7 +307,7 @@ namespace MediaBrowser.Controller.Providers.TV
         internal async Task DownloadSeriesZip(string seriesId, string seriesDataPath, CancellationToken cancellationToken)
         {
             var url = string.Format(SeriesGetZip, TVUtils.TvdbApiKey, seriesId, ConfigurationManager.Configuration.PreferredMetadataLanguage);
-            
+
             using (var zipStream = await HttpClient.Get(new HttpRequestOptions
             {
                 Url = url,
@@ -486,66 +464,6 @@ namespace MediaBrowser.Controller.Providers.TV
         /// </summary>
         protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
 
-        /// <summary>
-        /// Fetches the images.
-        /// </summary>
-        /// <param name="series">The series.</param>
-        /// <param name="images">The images.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <returns>Task.</returns>
-        private async Task FetchImages(Series series, XmlDocument images, CancellationToken cancellationToken)
-        {
-            if (ConfigurationManager.Configuration.RefreshItemImages || !series.HasImage(ImageType.Primary))
-            {
-                var n = images.SelectSingleNode("//Banner[BannerType='poster']");
-                if (n != null)
-                {
-                    n = n.SelectSingleNode("./BannerPath");
-                    if (n != null)
-                    {
-                        series.PrimaryImagePath = await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n.InnerText, "folder" + Path.GetExtension(n.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, TvDbResourcePool, cancellationToken).ConfigureAwait(false);
-                    }
-                }
-            }
-
-            if (ConfigurationManager.Configuration.DownloadSeriesImages.Banner && (ConfigurationManager.Configuration.RefreshItemImages || !series.HasImage(ImageType.Banner)))
-            {
-                var n = images.SelectSingleNode("//Banner[BannerType='series']");
-                if (n != null)
-                {
-                    n = n.SelectSingleNode("./BannerPath");
-                    if (n != null)
-                    {
-                        var bannerImagePath = await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n.InnerText, "banner" + Path.GetExtension(n.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, TvDbResourcePool, cancellationToken);
-
-                        series.SetImage(ImageType.Banner, bannerImagePath);
-                    }
-                }
-            }
-
-            if (series.BackdropImagePaths.Count < ConfigurationManager.Configuration.MaxBackdrops)
-            {
-                var bdNo = series.BackdropImagePaths.Count;
-                var xmlNodeList = images.SelectNodes("//Banner[BannerType='fanart']");
-                if (xmlNodeList != null)
-                {
-                    foreach (XmlNode b in xmlNodeList)
-                    {
-                        var p = b.SelectSingleNode("./BannerPath");
-
-                        if (p != null)
-                        {
-                            var bdName = "backdrop" + (bdNo > 0 ? bdNo.ToString(UsCulture) : "");
-                            series.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + p.InnerText, bdName + Path.GetExtension(p.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, TvDbResourcePool, cancellationToken).ConfigureAwait(false));
-                            bdNo++;
-                        }
-
-                        if (series.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MaxBackdrops) break;
-                    }
-                }
-            }
-        }
-
         /// <summary>
         /// Determines whether [has local meta] [the specified item].
         /// </summary>

+ 280 - 0
MediaBrowser.Controller/Providers/TV/TvdbSeriesImageProvider.cs

@@ -0,0 +1,280 @@
+using System.Globalization;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using System;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml;
+
+namespace MediaBrowser.Controller.Providers.TV
+{
+    public class TvdbSeriesImageProvider : BaseMetadataProvider
+    {
+        /// <summary>
+        /// Gets the HTTP client.
+        /// </summary>
+        /// <value>The HTTP client.</value>
+        protected IHttpClient HttpClient { get; private set; }
+
+        /// <summary>
+        /// The _provider manager
+        /// </summary>
+        private readonly IProviderManager _providerManager;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TvdbSeriesImageProvider"/> class.
+        /// </summary>
+        /// <param name="httpClient">The HTTP client.</param>
+        /// <param name="logManager">The log manager.</param>
+        /// <param name="configurationManager">The configuration manager.</param>
+        /// <param name="providerManager">The provider manager.</param>
+        /// <exception cref="System.ArgumentNullException">httpClient</exception>
+        public TvdbSeriesImageProvider(IHttpClient httpClient, ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
+            : base(logManager, configurationManager)
+        {
+            if (httpClient == null)
+            {
+                throw new ArgumentNullException("httpClient");
+            }
+            HttpClient = httpClient;
+            _providerManager = providerManager;
+        }
+
+        /// <summary>
+        /// Supportses the specified item.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
+        public override bool Supports(BaseItem item)
+        {
+            return item is Series;
+        }
+
+        /// <summary>
+        /// Gets the priority.
+        /// </summary>
+        /// <value>The priority.</value>
+        public override MetadataProviderPriority Priority
+        {
+            // Run after fanart
+            get { return MetadataProviderPriority.Fourth; }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether [requires internet].
+        /// </summary>
+        /// <value><c>true</c> if [requires internet]; otherwise, <c>false</c>.</value>
+        public override bool RequiresInternet
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        /// <summary>
+        /// Returns true or false indicating if the provider should refresh when the contents of it's directory changes
+        /// </summary>
+        /// <value><c>true</c> if [refresh on file system stamp change]; otherwise, <c>false</c>.</value>
+        protected override bool RefreshOnFileSystemStampChange
+        {
+            get
+            {
+                return ConfigurationManager.Configuration.SaveLocalMeta;
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether [refresh on version change].
+        /// </summary>
+        /// <value><c>true</c> if [refresh on version change]; otherwise, <c>false</c>.</value>
+        protected override bool RefreshOnVersionChange
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        /// <summary>
+        /// Gets the provider version.
+        /// </summary>
+        /// <value>The provider version.</value>
+        protected override string ProviderVersion
+        {
+            get
+            {
+                return "1";
+            }
+        }
+
+        /// <summary>
+        /// Needses the refresh internal.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="providerInfo">The provider info.</param>
+        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
+        protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
+        {
+            if (GetComparisonData(item) != providerInfo.Data)
+            {
+                return true;
+            }
+
+            return base.NeedsRefreshInternal(item, providerInfo);
+        }
+
+        /// <summary>
+        /// Gets the comparison data.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <returns>Guid.</returns>
+        private Guid GetComparisonData(BaseItem item)
+        {
+            var seriesId = item.GetProviderId(MetadataProviders.Tvdb);
+
+            if (!string.IsNullOrEmpty(seriesId))
+            {
+                // Process images
+                var imagesXmlPath = Path.Combine(RemoteSeriesProvider.GetSeriesDataPath(ConfigurationManager.ApplicationPaths, seriesId), "banners.xml");
+
+                var imagesFileInfo = new FileInfo(imagesXmlPath);
+
+                return GetComparisonData(imagesFileInfo);
+            }
+
+            return Guid.Empty;
+        }
+
+        /// <summary>
+        /// Gets the comparison data.
+        /// </summary>
+        /// <param name="imagesFileInfo">The images file info.</param>
+        /// <returns>Guid.</returns>
+        private Guid GetComparisonData(FileInfo imagesFileInfo)
+        {
+            var date = imagesFileInfo.Exists ? imagesFileInfo.LastWriteTimeUtc : DateTime.MinValue;
+
+            var key = date.Ticks + imagesFileInfo.FullName;
+
+            return key.GetMD5();
+        }
+
+        /// <summary>
+        /// Fetches metadata and returns true or false indicating if any work that requires persistence was done
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="force">if set to <c>true</c> [force].</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task{System.Boolean}.</returns>
+        public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
+        {
+            cancellationToken.ThrowIfCancellationRequested();
+
+            var series = (Series)item;
+            var seriesId = series.GetProviderId(MetadataProviders.Tvdb);
+
+            if (!string.IsNullOrEmpty(seriesId))
+            {
+                // Process images
+                var imagesXmlPath = Path.Combine(RemoteSeriesProvider.GetSeriesDataPath(ConfigurationManager.ApplicationPaths, seriesId), "banners.xml");
+
+                var imagesFileInfo = new FileInfo(imagesXmlPath);
+
+                if (imagesFileInfo.Exists)
+                {
+                    if (!series.HasImage(ImageType.Primary) || !series.HasImage(ImageType.Banner) || series.BackdropImagePaths.Count == 0)
+                    {
+                        var xmlDoc = new XmlDocument();
+                        xmlDoc.Load(imagesXmlPath);
+
+                        await FetchImages(series, xmlDoc, cancellationToken).ConfigureAwait(false);
+                    }
+                }
+
+                BaseProviderInfo data;
+                if (!item.ProviderData.TryGetValue(Id, out data))
+                {
+                    data = new BaseProviderInfo();
+                    item.ProviderData[Id] = data;
+                }
+
+                data.Data = GetComparisonData(imagesFileInfo);
+                
+                SetLastRefreshed(item, DateTime.UtcNow);
+                return true;
+            }
+
+            return false;
+        }
+
+        protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
+        
+        /// <summary>
+        /// Fetches the images.
+        /// </summary>
+        /// <param name="series">The series.</param>
+        /// <param name="images">The images.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        private async Task FetchImages(Series series, XmlDocument images, CancellationToken cancellationToken)
+        {
+            if (ConfigurationManager.Configuration.RefreshItemImages || !series.HasImage(ImageType.Primary))
+            {
+                var n = images.SelectSingleNode("//Banner[BannerType='poster']");
+                if (n != null)
+                {
+                    n = n.SelectSingleNode("./BannerPath");
+                    if (n != null)
+                    {
+                        series.PrimaryImagePath = await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n.InnerText, "folder" + Path.GetExtension(n.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false);
+                    }
+                }
+            }
+
+            if (ConfigurationManager.Configuration.DownloadSeriesImages.Banner && (ConfigurationManager.Configuration.RefreshItemImages || !series.HasImage(ImageType.Banner)))
+            {
+                var n = images.SelectSingleNode("//Banner[BannerType='series']");
+                if (n != null)
+                {
+                    n = n.SelectSingleNode("./BannerPath");
+                    if (n != null)
+                    {
+                        var bannerImagePath = await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n.InnerText, "banner" + Path.GetExtension(n.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken);
+
+                        series.SetImage(ImageType.Banner, bannerImagePath);
+                    }
+                }
+            }
+
+            if (series.BackdropImagePaths.Count < ConfigurationManager.Configuration.MaxBackdrops)
+            {
+                var bdNo = series.BackdropImagePaths.Count;
+                var xmlNodeList = images.SelectNodes("//Banner[BannerType='fanart']");
+                if (xmlNodeList != null)
+                {
+                    foreach (XmlNode b in xmlNodeList)
+                    {
+                        var p = b.SelectSingleNode("./BannerPath");
+
+                        if (p != null)
+                        {
+                            var bdName = "backdrop" + (bdNo > 0 ? bdNo.ToString(UsCulture) : "");
+                            series.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + p.InnerText, bdName + Path.GetExtension(p.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false));
+                            bdNo++;
+                        }
+
+                        if (series.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MaxBackdrops) break;
+                    }
+                }
+            }
+        }
+    }
+}