repo creation with initial code after cloning public repo
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
namespace Emby.Server.Implementations.Images
|
||||
{
|
||||
/// <summary>
|
||||
/// Class ArtistImageProvider.
|
||||
/// </summary>
|
||||
public class ArtistImageProvider : BaseDynamicImageProvider<MusicArtist>
|
||||
{
|
||||
public ArtistImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor)
|
||||
: base(fileSystem, providerManager, applicationPaths, imageProcessor)
|
||||
{
|
||||
}
|
||||
|
||||
/// <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[] { nameof(MusicAlbum) },
|
||||
// OrderBy = new[] { (ItemSortBy.Random, SortOrder.Ascending) },
|
||||
// Limit = 4,
|
||||
// Recursive = true,
|
||||
// ImageTypes = new[] { ImageType.Primary },
|
||||
// DtoOptions = new DtoOptions(false)
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Playlists;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Net;
|
||||
|
||||
namespace Emby.Server.Implementations.Images
|
||||
{
|
||||
public abstract class BaseDynamicImageProvider<T> : IHasItemChangeMonitor, IForcedProvider, ICustomMetadataProvider<T>, IHasOrder
|
||||
where T : BaseItem
|
||||
{
|
||||
protected BaseDynamicImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor)
|
||||
{
|
||||
ApplicationPaths = applicationPaths;
|
||||
ProviderManager = providerManager;
|
||||
FileSystem = fileSystem;
|
||||
ImageProcessor = imageProcessor;
|
||||
}
|
||||
|
||||
protected IFileSystem FileSystem { get; }
|
||||
|
||||
protected IProviderManager ProviderManager { get; }
|
||||
|
||||
protected IApplicationPaths ApplicationPaths { get; }
|
||||
|
||||
protected IImageProcessor ImageProcessor { get; set; }
|
||||
|
||||
protected virtual IReadOnlyCollection<ImageType> SupportedImages { get; }
|
||||
= [ImageType.Primary];
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Dynamic Image Provider";
|
||||
|
||||
public int Order => 0;
|
||||
|
||||
protected virtual bool Supports(BaseItem item) => true;
|
||||
|
||||
public async Task<ItemUpdateType> FetchAsync(T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!Supports(item))
|
||||
{
|
||||
return ItemUpdateType.None;
|
||||
}
|
||||
|
||||
var updateType = ItemUpdateType.None;
|
||||
|
||||
if (SupportedImages.Contains(ImageType.Primary))
|
||||
{
|
||||
var primaryResult = await FetchAsync(item, ImageType.Primary, options, cancellationToken).ConfigureAwait(false);
|
||||
updateType |= primaryResult;
|
||||
}
|
||||
|
||||
if (SupportedImages.Contains(ImageType.Thumb))
|
||||
{
|
||||
var thumbResult = await FetchAsync(item, ImageType.Thumb, options, cancellationToken).ConfigureAwait(false);
|
||||
updateType |= thumbResult;
|
||||
}
|
||||
|
||||
return updateType;
|
||||
}
|
||||
|
||||
protected Task<ItemUpdateType> FetchAsync(BaseItem item, ImageType imageType, MetadataRefreshOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
var image = item.GetImageInfo(imageType, 0);
|
||||
|
||||
if (image is not null)
|
||||
{
|
||||
if (!image.IsLocalFile)
|
||||
{
|
||||
return Task.FromResult(ItemUpdateType.None);
|
||||
}
|
||||
|
||||
if (!FileSystem.ContainsSubPath(item.GetInternalMetadataPath(), image.Path))
|
||||
{
|
||||
return Task.FromResult(ItemUpdateType.None);
|
||||
}
|
||||
}
|
||||
|
||||
var items = GetItemsWithImages(item);
|
||||
|
||||
return FetchToFileInternal(item, items, imageType, cancellationToken);
|
||||
}
|
||||
|
||||
protected async Task<ItemUpdateType> FetchToFileInternal(
|
||||
BaseItem item,
|
||||
IReadOnlyList<BaseItem> itemsWithImages,
|
||||
ImageType imageType,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var outputPathWithoutExtension = Path.Combine(ApplicationPaths.TempDirectory, Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outputPathWithoutExtension));
|
||||
string outputPath = CreateImage(item, itemsWithImages, outputPathWithoutExtension, imageType, 0);
|
||||
|
||||
if (string.IsNullOrEmpty(outputPath))
|
||||
{
|
||||
return ItemUpdateType.None;
|
||||
}
|
||||
|
||||
var mimeType = MimeTypes.GetMimeType(outputPath);
|
||||
|
||||
if (string.Equals(mimeType, MediaTypeNames.Application.Octet, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mimeType = MediaTypeNames.Image.Png;
|
||||
}
|
||||
|
||||
await ProviderManager.SaveImage(item, outputPath, mimeType, imageType, null, false, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return ItemUpdateType.ImageUpdate;
|
||||
}
|
||||
|
||||
protected abstract IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item);
|
||||
|
||||
protected string CreateThumbCollage(BaseItem primaryItem, IEnumerable<BaseItem> items, string outputPath)
|
||||
{
|
||||
return CreateCollage(primaryItem, items, outputPath, 640, 360);
|
||||
}
|
||||
|
||||
protected virtual IEnumerable<string> GetStripCollageImagePaths(BaseItem primaryItem, IEnumerable<BaseItem> items)
|
||||
{
|
||||
var useBackdrop = primaryItem is CollectionFolder || primaryItem is UserView;
|
||||
return items
|
||||
.Select(i =>
|
||||
{
|
||||
// Use Backdrop instead of Primary image for Library images.
|
||||
if (useBackdrop)
|
||||
{
|
||||
var backdrop = i.GetImageInfo(ImageType.Backdrop, 0);
|
||||
if (backdrop is not null && backdrop.IsLocalFile)
|
||||
{
|
||||
return backdrop.Path;
|
||||
}
|
||||
}
|
||||
|
||||
var image = i.GetImageInfo(ImageType.Primary, 0);
|
||||
if (image is not null && image.IsLocalFile)
|
||||
{
|
||||
return image.Path;
|
||||
}
|
||||
|
||||
image = i.GetImageInfo(ImageType.Thumb, 0);
|
||||
if (image is not null && image.IsLocalFile)
|
||||
{
|
||||
return image.Path;
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.Where(i => !string.IsNullOrEmpty(i));
|
||||
}
|
||||
|
||||
protected string CreatePosterCollage(BaseItem primaryItem, IEnumerable<BaseItem> items, string outputPath)
|
||||
{
|
||||
return CreateCollage(primaryItem, items, outputPath, 400, 600);
|
||||
}
|
||||
|
||||
protected string CreateSquareCollage(BaseItem primaryItem, IEnumerable<BaseItem> items, string outputPath)
|
||||
{
|
||||
return CreateCollage(primaryItem, items, outputPath, 600, 600);
|
||||
}
|
||||
|
||||
protected string CreateThumbCollage(BaseItem primaryItem, IEnumerable<BaseItem> items, string outputPath, int width, int height)
|
||||
{
|
||||
return CreateCollage(primaryItem, items, outputPath, width, height);
|
||||
}
|
||||
|
||||
private string CreateCollage(BaseItem primaryItem, IEnumerable<BaseItem> items, string outputPath, int width, int height)
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
|
||||
|
||||
var options = new ImageCollageOptions
|
||||
{
|
||||
Height = height,
|
||||
Width = width,
|
||||
OutputPath = outputPath,
|
||||
InputPaths = GetStripCollageImagePaths(primaryItem, items).ToArray()
|
||||
};
|
||||
|
||||
if (options.InputPaths.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!ImageProcessor.SupportsImageCollageCreation)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ImageProcessor.CreateImageCollage(options, primaryItem.Name);
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
protected virtual string CreateImage(
|
||||
BaseItem item,
|
||||
IReadOnlyCollection<BaseItem> itemsWithImages,
|
||||
string outputPathWithoutExtension,
|
||||
ImageType imageType,
|
||||
int imageIndex)
|
||||
{
|
||||
if (itemsWithImages.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png");
|
||||
|
||||
if (imageType == ImageType.Thumb)
|
||||
{
|
||||
return CreateThumbCollage(item, itemsWithImages, outputPath);
|
||||
}
|
||||
|
||||
if (imageType == ImageType.Primary)
|
||||
{
|
||||
if (item is UserView
|
||||
|| item is Playlist
|
||||
|| item is MusicGenre
|
||||
|| item is Genre
|
||||
|| item is PhotoAlbum
|
||||
|| item is MusicArtist)
|
||||
{
|
||||
return CreateSquareCollage(item, itemsWithImages, outputPath);
|
||||
}
|
||||
|
||||
return CreatePosterCollage(item, itemsWithImages, outputPath);
|
||||
}
|
||||
|
||||
throw new ArgumentException("Unexpected image type", nameof(imageType));
|
||||
}
|
||||
|
||||
public bool HasChanged(BaseItem item, IDirectoryService directoryService)
|
||||
{
|
||||
if (!Supports(item))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SupportedImages.Contains(ImageType.Primary) && HasChanged(item, ImageType.Primary))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SupportedImages.Contains(ImageType.Thumb) && HasChanged(item, ImageType.Thumb))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected bool HasChanged(BaseItem item, ImageType type)
|
||||
{
|
||||
var image = item.GetImageInfo(type, 0);
|
||||
|
||||
if (image is null)
|
||||
{
|
||||
return GetItemsWithImages(item).Count is not 0;
|
||||
}
|
||||
|
||||
if (!image.IsLocalFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FileSystem.ContainsSubPath(item.GetInternalMetadataPath(), image.Path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasChangedByDate(item, image))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual bool HasChangedByDate(BaseItem item, ItemImageInfo image)
|
||||
{
|
||||
var path = image.Path;
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
var modificationDate = FileSystem.GetLastWriteTimeUtc(path);
|
||||
return image.DateModified != modificationDate;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected string CreateSingleImage(IEnumerable<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType)
|
||||
{
|
||||
var image = itemsWithImages
|
||||
.Where(i => i.HasImage(imageType) && i.GetImageInfo(imageType, 0).IsLocalFile && Path.HasExtension(i.GetImagePath(imageType)))
|
||||
.Select(i => i.GetImagePath(imageType))
|
||||
.FirstOrDefault();
|
||||
|
||||
if (string.IsNullOrEmpty(image))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(image);
|
||||
|
||||
var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ext);
|
||||
File.Copy(image, outputPath, true);
|
||||
|
||||
return outputPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Database.Implementations.Enums;
|
||||
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;
|
||||
|
||||
namespace Emby.Server.Implementations.Images
|
||||
{
|
||||
public abstract class BaseFolderImageProvider<T> : BaseDynamicImageProvider<T>
|
||||
where T : Folder, new()
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
protected 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,
|
||||
Recursive = true,
|
||||
DtoOptions = new DtoOptions(true),
|
||||
ImageTypes = [ImageType.Primary],
|
||||
OrderBy =
|
||||
[
|
||||
(ItemSortBy.IsFolder, SortOrder.Ascending),
|
||||
(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Database.Implementations.Enums;
|
||||
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;
|
||||
|
||||
BaseItemKind[] includeItemTypes;
|
||||
|
||||
switch (viewType)
|
||||
{
|
||||
case CollectionType.movies:
|
||||
includeItemTypes = new[] { BaseItemKind.Movie };
|
||||
break;
|
||||
case CollectionType.tvshows:
|
||||
includeItemTypes = new[] { BaseItemKind.Series };
|
||||
break;
|
||||
case CollectionType.music:
|
||||
includeItemTypes = new[] { BaseItemKind.MusicAlbum };
|
||||
break;
|
||||
case CollectionType.musicvideos:
|
||||
includeItemTypes = new[] { BaseItemKind.MusicVideo };
|
||||
break;
|
||||
case CollectionType.books:
|
||||
includeItemTypes = new[] { BaseItemKind.Book, BaseItemKind.AudioBook };
|
||||
break;
|
||||
case CollectionType.boxsets:
|
||||
includeItemTypes = new[] { BaseItemKind.BoxSet };
|
||||
break;
|
||||
case CollectionType.homevideos:
|
||||
case CollectionType.photos:
|
||||
includeItemTypes = new[] { BaseItemKind.Video, BaseItemKind.Photo };
|
||||
break;
|
||||
default:
|
||||
includeItemTypes = new[] { BaseItemKind.Video, BaseItemKind.Audio, BaseItemKind.Photo, BaseItemKind.Movie, BaseItemKind.Series };
|
||||
break;
|
||||
}
|
||||
|
||||
var recursive = viewType != CollectionType.playlists;
|
||||
|
||||
return view.GetItemList(new InternalItemsQuery
|
||||
{
|
||||
CollapseBoxSetItems = false,
|
||||
Recursive = recursive,
|
||||
DtoOptions = new DtoOptions(false),
|
||||
ImageTypes = new[] { ImageType.Primary },
|
||||
Limit = 8,
|
||||
OrderBy = new[]
|
||||
{
|
||||
(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);
|
||||
}
|
||||
|
||||
protected override bool HasChangedByDate(BaseItem item, ItemImageInfo image)
|
||||
{
|
||||
var age = DateTime.UtcNow - image.DateModified;
|
||||
return age.TotalDays > 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions;
|
||||
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 && view?.ViewType is not null && view.ViewType != CollectionType.boxsets && view.ViewType != CollectionType.playlists;
|
||||
|
||||
var result = view.GetItemList(new InternalItemsQuery
|
||||
{
|
||||
User = view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null,
|
||||
CollapseBoxSetItems = false,
|
||||
Recursive = recursive,
|
||||
ExcludeItemTypes = new[] { BaseItemKind.UserView, BaseItemKind.CollectionFolder, BaseItemKind.Person },
|
||||
DtoOptions = new DtoOptions(false)
|
||||
});
|
||||
|
||||
var items = result.Select(i =>
|
||||
{
|
||||
if (i is Episode episode)
|
||||
{
|
||||
var series = episode.Series;
|
||||
if (series is not null)
|
||||
{
|
||||
return series;
|
||||
}
|
||||
|
||||
return episode;
|
||||
}
|
||||
|
||||
if (i is Season season)
|
||||
{
|
||||
var series = season.Series;
|
||||
if (series is not null)
|
||||
{
|
||||
return series;
|
||||
}
|
||||
|
||||
return season;
|
||||
}
|
||||
|
||||
if (i is Audio audio)
|
||||
{
|
||||
var album = audio.AlbumEntity;
|
||||
if (album is not null && album.HasImage(ImageType.Primary))
|
||||
{
|
||||
return album;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}).DistinctBy(x => x.Id);
|
||||
|
||||
List<BaseItem> returnItems;
|
||||
if (isUsingCollectionStrip)
|
||||
{
|
||||
returnItems = items
|
||||
.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb))
|
||||
.ToList();
|
||||
returnItems.Shuffle();
|
||||
return returnItems;
|
||||
}
|
||||
|
||||
returnItems = items
|
||||
.Where(i => i.HasImage(ImageType.Primary))
|
||||
.ToList();
|
||||
returnItems.Shuffle();
|
||||
return returnItems;
|
||||
}
|
||||
|
||||
protected override bool Supports(BaseItem item)
|
||||
{
|
||||
if (item is UserView view)
|
||||
{
|
||||
return IsUsingCollectionStrip(view);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsUsingCollectionStrip(UserView view)
|
||||
{
|
||||
CollectionType[] collectionStripViewTypes =
|
||||
{
|
||||
CollectionType.movies,
|
||||
CollectionType.tvshows,
|
||||
CollectionType.playlists
|
||||
};
|
||||
|
||||
return view?.ViewType is not null && collectionStripViewTypes.Contains(view.ViewType.Value);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
namespace Emby.Server.Implementations.Images
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Database.Implementations.Enums;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
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 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[] { BaseItemKind.Series, BaseItemKind.Movie },
|
||||
OrderBy = new[] { (ItemSortBy.Random, SortOrder.Ascending) },
|
||||
Limit = 4,
|
||||
Recursive = true,
|
||||
ImageTypes = new[] { ImageType.Primary },
|
||||
DtoOptions = new DtoOptions(false)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#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.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
namespace Emby.Server.Implementations.Images
|
||||
{
|
||||
public class MusicAlbumImageProvider : BaseFolderImageProvider<MusicAlbum>
|
||||
{
|
||||
public MusicAlbumImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager)
|
||||
: base(fileSystem, providerManager, applicationPaths, imageProcessor, libraryManager)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item)
|
||||
{
|
||||
var items = base.GetItemsWithImages(item);
|
||||
|
||||
// Ignore any folders because they can have generated collages
|
||||
return items.Where(i => i is not Folder).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Database.Implementations.Enums;
|
||||
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
|
||||
{
|
||||
/// <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[]
|
||||
{
|
||||
BaseItemKind.MusicAlbum,
|
||||
BaseItemKind.MusicVideo,
|
||||
BaseItemKind.Audio
|
||||
},
|
||||
OrderBy = new[] { (ItemSortBy.Random, SortOrder.Ascending) },
|
||||
Limit = 4,
|
||||
Recursive = true,
|
||||
ImageTypes = new[] { ImageType.Primary },
|
||||
DtoOptions = new DtoOptions(false)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
namespace Emby.Server.Implementations.Images
|
||||
{
|
||||
public class PhotoAlbumImageProvider : BaseFolderImageProvider<PhotoAlbum>
|
||||
{
|
||||
public PhotoAlbumImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager)
|
||||
: base(fileSystem, providerManager, applicationPaths, imageProcessor, libraryManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#nullable disable
|
||||
|
||||
#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;
|
||||
|
||||
if (subItem is Episode episode)
|
||||
{
|
||||
var series = episode.Series;
|
||||
if (series is not null && series.HasImage(ImageType.Primary))
|
||||
{
|
||||
return series;
|
||||
}
|
||||
}
|
||||
|
||||
if (subItem.HasImage(ImageType.Primary))
|
||||
{
|
||||
return subItem;
|
||||
}
|
||||
|
||||
var parent = subItem.GetOwner() ?? subItem.GetParent();
|
||||
|
||||
if (parent is not null && parent.HasImage(ImageType.Primary))
|
||||
{
|
||||
if (parent is MusicAlbum)
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.Where(i => i is not null)
|
||||
.DistinctBy(x => x.Id)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user