From ad82c9f5e95e2b1f94ba7adda047dbfbc38004ea Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 28 Jan 2014 13:37:01 -0500 Subject: New provider system. Only for people right now --- .../Drawing/ImageProcessor.cs | 12 +- .../Dto/DtoService.cs | 5 + .../Library/ResolverHelper.cs | 6 +- .../Library/UserManager.cs | 7 +- .../Library/Validators/GenresPostScanTask.cs | 1 - .../Library/Validators/PeoplePostScanTask.cs | 10 +- .../LiveTv/ChannelImageProvider.cs | 2 +- .../LiveTv/LiveTvManager.cs | 22 +- .../LiveTv/ProgramImageProvider.cs | 2 +- .../LiveTv/RecordingImageProvider.cs | 2 +- .../MediaBrowser.Server.Implementations.csproj | 2 - .../Providers/ImageSaver.cs | 598 --------------------- .../Providers/ProviderManager.cs | 454 ---------------- 13 files changed, 51 insertions(+), 1072 deletions(-) delete mode 100644 MediaBrowser.Server.Implementations/Providers/ImageSaver.cs delete mode 100644 MediaBrowser.Server.Implementations/Providers/ProviderManager.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index 6378cef52..06a03ba1c 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -388,18 +388,18 @@ namespace MediaBrowser.Server.Implementations.Drawing /// The image. /// The output format. /// ImageFormat. - private ImageFormat GetOutputFormat(Image image, ImageOutputFormat outputFormat) + private System.Drawing.Imaging.ImageFormat GetOutputFormat(Image image, ImageOutputFormat outputFormat) { switch (outputFormat) { case ImageOutputFormat.Bmp: - return ImageFormat.Bmp; + return System.Drawing.Imaging.ImageFormat.Bmp; case ImageOutputFormat.Gif: - return ImageFormat.Gif; + return System.Drawing.Imaging.ImageFormat.Gif; case ImageOutputFormat.Jpg: - return ImageFormat.Jpeg; + return System.Drawing.Imaging.ImageFormat.Jpeg; case ImageOutputFormat.Png: - return ImageFormat.Png; + return System.Drawing.Imaging.ImageFormat.Png; default: return image.RawFormat; } @@ -787,7 +787,7 @@ namespace MediaBrowser.Server.Implementations.Drawing //And then save it in the cache using (var outputStream = _fileSystem.GetFileStream(enhancedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read, false)) { - newImage.Save(ImageFormat.Png, outputStream, 100); + newImage.Save(System.Drawing.Imaging.ImageFormat.Png, outputStream, 100); } } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 7a9735e0e..b427b0c45 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1024,6 +1024,11 @@ namespace MediaBrowser.Server.Implementations.Dto { dto.SpecialFeatureCount = specialFeatureCount; } + + if (fields.Contains(ItemFields.TmdbCollectionName)) + { + dto.TmdbCollectionName = movie.TmdbCollectionName; + } } // Add EpisodeInfo diff --git a/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs b/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs index e32fcd627..4ce5f11d4 100644 --- a/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs +++ b/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs @@ -46,7 +46,7 @@ namespace MediaBrowser.Server.Implementations.Library } // Make sure the item has a name - EnsureName(item); + EnsureName(item, args); item.DontFetchMeta = item.Path.IndexOf("[dontfetchmeta]", StringComparison.OrdinalIgnoreCase) != -1 || item.Parents.Any(i => i.DontFetchMeta); @@ -59,13 +59,13 @@ namespace MediaBrowser.Server.Implementations.Library /// Ensures the name. /// /// The item. - private static void EnsureName(BaseItem item) + private static void EnsureName(BaseItem item, ItemResolveArgs args) { // If the subclass didn't supply a name, add it here if (string.IsNullOrEmpty(item.Name) && !string.IsNullOrEmpty(item.Path)) { //we use our resolve args name here to get the name of the containg folder, not actual video file - item.Name = GetMBName(item.ResolveArgs.FileInfo.Name, (item.ResolveArgs.FileInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory); + item.Name = GetMBName(args.FileInfo.Name, (args.FileInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory); } } diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index d4a74f2b6..ce76dd21b 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; @@ -192,7 +193,11 @@ namespace MediaBrowser.Server.Implementations.Library /// Task. public Task RefreshUsersMetadata(CancellationToken cancellationToken, bool force = false) { - var tasks = Users.Select(user => user.RefreshMetadata(cancellationToken, forceRefresh: force)).ToList(); + var tasks = Users.Select(user => user.RefreshMetadata(new MetadataRefreshOptions + { + ReplaceAllMetadata = force + + }, cancellationToken)).ToList(); return Task.WhenAll(tasks); } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs index b4907a70c..d7add8574 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs @@ -16,7 +16,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Initializes a new instance of the class. /// /// The library manager. - /// The user manager. public GenresPostScanTask(ILibraryManager libraryManager) { _libraryManager = libraryManager; diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs index 0104b2b7e..c8094302c 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs @@ -1,5 +1,6 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; @@ -88,7 +89,14 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var itemByName = _libraryManager.GetPerson(name); - await itemByName.RefreshMetadata(cancellationToken, allowSlowProviders: false).ConfigureAwait(false); + // The only purpose here is to be able to react to image changes without running the people task. + // All other metadata can wait for that. + await itemByName.RefreshMetadata(new MetadataRefreshOptions + { + ImageRefreshMode = MetadataRefreshMode.None, + MetadataRefreshMode = MetadataRefreshMode.None + + }, cancellationToken).ConfigureAwait(false); foreach (var libraryId in counts.Keys) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs index f1e10e175..c1d8d796b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs @@ -116,7 +116,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (response != null) { imageStream = response.Stream; - contentType = response.MimeType; + contentType = "image/" + response.Format.ToString().ToLower(); } } catch (NotImplementedException) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index e256d7da5..9501d2d12 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -9,6 +9,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaInfo; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; @@ -328,7 +329,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv // Set this now so we don't cause additional file system access during provider executions item.ResetResolveArgs(fileInfo); - await item.RefreshMetadata(cancellationToken, forceSave: isNew, resetResolveArgs: false); + await item.RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = isNew, + ResetResolveArgs = false + + }, cancellationToken); return item; } @@ -383,7 +389,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.RunTimeTicks = (info.EndDate - info.StartDate).Ticks; item.StartDate = info.StartDate; - await item.RefreshMetadata(cancellationToken, forceSave: isNew, resetResolveArgs: false); + await item.RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = isNew, + ResetResolveArgs = false + + }, cancellationToken); return item; } @@ -435,7 +446,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.RecordingInfo = info; item.ServiceName = serviceName; - await item.RefreshMetadata(cancellationToken, forceSave: isNew, resetResolveArgs: false); + await item.RefreshMetadata(new MetadataRefreshOptions + { + ForceSave = isNew, + ResetResolveArgs = false + + }, cancellationToken); _libraryManager.RegisterItem((BaseItem)item); diff --git a/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs index 041925cdd..3bf2712d4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs @@ -116,7 +116,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (response != null) { imageStream = response.Stream; - contentType = response.MimeType; + contentType = "image/" + response.Format.ToString().ToLower(); } } catch (NotImplementedException) diff --git a/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs index 9f6ab85a4..ce7c1286b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs @@ -118,7 +118,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (response != null) { imageStream = response.Stream; - contentType = response.MimeType; + contentType = "image/" + response.Format.ToString().ToLower(); } } catch (NotImplementedException) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 314e7a458..a92ec29d5 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -189,8 +189,6 @@ - - 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 -{ - /// - /// Class ImageSaver - /// - public class ImageSaver - { - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - /// - /// The _config - /// - private readonly IServerConfigurationManager _config; - - /// - /// The remote image cache - /// - private readonly FileSystemRepository _remoteImageCache; - /// - /// The _directory watchers - /// - private readonly IDirectoryWatchers _directoryWatchers; - private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; - - /// - /// Initializes a new instance of the class. - /// - /// The config. - /// The directory watchers. - public ImageSaver(IServerConfigurationManager config, IDirectoryWatchers directoryWatchers, IFileSystem fileSystem, ILogger logger) - { - _config = config; - _directoryWatchers = directoryWatchers; - _fileSystem = fileSystem; - _logger = logger; - _remoteImageCache = new FileSystemRepository(config.ApplicationPaths.DownloadedImagesDataPath); - } - - /// - /// Saves the image. - /// - /// The item. - /// The source. - /// Type of the MIME. - /// The type. - /// Index of the image. - /// The source URL. - /// The cancellation token. - /// Task. - /// mimeType - 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); - } - } - } - - /// - /// Saves the image to location. - /// - /// The source. - /// The path. - /// The cancellation token. - /// Task. - 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); - } - } - - /// - /// Gets the save paths. - /// - /// The item. - /// The type. - /// Index of the image. - /// Type of the MIME. - /// if set to true [save locally]. - /// IEnumerable{System.String}. - 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); - } - - /// - /// Gets the current image path. - /// - /// The item. - /// The type. - /// Index of the image. - /// System.String. - /// - /// imageIndex - /// or - /// imageIndex - /// - private string GetCurrentImagePath(IHasImages item, ImageType type, int imageIndex) - { - return item.GetImagePath(type, imageIndex); - } - - /// - /// Sets the image path. - /// - /// The item. - /// The type. - /// Index of the image. - /// The path. - /// The source URL. - /// imageIndex - /// or - /// imageIndex - 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; - } - } - - /// - /// Gets the save path. - /// - /// The item. - /// The type. - /// Index of the image. - /// Type of the MIME. - /// if set to true [save locally]. - /// System.String. - /// - /// imageIndex - /// or - /// imageIndex - /// - 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 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); - } - - /// - /// Gets the compatible save paths. - /// - /// The item. - /// The type. - /// Index of the image. - /// Type of the MIME. - /// IEnumerable{System.String}. - /// imageIndex - 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) }; - } - - /// - /// Gets the save path for item in mixed folder. - /// - /// The item. - /// The type. - /// The image filename. - /// The extension. - /// System.String. - 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 -{ - /// - /// Class ProviderManager - /// - public class ProviderManager : IProviderManager - { - /// - /// The _logger - /// - private readonly ILogger _logger; - - /// - /// The _HTTP client - /// - private readonly IHttpClient _httpClient; - - /// - /// The _directory watchers - /// - private readonly IDirectoryWatchers _directoryWatchers; - - /// - /// Gets or sets the configuration manager. - /// - /// The configuration manager. - private IServerConfigurationManager ConfigurationManager { get; set; } - - /// - /// Gets the list of currently registered metadata prvoiders - /// - /// The metadata providers enumerable. - private BaseMetadataProvider[] MetadataProviders { get; set; } - - private IImageProvider[] ImageProviders { get; set; } - private readonly IFileSystem _fileSystem; - - private readonly IItemRepository _itemRepo; - - /// - /// Initializes a new instance of the class. - /// - /// The HTTP client. - /// The configuration manager. - /// The directory watchers. - /// The log manager. - 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; - } - - /// - /// Adds the metadata providers. - /// - /// The providers. - /// The image providers. - public void AddParts(IEnumerable providers, IEnumerable imageProviders) - { - MetadataProviders = providers.OrderBy(e => e.Priority).ToArray(); - - ImageProviders = imageProviders.OrderByDescending(i => i.Priority).ToArray(); - } - - /// - /// Runs all metadata providers for an entity, and returns true or false indicating if at least one was refreshed and requires persistence - /// - /// The item. - /// The cancellation token. - /// if set to true [force]. - /// if set to true [allow slow providers]. - /// Task{System.Boolean}. - public async Task 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() : - _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; - } - - /// - /// Providers the supports item. - /// - /// The provider. - /// The item. - /// true if XXXX, false otherwise - 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; - } - } - - /// - /// Fetches metadata and returns true or false indicating if any work that requires persistence was done - /// - /// The provider. - /// The item. - /// The provider information. - /// if set to true [force]. - /// The cancellation token. - /// Task{System.Boolean}. - /// item - private async Task 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; - } - } - - /// - /// Saves to library filesystem. - /// - /// The item. - /// The path. - /// The data to save. - /// The cancellation token. - /// Task. - /// - 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); - } - } - - - /// - /// Saves the image. - /// - /// The item. - /// The URL. - /// The resource pool. - /// The type. - /// Index of the image. - /// The cancellation token. - /// Task. - 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); - } - - /// - /// Saves the image. - /// - /// The item. - /// The source. - /// Type of the MIME. - /// The type. - /// Index of the image. - /// The source URL. - /// The cancellation token. - /// Task. - 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); - } - - /// - /// Gets the available remote images. - /// - /// The item. - /// The cancellation token. - /// Name of the provider. - /// The type. - /// Task{IEnumerable{RemoteImageInfo}}. - public async Task> 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); - } - - /// - /// Gets the images. - /// - /// The item. - /// The cancellation token. - /// The i. - /// The preferred language. - /// The type. - /// Task{IEnumerable{RemoteImageInfo}}. - private async Task> 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(); - } - } - - private IEnumerable FilterImages(IEnumerable 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; - } - - /// - /// Gets the supported image providers. - /// - /// The item. - /// IEnumerable{IImageProvider}. - public IEnumerable 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; - } - }); - } - } -} -- cgit v1.2.3