diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-01-28 13:37:01 -0500 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-01-28 13:37:01 -0500 |
| commit | ad82c9f5e95e2b1f94ba7adda047dbfbc38004ea (patch) | |
| tree | 52ab08873cb353faff048edecf8d97d49114b4db /MediaBrowser.Server.Implementations/Providers | |
| parent | d748967c5de99ba20a788c2448b066fc3fc4fecb (diff) | |
New provider system. Only for people right now
Diffstat (limited to 'MediaBrowser.Server.Implementations/Providers')
| -rw-r--r-- | MediaBrowser.Server.Implementations/Providers/ImageSaver.cs | 598 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/Providers/ProviderManager.cs | 454 |
2 files changed, 0 insertions, 1052 deletions
diff --git a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs deleted file mode 100644 index ec797b688..000000000 --- a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs +++ /dev/null @@ -1,598 +0,0 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.Providers -{ - /// <summary> - /// Class ImageSaver - /// </summary> - public class ImageSaver - { - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - /// <summary> - /// The _config - /// </summary> - private readonly IServerConfigurationManager _config; - - /// <summary> - /// The remote image cache - /// </summary> - private readonly FileSystemRepository _remoteImageCache; - /// <summary> - /// The _directory watchers - /// </summary> - private readonly IDirectoryWatchers _directoryWatchers; - private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; - - /// <summary> - /// Initializes a new instance of the <see cref="ImageSaver"/> class. - /// </summary> - /// <param name="config">The config.</param> - /// <param name="directoryWatchers">The directory watchers.</param> - public ImageSaver(IServerConfigurationManager config, IDirectoryWatchers directoryWatchers, IFileSystem fileSystem, ILogger logger) - { - _config = config; - _directoryWatchers = directoryWatchers; - _fileSystem = fileSystem; - _logger = logger; - _remoteImageCache = new FileSystemRepository(config.ApplicationPaths.DownloadedImagesDataPath); - } - - /// <summary> - /// Saves the image. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="source">The source.</param> - /// <param name="mimeType">Type of the MIME.</param> - /// <param name="type">The type.</param> - /// <param name="imageIndex">Index of the image.</param> - /// <param name="sourceUrl">The source URL.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - /// <exception cref="System.ArgumentNullException">mimeType</exception> - public async Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, string sourceUrl, CancellationToken cancellationToken) - { - if (string.IsNullOrEmpty(mimeType)) - { - throw new ArgumentNullException("mimeType"); - } - - var saveLocally = item.IsSaveLocalMetadataEnabled() && item.Parent != null && !(item is Audio); - - if (item is IItemByName || item is User) - { - saveLocally = true; - } - - if (type != ImageType.Primary && item is Episode) - { - saveLocally = false; - } - - var locationType = item.LocationType; - if (locationType == LocationType.Remote || locationType == LocationType.Virtual) - { - saveLocally = false; - - var season = item as Season; - - // If season is virtual under a physical series, save locally if using compatible convention - if (season != null && _config.Configuration.ImageSavingConvention == ImageSavingConvention.Compatible) - { - var series = season.Series; - - if (series != null) - { - var seriesLocationType = series.LocationType; - if (seriesLocationType == LocationType.FileSystem || seriesLocationType == LocationType.Offline) - { - saveLocally = true; - } - } - } - } - - if (type == ImageType.Backdrop && imageIndex == null) - { - imageIndex = item.BackdropImagePaths.Count; - } - else if (type == ImageType.Screenshot && imageIndex == null) - { - var hasScreenshots = (IHasScreenshots)item; - imageIndex = hasScreenshots.ScreenshotImagePaths.Count; - } - - var index = imageIndex ?? 0; - - var paths = GetSavePaths(item, type, imageIndex, mimeType, saveLocally); - - // If there are more than one output paths, the stream will need to be seekable - if (paths.Length > 1 && !source.CanSeek) - { - var memoryStream = new MemoryStream(); - using (source) - { - await source.CopyToAsync(memoryStream).ConfigureAwait(false); - } - memoryStream.Position = 0; - source = memoryStream; - } - - var currentPath = GetCurrentImagePath(item, type, index); - - using (source) - { - var isFirst = true; - - foreach (var path in paths) - { - // Seek back to the beginning - if (!isFirst) - { - source.Position = 0; - } - - await SaveImageToLocation(source, path, cancellationToken).ConfigureAwait(false); - - isFirst = false; - } - } - - // Set the path into the item - SetImagePath(item, type, imageIndex, paths[0], sourceUrl); - - // Delete the current path - if (!string.IsNullOrEmpty(currentPath) && !paths.Contains(currentPath, StringComparer.OrdinalIgnoreCase)) - { - _directoryWatchers.TemporarilyIgnore(currentPath); - - try - { - var currentFile = new FileInfo(currentPath); - - // This will fail if the file is hidden - if (currentFile.Exists) - { - if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) - { - currentFile.Attributes &= ~FileAttributes.Hidden; - } - - currentFile.Delete(); - } - } - finally - { - _directoryWatchers.RemoveTempIgnore(currentPath); - } - } - } - - /// <summary> - /// Saves the image to location. - /// </summary> - /// <param name="source">The source.</param> - /// <param name="path">The path.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - private async Task SaveImageToLocation(Stream source, string path, CancellationToken cancellationToken) - { - _logger.Debug("Saving image to {0}", path); - - var parentFolder = Path.GetDirectoryName(path); - - _directoryWatchers.TemporarilyIgnore(path); - _directoryWatchers.TemporarilyIgnore(parentFolder); - - try - { - Directory.CreateDirectory(Path.GetDirectoryName(path)); - - // If the file is currently hidden we'll have to remove that or the save will fail - var file = new FileInfo(path); - - // This will fail if the file is hidden - if (file.Exists) - { - if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) - { - file.Attributes &= ~FileAttributes.Hidden; - } - } - - using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) - { - await source.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false); - } - } - finally - { - _directoryWatchers.RemoveTempIgnore(path); - _directoryWatchers.RemoveTempIgnore(parentFolder); - } - } - - /// <summary> - /// Gets the save paths. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="type">The type.</param> - /// <param name="imageIndex">Index of the image.</param> - /// <param name="mimeType">Type of the MIME.</param> - /// <param name="saveLocally">if set to <c>true</c> [save locally].</param> - /// <returns>IEnumerable{System.String}.</returns> - private string[] GetSavePaths(BaseItem item, ImageType type, int? imageIndex, string mimeType, bool saveLocally) - { - if (_config.Configuration.ImageSavingConvention == ImageSavingConvention.Legacy || !saveLocally) - { - return new[] { GetStandardSavePath(item, type, imageIndex, mimeType, saveLocally) }; - } - - return GetCompatibleSavePaths(item, type, imageIndex, mimeType); - } - - /// <summary> - /// Gets the current image path. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="type">The type.</param> - /// <param name="imageIndex">Index of the image.</param> - /// <returns>System.String.</returns> - /// <exception cref="System.ArgumentNullException"> - /// imageIndex - /// or - /// imageIndex - /// </exception> - private string GetCurrentImagePath(IHasImages item, ImageType type, int imageIndex) - { - return item.GetImagePath(type, imageIndex); - } - - /// <summary> - /// Sets the image path. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="type">The type.</param> - /// <param name="imageIndex">Index of the image.</param> - /// <param name="path">The path.</param> - /// <param name="sourceUrl">The source URL.</param> - /// <exception cref="System.ArgumentNullException">imageIndex - /// or - /// imageIndex</exception> - private void SetImagePath(BaseItem item, ImageType type, int? imageIndex, string path, string sourceUrl) - { - switch (type) - { - case ImageType.Screenshot: - - if (!imageIndex.HasValue) - { - throw new ArgumentNullException("imageIndex"); - } - - var hasScreenshots = (IHasScreenshots)item; - if (hasScreenshots.ScreenshotImagePaths.Count > imageIndex.Value) - { - hasScreenshots.ScreenshotImagePaths[imageIndex.Value] = path; - } - else if (!hasScreenshots.ScreenshotImagePaths.Contains(path, StringComparer.OrdinalIgnoreCase)) - { - hasScreenshots.ScreenshotImagePaths.Add(path); - } - break; - case ImageType.Backdrop: - if (!imageIndex.HasValue) - { - throw new ArgumentNullException("imageIndex"); - } - if (item.BackdropImagePaths.Count > imageIndex.Value) - { - item.BackdropImagePaths[imageIndex.Value] = path; - } - else if (!item.BackdropImagePaths.Contains(path, StringComparer.OrdinalIgnoreCase)) - { - item.BackdropImagePaths.Add(path); - } - - if (string.IsNullOrEmpty(sourceUrl)) - { - item.RemoveImageSourceForPath(path); - } - else - { - item.AddImageSource(path, sourceUrl); - } - break; - default: - item.SetImagePath(type, path); - break; - } - } - - /// <summary> - /// Gets the save path. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="type">The type.</param> - /// <param name="imageIndex">Index of the image.</param> - /// <param name="mimeType">Type of the MIME.</param> - /// <param name="saveLocally">if set to <c>true</c> [save locally].</param> - /// <returns>System.String.</returns> - /// <exception cref="System.ArgumentNullException"> - /// imageIndex - /// or - /// imageIndex - /// </exception> - private string GetStandardSavePath(BaseItem item, ImageType type, int? imageIndex, string mimeType, bool saveLocally) - { - string filename; - - switch (type) - { - case ImageType.Art: - filename = "clearart"; - break; - case ImageType.Disc: - filename = item is MusicAlbum ? "cdart" : "disc"; - break; - case ImageType.Primary: - filename = item is Episode ? Path.GetFileNameWithoutExtension(item.Path) : "folder"; - break; - case ImageType.Backdrop: - if (!imageIndex.HasValue) - { - throw new ArgumentNullException("imageIndex"); - } - filename = GetBackdropSaveFilename(item.BackdropImagePaths, "backdrop", "backdrop", imageIndex.Value); - break; - case ImageType.Screenshot: - if (!imageIndex.HasValue) - { - throw new ArgumentNullException("imageIndex"); - } - var hasScreenshots = (IHasScreenshots)item; - filename = GetBackdropSaveFilename(hasScreenshots.ScreenshotImagePaths, "screenshot", "screenshot", imageIndex.Value); - break; - default: - filename = type.ToString().ToLower(); - break; - } - - var extension = mimeType.Split('/').Last(); - - if (string.Equals(extension, "jpeg", StringComparison.OrdinalIgnoreCase)) - { - extension = "jpg"; - } - - extension = "." + extension.ToLower(); - - string path = null; - - if (saveLocally) - { - if (item.IsInMixedFolder && !(item is Episode)) - { - path = GetSavePathForItemInMixedFolder(item, type, filename, extension); - } - - if (string.IsNullOrEmpty(path)) - { - path = Path.Combine(item.MetaLocation, filename + extension); - } - } - - // None of the save local conditions passed, so store it in our internal folders - if (string.IsNullOrEmpty(path)) - { - path = _remoteImageCache.GetResourcePath(item.GetType().FullName + item.Id, filename + extension); - } - - return path; - } - - private string GetBackdropSaveFilename(IEnumerable<string> images, string zeroIndexFilename, string numberedIndexPrefix, int index) - { - if (index == 0) - { - return zeroIndexFilename; - } - - var filenames = images.Select(Path.GetFileNameWithoutExtension).ToList(); - - var current = index; - while (filenames.Contains(numberedIndexPrefix + current.ToString(UsCulture), StringComparer.OrdinalIgnoreCase)) - { - current++; - } - - return numberedIndexPrefix + current.ToString(UsCulture); - } - - /// <summary> - /// Gets the compatible save paths. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="type">The type.</param> - /// <param name="imageIndex">Index of the image.</param> - /// <param name="mimeType">Type of the MIME.</param> - /// <returns>IEnumerable{System.String}.</returns> - /// <exception cref="System.ArgumentNullException">imageIndex</exception> - private string[] GetCompatibleSavePaths(BaseItem item, ImageType type, int? imageIndex, string mimeType) - { - var season = item as Season; - - var extension = mimeType.Split('/').Last(); - - if (string.Equals(extension, "jpeg", StringComparison.OrdinalIgnoreCase)) - { - extension = "jpg"; - } - extension = "." + extension.ToLower(); - - // Backdrop paths - if (type == ImageType.Backdrop) - { - if (!imageIndex.HasValue) - { - throw new ArgumentNullException("imageIndex"); - } - - if (imageIndex.Value == 0) - { - if (item.IsInMixedFolder) - { - return new[] { GetSavePathForItemInMixedFolder(item, type, "fanart", extension) }; - } - - if (season != null && item.IndexNumber.HasValue) - { - var seriesFolder = season.SeriesPath; - - var seasonMarker = item.IndexNumber.Value == 0 - ? "-specials" - : item.IndexNumber.Value.ToString("00", UsCulture); - - var imageFilename = "season" + seasonMarker + "-fanart" + extension; - - return new[] { Path.Combine(seriesFolder, imageFilename) }; - } - - return new[] - { - Path.Combine(item.MetaLocation, "fanart" + extension) - }; - } - - var outputIndex = imageIndex.Value; - - if (item.IsInMixedFolder) - { - return new[] { GetSavePathForItemInMixedFolder(item, type, "fanart" + outputIndex.ToString(UsCulture), extension) }; - } - - var extraFanartFilename = GetBackdropSaveFilename(item.BackdropImagePaths, "fanart", "fanart", outputIndex); - - return new[] - { - Path.Combine(item.MetaLocation, "extrafanart", extraFanartFilename + extension), - Path.Combine(item.MetaLocation, "extrathumbs", "thumb" + outputIndex.ToString(UsCulture) + extension) - }; - } - - if (type == ImageType.Primary) - { - if (season != null && item.IndexNumber.HasValue) - { - var seriesFolder = season.SeriesPath; - - var seasonMarker = item.IndexNumber.Value == 0 - ? "-specials" - : item.IndexNumber.Value.ToString("00", UsCulture); - - var imageFilename = "season" + seasonMarker + "-poster" + extension; - - return new[] { Path.Combine(seriesFolder, imageFilename) }; - } - - if (item is Episode) - { - var seasonFolder = Path.GetDirectoryName(item.Path); - - var imageFilename = Path.GetFileNameWithoutExtension(item.Path) + "-thumb" + extension; - - return new[] { Path.Combine(seasonFolder, imageFilename) }; - } - - if (item.IsInMixedFolder || item is MusicVideo) - { - return new[] { GetSavePathForItemInMixedFolder(item, type, string.Empty, extension) }; - } - - if (item is MusicAlbum || item is MusicArtist) - { - return new[] { Path.Combine(item.MetaLocation, "folder" + extension) }; - } - - return new[] { Path.Combine(item.MetaLocation, "poster" + extension) }; - } - - if (type == ImageType.Banner) - { - if (season != null && item.IndexNumber.HasValue) - { - var seriesFolder = season.SeriesPath; - - var seasonMarker = item.IndexNumber.Value == 0 - ? "-specials" - : item.IndexNumber.Value.ToString("00", UsCulture); - - var imageFilename = "season" + seasonMarker + "-banner" + extension; - - return new[] { Path.Combine(seriesFolder, imageFilename) }; - } - } - - if (type == ImageType.Thumb) - { - if (season != null && item.IndexNumber.HasValue) - { - var seriesFolder = season.SeriesPath; - - var seasonMarker = item.IndexNumber.Value == 0 - ? "-specials" - : item.IndexNumber.Value.ToString("00", UsCulture); - - var imageFilename = "season" + seasonMarker + "-landscape" + extension; - - return new[] { Path.Combine(seriesFolder, imageFilename) }; - } - - if (item.IsInMixedFolder) - { - return new[] { GetSavePathForItemInMixedFolder(item, type, "landscape", extension) }; - } - - return new[] { Path.Combine(item.MetaLocation, "landscape" + extension) }; - } - - // All other paths are the same - return new[] { GetStandardSavePath(item, type, imageIndex, mimeType, true) }; - } - - /// <summary> - /// Gets the save path for item in mixed folder. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="type">The type.</param> - /// <param name="imageFilename">The image filename.</param> - /// <param name="extension">The extension.</param> - /// <returns>System.String.</returns> - private string GetSavePathForItemInMixedFolder(IHasImages item, ImageType type, string imageFilename, string extension) - { - if (type == ImageType.Primary) - { - imageFilename = "poster"; - } - var folder = Path.GetDirectoryName(item.Path); - - return Path.Combine(folder, Path.GetFileNameWithoutExtension(item.Path) + "-" + imageFilename + extension); - } - } -} diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs deleted file mode 100644 index cbfd7d74d..000000000 --- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs +++ /dev/null @@ -1,454 +0,0 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.IO; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Persistence; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Providers; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.Providers -{ - /// <summary> - /// Class ProviderManager - /// </summary> - public class ProviderManager : IProviderManager - { - /// <summary> - /// The _logger - /// </summary> - private readonly ILogger _logger; - - /// <summary> - /// The _HTTP client - /// </summary> - private readonly IHttpClient _httpClient; - - /// <summary> - /// The _directory watchers - /// </summary> - private readonly IDirectoryWatchers _directoryWatchers; - - /// <summary> - /// Gets or sets the configuration manager. - /// </summary> - /// <value>The configuration manager.</value> - private IServerConfigurationManager ConfigurationManager { get; set; } - - /// <summary> - /// Gets the list of currently registered metadata prvoiders - /// </summary> - /// <value>The metadata providers enumerable.</value> - private BaseMetadataProvider[] MetadataProviders { get; set; } - - private IImageProvider[] ImageProviders { get; set; } - private readonly IFileSystem _fileSystem; - - private readonly IItemRepository _itemRepo; - - /// <summary> - /// Initializes a new instance of the <see cref="ProviderManager" /> class. - /// </summary> - /// <param name="httpClient">The HTTP client.</param> - /// <param name="configurationManager">The configuration manager.</param> - /// <param name="directoryWatchers">The directory watchers.</param> - /// <param name="logManager">The log manager.</param> - public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, IDirectoryWatchers directoryWatchers, ILogManager logManager, IFileSystem fileSystem, IItemRepository itemRepo) - { - _logger = logManager.GetLogger("ProviderManager"); - _httpClient = httpClient; - ConfigurationManager = configurationManager; - _directoryWatchers = directoryWatchers; - _fileSystem = fileSystem; - _itemRepo = itemRepo; - } - - /// <summary> - /// Adds the metadata providers. - /// </summary> - /// <param name="providers">The providers.</param> - /// <param name="imageProviders">The image providers.</param> - public void AddParts(IEnumerable<BaseMetadataProvider> providers, IEnumerable<IImageProvider> imageProviders) - { - MetadataProviders = providers.OrderBy(e => e.Priority).ToArray(); - - ImageProviders = imageProviders.OrderByDescending(i => i.Priority).ToArray(); - } - - /// <summary> - /// Runs all metadata providers for an entity, and returns true or false indicating if at least one was refreshed and requires persistence - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <param name="force">if set to <c>true</c> [force].</param> - /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param> - /// <returns>Task{System.Boolean}.</returns> - public async Task<ItemUpdateType?> ExecuteMetadataProviders(BaseItem item, CancellationToken cancellationToken, bool force = false, bool allowSlowProviders = true) - { - if (item == null) - { - throw new ArgumentNullException("item"); - } - - ItemUpdateType? result = null; - - cancellationToken.ThrowIfCancellationRequested(); - - var enableInternetProviders = ConfigurationManager.Configuration.EnableInternetProviders; - - var providerHistories = item.DateLastSaved == default(DateTime) ? - new List<BaseProviderInfo>() : - _itemRepo.GetProviderHistory(item.Id).ToList(); - - // Run the normal providers sequentially in order of priority - foreach (var provider in MetadataProviders) - { - cancellationToken.ThrowIfCancellationRequested(); - - if (!ProviderSupportsItem(provider, item)) - { - continue; - } - - // Skip if internet providers are currently disabled - if (provider.RequiresInternet && !enableInternetProviders) - { - continue; - } - - // Skip if is slow and we aren't allowing slow ones - if (provider.IsSlow && !allowSlowProviders) - { - continue; - } - - // Put this check below the await because the needs refresh of the next tier of providers may depend on the previous ones running - // This is the case for the fan art provider which depends on the movie and tv providers having run before them - if (provider.RequiresInternet && item.DontFetchMeta && provider.EnforceDontFetchMetadata) - { - continue; - } - - var providerInfo = providerHistories.FirstOrDefault(i => i.ProviderId == provider.Id); - - if (providerInfo == null) - { - providerInfo = new BaseProviderInfo - { - ProviderId = provider.Id - }; - providerHistories.Add(providerInfo); - } - - try - { - if (!force && !provider.NeedsRefresh(item, providerInfo)) - { - continue; - } - } - catch (Exception ex) - { - _logger.Error("Error determining NeedsRefresh for {0}", ex, item.Path); - } - - var updateType = await FetchAsync(provider, item, providerInfo, force, cancellationToken).ConfigureAwait(false); - - if (updateType.HasValue) - { - if (result.HasValue) - { - result = result.Value | updateType.Value; - } - else - { - result = updateType; - } - } - } - - if (result.HasValue || force) - { - await _itemRepo.SaveProviderHistory(item.Id, providerHistories, cancellationToken); - } - - return result; - } - - /// <summary> - /// Providers the supports item. - /// </summary> - /// <param name="provider">The provider.</param> - /// <param name="item">The item.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private bool ProviderSupportsItem(BaseMetadataProvider provider, BaseItem item) - { - try - { - return provider.Supports(item); - } - catch (Exception ex) - { - _logger.ErrorException("{0} failed in Supports for type {1}", ex, provider.GetType().Name, item.GetType().Name); - return false; - } - } - - /// <summary> - /// Fetches metadata and returns true or false indicating if any work that requires persistence was done - /// </summary> - /// <param name="provider">The provider.</param> - /// <param name="item">The item.</param> - /// <param name="providerInfo">The provider information.</param> - /// <param name="force">if set to <c>true</c> [force].</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{System.Boolean}.</returns> - /// <exception cref="System.ArgumentNullException">item</exception> - private async Task<ItemUpdateType?> FetchAsync(BaseMetadataProvider provider, BaseItem item, BaseProviderInfo providerInfo, bool force, CancellationToken cancellationToken) - { - if (item == null) - { - throw new ArgumentNullException("item"); - } - - cancellationToken.ThrowIfCancellationRequested(); - - // Don't clog up the log with these providers - if (!(provider is IDynamicInfoProvider)) - { - _logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name ?? "--Unknown--"); - } - - try - { - var changed = await provider.FetchAsync(item, force, providerInfo, cancellationToken).ConfigureAwait(false); - - if (changed) - { - return provider.ItemUpdateType; - } - - return null; - } - catch (OperationCanceledException ex) - { - _logger.Debug("{0} canceled for {1}", provider.GetType().Name, item.Name); - - // If the outer cancellation token is the one that caused the cancellation, throw it - if (cancellationToken.IsCancellationRequested && ex.CancellationToken == cancellationToken) - { - throw; - } - - return null; - } - catch (Exception ex) - { - _logger.ErrorException("{0} failed refreshing {1} {2}", ex, provider.GetType().Name, item.Name, item.Path ?? string.Empty); - - provider.SetLastRefreshed(item, DateTime.UtcNow, providerInfo, ProviderRefreshStatus.Failure); - - return ItemUpdateType.Unspecified; - } - } - - /// <summary> - /// Saves to library filesystem. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="path">The path.</param> - /// <param name="dataToSave">The data to save.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - /// <exception cref="System.ArgumentNullException"></exception> - public async Task SaveToLibraryFilesystem(BaseItem item, string path, Stream dataToSave, CancellationToken cancellationToken) - { - if (item == null) - { - throw new ArgumentNullException(); - } - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentNullException(); - } - if (dataToSave == null) - { - throw new ArgumentNullException(); - } - - if (cancellationToken.IsCancellationRequested) - { - dataToSave.Dispose(); - cancellationToken.ThrowIfCancellationRequested(); - } - - //Tell the watchers to ignore - _directoryWatchers.TemporarilyIgnore(path); - - if (dataToSave.CanSeek) - { - dataToSave.Position = 0; - } - - try - { - using (dataToSave) - { - using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) - { - await dataToSave.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false); - } - } - - // If this is ever used for something other than metadata we can add a file type param - item.ResolveArgs.AddMetadataFile(path); - } - finally - { - //Remove the ignore - _directoryWatchers.RemoveTempIgnore(path); - } - } - - - /// <summary> - /// Saves the image. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="url">The URL.</param> - /// <param name="resourcePool">The resource pool.</param> - /// <param name="type">The type.</param> - /// <param name="imageIndex">Index of the image.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - public async Task SaveImage(BaseItem item, string url, SemaphoreSlim resourcePool, ImageType type, int? imageIndex, CancellationToken cancellationToken) - { - var response = await _httpClient.GetResponse(new HttpRequestOptions - { - CancellationToken = cancellationToken, - ResourcePool = resourcePool, - Url = url - - }).ConfigureAwait(false); - - await SaveImage(item, response.Content, response.ContentType, type, imageIndex, url, cancellationToken) - .ConfigureAwait(false); - } - - /// <summary> - /// Saves the image. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="source">The source.</param> - /// <param name="mimeType">Type of the MIME.</param> - /// <param name="type">The type.</param> - /// <param name="imageIndex">Index of the image.</param> - /// <param name="sourceUrl">The source URL.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, string sourceUrl, CancellationToken cancellationToken) - { - return new ImageSaver(ConfigurationManager, _directoryWatchers, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, sourceUrl, cancellationToken); - } - - /// <summary> - /// Gets the available remote images. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <param name="providerName">Name of the provider.</param> - /// <param name="type">The type.</param> - /// <returns>Task{IEnumerable{RemoteImageInfo}}.</returns> - public async Task<IEnumerable<RemoteImageInfo>> GetAvailableRemoteImages(BaseItem item, CancellationToken cancellationToken, string providerName = null, ImageType? type = null) - { - var providers = GetImageProviders(item); - - if (!string.IsNullOrEmpty(providerName)) - { - providers = providers.Where(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase)); - } - - var preferredLanguage = item.GetPreferredMetadataLanguage(); - - var tasks = providers.Select(i => GetImages(item, cancellationToken, i, preferredLanguage, type)); - - var results = await Task.WhenAll(tasks).ConfigureAwait(false); - - return results.SelectMany(i => i); - } - - /// <summary> - /// Gets the images. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <param name="i">The i.</param> - /// <param name="preferredLanguage">The preferred language.</param> - /// <param name="type">The type.</param> - /// <returns>Task{IEnumerable{RemoteImageInfo}}.</returns> - private async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken, IImageProvider i, string preferredLanguage, ImageType? type = null) - { - try - { - if (type.HasValue) - { - var result = await i.GetImages(item, type.Value, cancellationToken).ConfigureAwait(false); - - return FilterImages(result, preferredLanguage); - } - else - { - var result = await i.GetAllImages(item, cancellationToken).ConfigureAwait(false); - return FilterImages(result, preferredLanguage); - } - } - catch (Exception ex) - { - _logger.ErrorException("{0} failed in GetImages for type {1}", ex, i.GetType().Name, item.GetType().Name); - return new List<RemoteImageInfo>(); - } - } - - private IEnumerable<RemoteImageInfo> FilterImages(IEnumerable<RemoteImageInfo> images, string preferredLanguage) - { - if (string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase)) - { - images = images.Where(i => string.IsNullOrEmpty(i.Language) || - string.Equals(i.Language, "en", StringComparison.OrdinalIgnoreCase)); - } - - return images; - } - - /// <summary> - /// Gets the supported image providers. - /// </summary> - /// <param name="item">The item.</param> - /// <returns>IEnumerable{IImageProvider}.</returns> - public IEnumerable<IImageProvider> GetImageProviders(BaseItem item) - { - return ImageProviders.Where(i => - { - try - { - return i.Supports(item); - } - catch (Exception ex) - { - _logger.ErrorException("{0} failed in Supports for type {1}", ex, i.GetType().Name, item.GetType().Name); - return false; - } - }); - } - } -} |
