public async Task<RefreshResult> RefreshImages(IHasImages item, IEnumerable<IImageProvider> imageProviders, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, CancellationToken cancellationToken) { if (refreshOptions.IsReplacingImage(ImageType.Backdrop)) { ClearImages(item, ImageType.Backdrop); } if (refreshOptions.IsReplacingImage(ImageType.Screenshot)) { ClearImages(item, ImageType.Screenshot); } var result = new RefreshResult { UpdateType = ItemUpdateType.None }; var providers = imageProviders.ToList(); var providerIds = new List<Guid>(); // In order to avoid duplicates, only download these if there are none already var backdropLimit = savedOptions.GetLimit(ImageType.Backdrop); var screenshotLimit = savedOptions.GetLimit(ImageType.Screenshot); var downloadedImages = new List<ImageType>(); foreach (var provider in providers) { var remoteProvider = provider as IRemoteImageProvider; if (remoteProvider != null) { await RefreshFromProvider(item, remoteProvider, refreshOptions, savedOptions, backdropLimit, screenshotLimit, downloadedImages, result, cancellationToken).ConfigureAwait(false); providerIds.Add(provider.GetType().FullName.GetMD5()); continue; } var dynamicImageProvider = provider as IDynamicImageProvider; if (dynamicImageProvider != null) { await RefreshFromProvider(item, dynamicImageProvider, refreshOptions, savedOptions, downloadedImages, result, cancellationToken).ConfigureAwait(false); providerIds.Add(provider.GetType().FullName.GetMD5()); } } result.Providers = providerIds; return result; }
private MetadataOptions GetMetadataOptions(Type type, ServerConfiguration config) { var options = config.MetadataOptions .FirstOrDefault(i => string.Equals(i.ItemType, type.Name, StringComparison.OrdinalIgnoreCase)); if (options == null) { var list = config.MetadataOptions.ToList(); options = new MetadataOptions { ItemType = type.Name }; list.Add(options); config.MetadataOptions = list.ToArray(); } return options; }
private bool IsEnabled(MetadataOptions options, ImageType type, IHasImages item) { if (type == ImageType.Backdrop) { if (item.LockedFields.Contains(MetadataFields.Backdrops)) { return false; } } else if (type == ImageType.Screenshot) { if (item.LockedFields.Contains(MetadataFields.Screenshots)) { return false; } } else { if (item.LockedFields.Contains(MetadataFields.Images)) { return false; } } return options.IsEnabled(type); }
/// <summary> /// Determines if an item already contains the given images /// </summary> /// <param name="item">The item.</param> /// <param name="images">The images.</param> /// <param name="savedOptions">The saved options.</param> /// <param name="backdropLimit">The backdrop limit.</param> /// <param name="screenshotLimit">The screenshot limit.</param> /// <returns><c>true</c> if the specified item contains images; otherwise, <c>false</c>.</returns> private bool ContainsImages(IHasImages item, List<ImageType> images, MetadataOptions savedOptions, int backdropLimit, int screenshotLimit) { if (_singularImages.Any(i => images.Contains(i) && !item.HasImage(i) && savedOptions.GetLimit(i) > 0)) { return false; } if (images.Contains(ImageType.Backdrop) && item.GetImages(ImageType.Backdrop).Count() < backdropLimit) { return false; } if (images.Contains(ImageType.Screenshot) && item.GetImages(ImageType.Screenshot).Count() < screenshotLimit) { return false; } return true; }
/// <summary> /// Refreshes from provider. /// </summary> /// <param name="item">The item.</param> /// <param name="provider">The provider.</param> /// <param name="refreshOptions">The refresh options.</param> /// <param name="savedOptions">The saved options.</param> /// <param name="backdropLimit">The backdrop limit.</param> /// <param name="screenshotLimit">The screenshot limit.</param> /// <param name="downloadedImages">The downloaded images.</param> /// <param name="result">The result.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> private async Task RefreshFromProvider(IHasImages item, IRemoteImageProvider provider, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, int backdropLimit, int screenshotLimit, ICollection<ImageType> downloadedImages, RefreshResult result, CancellationToken cancellationToken) { try { if (!item.SupportsRemoteImageDownloading) { return; } if (!refreshOptions.ReplaceAllImages && refreshOptions.ReplaceImages.Count == 0 && ContainsImages(item, provider.GetSupportedImages(item).ToList(), savedOptions, backdropLimit, screenshotLimit)) { return; } _logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name); var images = await _providerManager.GetAvailableRemoteImages(item, new RemoteImageQuery { ProviderName = provider.Name, IncludeAllLanguages = false, IncludeDisabledProviders = false, }, cancellationToken).ConfigureAwait(false); var list = images.ToList(); int minWidth; foreach (var imageType in _singularImages) { if (!IsEnabled(savedOptions, imageType, item)) continue; if (!item.HasImage(imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType))) { minWidth = savedOptions.GetMinWidth(imageType); var downloaded = await DownloadImage(item, provider, result, list, minWidth, imageType, cancellationToken).ConfigureAwait(false); if (downloaded) { downloadedImages.Add(imageType); } } } if (!item.LockedFields.Contains(MetadataFields.Backdrops)) { minWidth = savedOptions.GetMinWidth(ImageType.Backdrop); await DownloadBackdrops(item, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false); } if (!item.LockedFields.Contains(MetadataFields.Screenshots)) { var hasScreenshots = item as IHasScreenshots; if (hasScreenshots != null) { minWidth = savedOptions.GetMinWidth(ImageType.Screenshot); await DownloadBackdrops(item, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false); } } } catch (OperationCanceledException) { throw; } catch (Exception ex) { result.ErrorMessage = ex.Message; result.Status = ProviderRefreshStatus.CompletedWithErrors; _logger.ErrorException("Error in {0}", ex, provider.Name); } }
/// <summary> /// Refreshes from provider. /// </summary> /// <param name="item">The item.</param> /// <param name="provider">The provider.</param> /// <param name="refreshOptions">The refresh options.</param> /// <param name="savedOptions">The saved options.</param> /// <param name="downloadedImages">The downloaded images.</param> /// <param name="result">The result.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> private async Task RefreshFromProvider(IHasImages item, IDynamicImageProvider provider, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, ICollection<ImageType> downloadedImages, RefreshResult result, CancellationToken cancellationToken) { try { var images = provider.GetSupportedImages(item); foreach (var imageType in images) { if (!IsEnabled(savedOptions, imageType, item)) continue; if (!item.HasImage(imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType))) { _logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name); var response = await provider.GetImage(item, imageType, cancellationToken).ConfigureAwait(false); if (response.HasImage) { if (!string.IsNullOrEmpty(response.Path)) { var mimeType = "image/" + Path.GetExtension(response.Path).TrimStart('.').ToLower(); var stream = _fileSystem.GetFileStream(response.Path, FileMode.Open, FileAccess.Read, FileShare.Read, true); await _providerManager.SaveImage(item, stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false); } else { var mimeType = "image/" + response.Format.ToString().ToLower(); await _providerManager.SaveImage(item, response.Stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false); } downloadedImages.Add(imageType); result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; } } } } catch (OperationCanceledException) { throw; } catch (Exception ex) { result.ErrorMessage = ex.Message; result.Status = ProviderRefreshStatus.CompletedWithErrors; _logger.ErrorException("Error in {0}", ex, provider.Name); } }
private int GetConfiguredOrder(IMetadataProvider provider, MetadataOptions options) { // See if there's a user-defined order if (provider is ILocalMetadataProvider) { var index = Array.IndexOf(options.LocalMetadataReaderOrder, provider.Name); if (index != -1) { return index; } } // See if there's a user-defined order if (provider is IRemoteMetadataProvider) { var index = Array.IndexOf(options.MetadataFetcherOrder, provider.Name); if (index != -1) { return index; } } // Not configured. Just return some high number to put it at the end. return 100; }
private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, MetadataOptions options, bool includeDisabled, bool checkIsOwnedItem) { if (!includeDisabled) { // If locked only allow local providers if (item.IsLocked && !(provider is ILocalMetadataProvider) && !(provider is IForcedProvider)) { return false; } if (provider is IRemoteMetadataProvider) { if (!item.IsInternetMetadataEnabled()) { return false; } if (Array.IndexOf(options.DisabledMetadataFetchers, provider.Name) != -1) { return false; } } } if (!item.SupportsLocalMetadata && provider is ILocalMetadataProvider) { return false; } // If this restriction is ever lifted, movie xml providers will have to be updated to prevent owned items like trailers from reading those files if (checkIsOwnedItem && item.IsOwnedItem) { if (provider is ILocalMetadataProvider || provider is IRemoteMetadataProvider) { return false; } } return true; }
/// <summary> /// Initializes a new instance of the <see cref="ServerConfiguration" /> class. /// </summary> public ServerConfiguration() : base() { MediaEncodingQuality = EncodingQuality.Auto; ImageSavingConvention = ImageSavingConvention.Compatible; HttpServerPortNumber = 8096; LegacyWebSocketPortNumber = 8945; EnableHttpLevelLogging = true; EnableDashboardResponseCaching = true; EnableVideoImageExtraction = true; EnableMovieChapterImageExtraction = true; EnableEpisodeChapterImageExtraction = false; EnableOtherVideoChapterImageExtraction = false; EnableAutomaticRestart = true; MinResumePct = 5; MaxResumePct = 90; MinResumeDurationSeconds = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalSeconds); FileWatcherDelay = 8; RecentItemDays = 10; EnableInternetProviders = true; //initial installs will need these ManualLoginClients = new ManualLoginCategory[] { }; MetadataRefreshDays = 30; PreferredMetadataLanguage = "en"; MetadataCountryCode = "US"; DownloadMovieImages = new ImageDownloadOptions(); DownloadSeriesImages = new ImageDownloadOptions(); DownloadSeasonImages = new ImageDownloadOptions { Backdrops = false }; DownloadMusicArtistImages = new ImageDownloadOptions(); DownloadMusicAlbumImages = new ImageDownloadOptions(); SortReplaceCharacters = new[] { ".", "+", "%" }; SortRemoveCharacters = new[] { ",", "&", "-", "{", "}", "'" }; SortRemoveWords = new[] { "the", "a", "an" }; SeasonZeroDisplayName = "Specials"; MovieOptions = new MetadataOptions(); TvOptions = new MetadataOptions(); MusicOptions = new MetadataOptions() { MaxBackdrops = 1 }; GameOptions = new MetadataOptions(); BookOptions = new MetadataOptions { MaxBackdrops = 1 }; LiveTvOptions = new LiveTvOptions(); TvFileOrganizationOptions = new TvFileOrganizationOptions(); }
/// <summary> /// Refreshes from provider. /// </summary> /// <param name="item">The item.</param> /// <param name="provider">The provider.</param> /// <param name="refreshOptions">The refresh options.</param> /// <param name="savedOptions">The saved options.</param> /// <param name="downloadedImages">The downloaded images.</param> /// <param name="result">The result.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> private async Task RefreshFromProvider(IHasImages item, IDynamicImageProvider provider, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, ICollection<ImageType> downloadedImages, RefreshResult result, CancellationToken cancellationToken) { try { var images = provider.GetSupportedImages(item); foreach (var imageType in images) { if (!IsEnabled(savedOptions, imageType, item)) continue; if (!HasImage(item, imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType))) { _logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name); var response = await provider.GetImage(item, imageType, cancellationToken).ConfigureAwait(false); if (response.HasImage) { if (!string.IsNullOrEmpty(response.Path)) { if (response.Protocol == MediaProtocol.Http) { _logger.Debug("Setting image url into item {0}", item.Id); item.SetImage(new ItemImageInfo { Path = response.Path, Type = imageType }, 0); } else { var mimeType = MimeTypes.GetMimeType(response.Path); var stream = _fileSystem.GetFileStream(response.Path, FileMode.Open, FileAccess.Read, FileShare.Read, true); await _providerManager.SaveImage(item, stream, mimeType, imageType, null, response.InternalCacheKey, cancellationToken).ConfigureAwait(false); } } else { var mimeType = "image/" + response.Format.ToString().ToLower(); await _providerManager.SaveImage(item, response.Stream, mimeType, imageType, null, response.InternalCacheKey, cancellationToken).ConfigureAwait(false); } downloadedImages.Add(imageType); result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; } } } } catch (OperationCanceledException) { throw; } catch (Exception ex) { result.ErrorMessage = ex.Message; _logger.ErrorException("Error in {0}", ex, provider.Name); } }