TvdbSeasonProvider.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using System.Net;
  2. using MediaBrowser.Common.IO;
  3. using MediaBrowser.Controller.Configuration;
  4. using MediaBrowser.Controller.Entities;
  5. using MediaBrowser.Controller.Entities.TV;
  6. using MediaBrowser.Controller.Library;
  7. using MediaBrowser.Controller.Providers;
  8. using MediaBrowser.Model.Entities;
  9. using MediaBrowser.Model.Logging;
  10. using MediaBrowser.Model.Net;
  11. using MediaBrowser.Model.Providers;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.IO;
  15. using System.Linq;
  16. using System.Threading;
  17. using System.Threading.Tasks;
  18. namespace MediaBrowser.Providers.TV
  19. {
  20. /// <summary>
  21. /// Class RemoteSeasonProvider
  22. /// </summary>
  23. class TvdbSeasonProvider : BaseMetadataProvider
  24. {
  25. /// <summary>
  26. /// The _provider manager
  27. /// </summary>
  28. private readonly IProviderManager _providerManager;
  29. private readonly IFileSystem _fileSystem;
  30. /// <summary>
  31. /// Initializes a new instance of the <see cref="TvdbSeasonProvider"/> class.
  32. /// </summary>
  33. /// <param name="logManager">The log manager.</param>
  34. /// <param name="configurationManager">The configuration manager.</param>
  35. /// <param name="providerManager">The provider manager.</param>
  36. /// <exception cref="System.ArgumentNullException">httpClient</exception>
  37. public TvdbSeasonProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
  38. : base(logManager, configurationManager)
  39. {
  40. _providerManager = providerManager;
  41. _fileSystem = fileSystem;
  42. }
  43. /// <summary>
  44. /// Supportses the specified item.
  45. /// </summary>
  46. /// <param name="item">The item.</param>
  47. /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
  48. public override bool Supports(BaseItem item)
  49. {
  50. return item is Season;
  51. }
  52. /// <summary>
  53. /// Gets the priority.
  54. /// </summary>
  55. /// <value>The priority.</value>
  56. public override MetadataProviderPriority Priority
  57. {
  58. // Run after fanart
  59. get { return MetadataProviderPriority.Fourth; }
  60. }
  61. /// <summary>
  62. /// Gets a value indicating whether [requires internet].
  63. /// </summary>
  64. /// <value><c>true</c> if [requires internet]; otherwise, <c>false</c>.</value>
  65. public override bool RequiresInternet
  66. {
  67. get
  68. {
  69. return true;
  70. }
  71. }
  72. public override ItemUpdateType ItemUpdateType
  73. {
  74. get
  75. {
  76. return ItemUpdateType.ImageUpdate;
  77. }
  78. }
  79. /// <summary>
  80. /// Gets a value indicating whether [refresh on version change].
  81. /// </summary>
  82. /// <value><c>true</c> if [refresh on version change]; otherwise, <c>false</c>.</value>
  83. protected override bool RefreshOnVersionChange
  84. {
  85. get
  86. {
  87. return true;
  88. }
  89. }
  90. /// <summary>
  91. /// Gets the provider version.
  92. /// </summary>
  93. /// <value>The provider version.</value>
  94. protected override string ProviderVersion
  95. {
  96. get
  97. {
  98. return "2";
  99. }
  100. }
  101. protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
  102. {
  103. var season = (Season)item;
  104. var seriesId = season.Series != null ? season.Series.GetProviderId(MetadataProviders.Tvdb) : null;
  105. if (!string.IsNullOrEmpty(seriesId))
  106. {
  107. // Process images
  108. var imagesXmlPath = Path.Combine(TvdbSeriesProvider.GetSeriesDataPath(ConfigurationManager.ApplicationPaths, seriesId), "banners.xml");
  109. var imagesFileInfo = new FileInfo(imagesXmlPath);
  110. if (imagesFileInfo.Exists)
  111. {
  112. return _fileSystem.GetLastWriteTimeUtc(imagesFileInfo) > providerInfo.LastRefreshed;
  113. }
  114. }
  115. return false;
  116. }
  117. protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
  118. {
  119. if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Banner) && item.BackdropImagePaths.Count > 0)
  120. {
  121. return false;
  122. }
  123. return base.NeedsRefreshInternal(item, providerInfo);
  124. }
  125. /// <summary>
  126. /// Fetches metadata and returns true or false indicating if any work that requires persistence was done
  127. /// </summary>
  128. /// <param name="item">The item.</param>
  129. /// <param name="force">if set to <c>true</c> [force].</param>
  130. /// <param name="cancellationToken">The cancellation token.</param>
  131. /// <returns>Task{System.Boolean}.</returns>
  132. public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
  133. {
  134. cancellationToken.ThrowIfCancellationRequested();
  135. var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, ManualTvdbSeasonImageProvider.ProviderName).ConfigureAwait(false);
  136. const int backdropLimit = 1;
  137. await DownloadImages(item, images.ToList(), backdropLimit, cancellationToken).ConfigureAwait(false);
  138. SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
  139. return true;
  140. }
  141. private async Task DownloadImages(BaseItem item, List<RemoteImageInfo> images, int backdropLimit, CancellationToken cancellationToken)
  142. {
  143. if (!item.HasImage(ImageType.Primary))
  144. {
  145. await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false);
  146. }
  147. if (ConfigurationManager.Configuration.DownloadSeasonImages.Banner && !item.HasImage(ImageType.Banner))
  148. {
  149. await SaveImage(item, images, ImageType.Banner, cancellationToken).ConfigureAwait(false);
  150. }
  151. if (ConfigurationManager.Configuration.DownloadSeasonImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit)
  152. {
  153. foreach (var backdrop in images.Where(i => i.Type == ImageType.Backdrop))
  154. {
  155. var url = backdrop.Url;
  156. if (item.ContainsImageWithSourceUrl(url))
  157. {
  158. continue;
  159. }
  160. await _providerManager.SaveImage(item, url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, null, cancellationToken).ConfigureAwait(false);
  161. if (item.BackdropImagePaths.Count >= backdropLimit) break;
  162. }
  163. }
  164. }
  165. private async Task SaveImage(BaseItem item, List<RemoteImageInfo> images, ImageType type, CancellationToken cancellationToken)
  166. {
  167. foreach (var image in images.Where(i => i.Type == type))
  168. {
  169. try
  170. {
  171. await _providerManager.SaveImage(item, image.Url, TvdbSeriesProvider.Current.TvDbResourcePool, type, null, cancellationToken).ConfigureAwait(false);
  172. break;
  173. }
  174. catch (HttpException ex)
  175. {
  176. // Sometimes fanart has bad url's in their xml
  177. if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
  178. {
  179. continue;
  180. }
  181. break;
  182. }
  183. }
  184. }
  185. }
  186. }