diff options
Diffstat (limited to 'Emby.Server.Implementations/Images')
7 files changed, 559 insertions, 3 deletions
diff --git a/Emby.Server.Implementations/Images/ArtistImageProvider.cs b/Emby.Server.Implementations/Images/ArtistImageProvider.cs new file mode 100644 index 000000000..52896720e --- /dev/null +++ b/Emby.Server.Implementations/Images/ArtistImageProvider.cs @@ -0,0 +1,60 @@ +#pragma warning disable CS1591 + +using System; +using System.Collections.Generic; +using System.Linq; +using Emby.Server.Implementations.Images; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Playlists; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Querying; + +namespace Emby.Server.Implementations.Images +{ + /// <summary> + /// Class ArtistImageProvider. + /// </summary> + public class ArtistImageProvider : BaseDynamicImageProvider<MusicArtist> + { + /// <summary> + /// The library manager. + /// </summary> + private readonly ILibraryManager _libraryManager; + + public ArtistImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) : base(fileSystem, providerManager, applicationPaths, imageProcessor) + { + _libraryManager = libraryManager; + } + + /// <summary> + /// Get children objects used to create an artist image. + /// </summary> + /// <param name="item">The artist used to create the image.</param> + /// <returns>Any relevant children objects.</returns> + protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item) + { + return Array.Empty<BaseItem>(); + + // TODO enable this when BaseDynamicImageProvider objects are configurable + // return _libraryManager.GetItemList(new InternalItemsQuery + // { + // ArtistIds = new[] { item.Id }, + // IncludeItemTypes = new[] { typeof(MusicAlbum).Name }, + // OrderBy = new[] { (ItemSortBy.Random, SortOrder.Ascending) }, + // Limit = 4, + // Recursive = true, + // ImageTypes = new[] { ImageType.Primary }, + // DtoOptions = new DtoOptions(false) + // }); + } + } +} diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs index fd50f156a..57302b506 100644 --- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs @@ -194,7 +194,8 @@ namespace Emby.Server.Implementations.Images return outputPath; } - protected virtual string CreateImage(BaseItem item, + protected virtual string CreateImage( + BaseItem item, IReadOnlyCollection<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, @@ -214,7 +215,12 @@ namespace Emby.Server.Implementations.Images if (imageType == ImageType.Primary) { - if (item is UserView || item is Playlist || item is MusicGenre || item is Genre || item is PhotoAlbum) + if (item is UserView + || item is Playlist + || item is MusicGenre + || item is Genre + || item is PhotoAlbum + || item is MusicArtist) { return CreateSquareCollage(item, itemsWithImages, outputPath); } @@ -225,7 +231,7 @@ namespace Emby.Server.Implementations.Images throw new ArgumentException("Unexpected image type", nameof(imageType)); } - public bool HasChanged(BaseItem item, IDirectoryService directoryServicee) + public bool HasChanged(BaseItem item, IDirectoryService directoryService) { if (!Supports(item)) { @@ -236,6 +242,7 @@ namespace Emby.Server.Implementations.Images { return true; } + if (SupportedImages.Contains(ImageType.Thumb) && HasChanged(item, ImageType.Thumb)) { return true; diff --git a/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs b/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs new file mode 100644 index 000000000..dc8062b45 --- /dev/null +++ b/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs @@ -0,0 +1,100 @@ +#pragma warning disable CS1591 + +using System; +using System.Collections.Generic; +using System.IO; +using Emby.Server.Implementations.Images; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Querying; + +namespace Emby.Server.Implementations.Images +{ + public class CollectionFolderImageProvider : BaseDynamicImageProvider<CollectionFolder> + { + public CollectionFolderImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) : base(fileSystem, providerManager, applicationPaths, imageProcessor) + { + } + + protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item) + { + var view = (CollectionFolder)item; + var viewType = view.CollectionType; + + string[] includeItemTypes; + + if (string.Equals(viewType, CollectionType.Movies)) + { + includeItemTypes = new string[] { "Movie" }; + } + else if (string.Equals(viewType, CollectionType.TvShows)) + { + includeItemTypes = new string[] { "Series" }; + } + else if (string.Equals(viewType, CollectionType.Music)) + { + includeItemTypes = new string[] { "MusicAlbum" }; + } + else if (string.Equals(viewType, CollectionType.Books)) + { + includeItemTypes = new string[] { "Book", "AudioBook" }; + } + else if (string.Equals(viewType, CollectionType.BoxSets)) + { + includeItemTypes = new string[] { "BoxSet" }; + } + else if (string.Equals(viewType, CollectionType.HomeVideos) || string.Equals(viewType, CollectionType.Photos)) + { + includeItemTypes = new string[] { "Video", "Photo" }; + } + else + { + includeItemTypes = new string[] { "Video", "Audio", "Photo", "Movie", "Series" }; + } + + var recursive = !string.Equals(CollectionType.Playlists, viewType, StringComparison.OrdinalIgnoreCase); + + return view.GetItemList(new InternalItemsQuery + { + CollapseBoxSetItems = false, + Recursive = recursive, + DtoOptions = new DtoOptions(false), + ImageTypes = new ImageType[] { ImageType.Primary }, + Limit = 8, + OrderBy = new ValueTuple<string, SortOrder>[] + { + new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) + }, + IncludeItemTypes = includeItemTypes + + }); + } + + protected override bool Supports(BaseItem item) + { + return item is CollectionFolder; + } + + protected override string CreateImage(BaseItem item, IReadOnlyCollection<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + { + var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); + + if (imageType == ImageType.Primary) + { + if (itemsWithImages.Count == 0) + { + return null; + } + + return CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540); + } + + return base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex); + } + } +} diff --git a/Emby.Server.Implementations/Images/DynamicImageProvider.cs b/Emby.Server.Implementations/Images/DynamicImageProvider.cs new file mode 100644 index 000000000..ca0aa4a9f --- /dev/null +++ b/Emby.Server.Implementations/Images/DynamicImageProvider.cs @@ -0,0 +1,131 @@ +#pragma warning disable CS1591 + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Emby.Server.Implementations.Images; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; + +namespace Emby.Server.Implementations.Images +{ + public class DynamicImageProvider : BaseDynamicImageProvider<UserView> + { + private readonly IUserManager _userManager; + + public DynamicImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, IUserManager userManager) + : base(fileSystem, providerManager, applicationPaths, imageProcessor) + { + _userManager = userManager; + } + + protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item) + { + var view = (UserView)item; + + var isUsingCollectionStrip = IsUsingCollectionStrip(view); + var recursive = isUsingCollectionStrip && !new[] { CollectionType.BoxSets, CollectionType.Playlists }.Contains(view.ViewType ?? string.Empty, StringComparer.OrdinalIgnoreCase); + + var result = view.GetItemList(new InternalItemsQuery + { + User = view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null, + CollapseBoxSetItems = false, + Recursive = recursive, + ExcludeItemTypes = new[] { "UserView", "CollectionFolder", "Person" }, + DtoOptions = new DtoOptions(false) + }); + + var items = result.Select(i => + { + if (i is Episode episode) + { + var series = episode.Series; + if (series != null) + { + return series; + } + + return episode; + } + + if (i is Season season) + { + var series = season.Series; + if (series != null) + { + return series; + } + + return season; + } + + if (i is Audio audio) + { + var album = audio.AlbumEntity; + if (album != null && album.HasImage(ImageType.Primary)) + { + return album; + } + } + + return i; + + }).GroupBy(x => x.Id) + .Select(x => x.First()); + + if (isUsingCollectionStrip) + { + return items + .Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)) + .ToList(); + } + + return items + .Where(i => i.HasImage(ImageType.Primary)) + .ToList(); + } + + protected override bool Supports(BaseItem item) + { + if (item is UserView view) + { + return IsUsingCollectionStrip(view); + } + + return false; + } + + private static bool IsUsingCollectionStrip(UserView view) + { + string[] collectionStripViewTypes = + { + CollectionType.Movies, + CollectionType.TvShows, + CollectionType.Playlists + }; + + return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty); + } + + protected override string CreateImage(BaseItem item, IReadOnlyCollection<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + { + if (itemsWithImages.Count == 0) + { + return null; + } + + var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); + + return CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540); + } + } +} diff --git a/Emby.Server.Implementations/Images/FolderImageProvider.cs b/Emby.Server.Implementations/Images/FolderImageProvider.cs new file mode 100644 index 000000000..e9523386e --- /dev/null +++ b/Emby.Server.Implementations/Images/FolderImageProvider.cs @@ -0,0 +1,104 @@ +#pragma warning disable CS1591 + +using System.Collections.Generic; +using Emby.Server.Implementations.Images; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Querying; + +namespace Emby.Server.Implementations.Images +{ + public abstract class BaseFolderImageProvider<T> : BaseDynamicImageProvider<T> + where T : Folder, new() + { + protected ILibraryManager _libraryManager; + + public BaseFolderImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) + : base(fileSystem, providerManager, applicationPaths, imageProcessor) + { + _libraryManager = libraryManager; + } + + protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item) + { + return _libraryManager.GetItemList(new InternalItemsQuery + { + Parent = item, + DtoOptions = new DtoOptions(true), + ImageTypes = new ImageType[] { ImageType.Primary }, + OrderBy = new System.ValueTuple<string, SortOrder>[] + { + new System.ValueTuple<string, SortOrder>(ItemSortBy.IsFolder, SortOrder.Ascending), + new System.ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) + }, + Limit = 1 + }); + } + + protected override string CreateImage(BaseItem item, IReadOnlyCollection<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + { + return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); + } + + protected override bool Supports(BaseItem item) + { + return item is T; + } + + protected override bool HasChangedByDate(BaseItem item, ItemImageInfo image) + { + if (item is MusicAlbum) + { + return false; + } + + return base.HasChangedByDate(item, image); + } + } + + public class FolderImageProvider : BaseFolderImageProvider<Folder> + { + public FolderImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) + : base(fileSystem, providerManager, applicationPaths, imageProcessor, libraryManager) + { + } + + protected override bool Supports(BaseItem item) + { + if (item is PhotoAlbum || item is MusicAlbum) + { + return false; + } + + if (item is Folder && item.IsTopParent) + { + return false; + } + + return true; + } + } + + public class MusicAlbumImageProvider : BaseFolderImageProvider<MusicAlbum> + { + public MusicAlbumImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) + : base(fileSystem, providerManager, applicationPaths, imageProcessor, libraryManager) + { + } + } + + public class PhotoAlbumImageProvider : BaseFolderImageProvider<PhotoAlbum> + { + public PhotoAlbumImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) + : base(fileSystem, providerManager, applicationPaths, imageProcessor, libraryManager) + { + } + } +} diff --git a/Emby.Server.Implementations/Images/GenreImageProvider.cs b/Emby.Server.Implementations/Images/GenreImageProvider.cs new file mode 100644 index 000000000..d2aeccdb2 --- /dev/null +++ b/Emby.Server.Implementations/Images/GenreImageProvider.cs @@ -0,0 +1,88 @@ +#pragma warning disable CS1591 + +using System.Collections.Generic; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Querying; + +namespace Emby.Server.Implementations.Images +{ + /// <summary> + /// Class MusicGenreImageProvider. + /// </summary> + public class MusicGenreImageProvider : BaseDynamicImageProvider<MusicGenre> + { + /// <summary> + /// The library manager. + /// </summary> + private readonly ILibraryManager _libraryManager; + + public MusicGenreImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) : base(fileSystem, providerManager, applicationPaths, imageProcessor) + { + _libraryManager = libraryManager; + } + + /// <summary> + /// Get children objects used to create an music genre image. + /// </summary> + /// <param name="item">The music genre used to create the image.</param> + /// <returns>Any relevant children objects.</returns> + protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item) + { + return _libraryManager.GetItemList(new InternalItemsQuery + { + Genres = new[] { item.Name }, + IncludeItemTypes = new[] { typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Audio).Name }, + OrderBy = new[] { (ItemSortBy.Random, SortOrder.Ascending) }, + Limit = 4, + Recursive = true, + ImageTypes = new[] { ImageType.Primary }, + DtoOptions = new DtoOptions(false) + }); + } + } + + /// <summary> + /// Class GenreImageProvider. + /// </summary> + public class GenreImageProvider : BaseDynamicImageProvider<Genre> + { + /// <summary> + /// The library manager. + /// </summary> + private readonly ILibraryManager _libraryManager; + + public GenreImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) : base(fileSystem, providerManager, applicationPaths, imageProcessor) + { + _libraryManager = libraryManager; + } + + /// <summary> + /// Get children objects used to create an genre image. + /// </summary> + /// <param name="item">The genre used to create the image.</param> + /// <returns>Any relevant children objects.</returns> + protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item) + { + return _libraryManager.GetItemList(new InternalItemsQuery + { + Genres = new[] { item.Name }, + IncludeItemTypes = new[] { typeof(Series).Name, typeof(Movie).Name }, + OrderBy = new[] { (ItemSortBy.Random, SortOrder.Ascending) }, + Limit = 4, + Recursive = true, + ImageTypes = new[] { ImageType.Primary }, + DtoOptions = new DtoOptions(false) + }); + } + } +} diff --git a/Emby.Server.Implementations/Images/PlaylistImageProvider.cs b/Emby.Server.Implementations/Images/PlaylistImageProvider.cs new file mode 100644 index 000000000..0ce1b91e8 --- /dev/null +++ b/Emby.Server.Implementations/Images/PlaylistImageProvider.cs @@ -0,0 +1,66 @@ +#pragma warning disable CS1591 + +using System.Collections.Generic; +using System.Linq; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Playlists; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; + +namespace Emby.Server.Implementations.Images +{ + public class PlaylistImageProvider : BaseDynamicImageProvider<Playlist> + { + public PlaylistImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) : base(fileSystem, providerManager, applicationPaths, imageProcessor) + { + } + + protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item) + { + var playlist = (Playlist)item; + + return playlist.GetManageableItems() + .Select(i => + { + var subItem = i.Item2; + + var episode = subItem as Episode; + + if (episode != null) + { + var series = episode.Series; + if (series != null && series.HasImage(ImageType.Primary)) + { + return series; + } + } + + if (subItem.HasImage(ImageType.Primary)) + { + return subItem; + } + + var parent = subItem.GetOwner() ?? subItem.GetParent(); + + if (parent != null && parent.HasImage(ImageType.Primary)) + { + if (parent is MusicAlbum) + { + return parent; + } + } + + return null; + }) + .Where(i => i != null) + .GroupBy(x => x.Id) + .Select(x => x.First()) + .ToList(); + } + } +} |
