diff options
| author | Cody Robibero <cody@robibe.ro> | 2022-01-04 08:37:57 -0700 |
|---|---|---|
| committer | Cody Robibero <cody@robibe.ro> | 2022-01-04 08:44:03 -0700 |
| commit | 360fd70fc74325008b031c9a1155b9b76724866d (patch) | |
| tree | 88966cefe4f3a9a982cdf7b0bcb2c88edc6e0d64 | |
| parent | 9e0958d8224ef3fa51893fd5a38cc57104f32422 (diff) | |
Clean up
| -rw-r--r-- | Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs | 2 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/ImageController.cs | 32 | ||||
| -rw-r--r-- | Jellyfin.Drawing.Skia/DefaultImageGenerator.cs | 113 | ||||
| -rw-r--r-- | Jellyfin.Server/CoreAppHost.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/GeneratedImageType.cs | 12 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/GeneratedImages.cs | 13 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Drawing/IImageGenerator.cs | 32 | ||||
| -rw-r--r-- | MediaBrowser.Model/Branding/BrandingOptions.cs | 58 |
8 files changed, 133 insertions, 131 deletions
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs index 64393669b..c12fc2113 100644 --- a/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs +++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/RefreshMediaLibraryTask.cs @@ -83,7 +83,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks progress.Report(0); - _imageGenerator.GenerateSplashscreen(Path.Combine(_applicationPaths.DataPath, "splashscreen.webp")); + _imageGenerator.Generate(GeneratedImageType.Splashscreen, Path.Combine(_applicationPaths.DataPath, "splashscreen.webp")); return ((LibraryManager)_libraryManager).ValidateMediaLibraryInternal(progress, cancellationToken); } diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs index 24059cddd..6d34ca770 100644 --- a/Jellyfin.Api/Controllers/ImageController.cs +++ b/Jellyfin.Api/Controllers/ImageController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; using System.Globalization; @@ -1705,18 +1706,18 @@ namespace Jellyfin.Api.Controllers /// <summary> /// Generates or gets the splashscreen. /// </summary> - /// <param name="tag">Optional. Supply the cache tag from the item object to receive strong caching headers.</param> + /// <param name="tag">Supply the cache tag from the item object to receive strong caching headers.</param> /// <param name="format">Determines the output format of the image - original,gif,jpg,png.</param> /// <param name="maxWidth">The maximum image width to return.</param> /// <param name="maxHeight">The maximum image height to return.</param> /// <param name="width">The fixed image width to return.</param> /// <param name="height">The fixed image height to return.</param> - /// <param name="quality">Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases.</param> /// <param name="fillWidth">Width of box to fill.</param> /// <param name="fillHeight">Height of box to fill.</param> - /// <param name="blur">Optional. Blur image.</param> - /// <param name="backgroundColor">Optional. Apply a background color for transparent images.</param> - /// <param name="foregroundLayer">Optional. Apply a foreground layer on top of the image.</param> + /// <param name="blur">Blur image.</param> + /// <param name="backgroundColor">Apply a background color for transparent images.</param> + /// <param name="foregroundLayer">Apply a foreground layer on top of the image.</param> + /// <param name="quality">Quality setting, from 0-100.</param> /// <response code="200">Splashscreen returned successfully.</response> /// <returns>The splashscreen.</returns> [HttpGet("Branding/Splashscreen")] @@ -1729,12 +1730,12 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? maxHeight, [FromQuery] int? width, [FromQuery] int? height, - [FromQuery] int? quality, [FromQuery] int? fillWidth, [FromQuery] int? fillHeight, [FromQuery] int? blur, [FromQuery] string? backgroundColor, - [FromQuery] string? foregroundLayer) + [FromQuery] string? foregroundLayer, + [FromQuery, Range(0, 100)] int quality = 90) { string splashscreenPath; var brandingOptions = _serverConfigurationManager.GetConfiguration<BrandingOptions>("branding"); @@ -1746,9 +1747,9 @@ namespace Jellyfin.Api.Controllers { splashscreenPath = Path.Combine(_appPaths.DataPath, "splashscreen.webp"); - if (!System.IO.File.Exists(splashscreenPath) && _imageGenerator.GetSupportedImages().Contains(GeneratedImages.Splashscreen)) + if (!System.IO.File.Exists(splashscreenPath) && _imageGenerator.GetSupportedImages().Contains(GeneratedImageType.Splashscreen)) { - _imageGenerator.GenerateSplashscreen(splashscreenPath); + _imageGenerator.Generate(GeneratedImageType.Splashscreen, splashscreenPath); } } @@ -1771,18 +1772,20 @@ namespace Jellyfin.Api.Controllers MaxWidth = maxWidth, FillHeight = fillHeight, FillWidth = fillWidth, - Quality = quality ?? 100, + Quality = quality, Width = width, Blur = blur, BackgroundColor = backgroundColor, ForegroundLayer = foregroundLayer, SupportedOutputFormats = outputFormats }; + return await GetImageResult( - options, - cacheDuration, - new Dictionary<string, string>(), - Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase)); + options, + cacheDuration, + ImmutableDictionary<string, string>.Empty, + Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase)) + .ConfigureAwait(false); } /// <summary> @@ -1815,7 +1818,6 @@ namespace Jellyfin.Api.Controllers brandingOptions.SplashscreenLocation = filePath; _serverConfigurationManager.SaveConfiguration("branding", brandingOptions); - // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 . await using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous)) { await memoryStream.CopyToAsync(fs, CancellationToken.None).ConfigureAwait(false); diff --git a/Jellyfin.Drawing.Skia/DefaultImageGenerator.cs b/Jellyfin.Drawing.Skia/DefaultImageGenerator.cs index 4d029d906..e102b8f49 100644 --- a/Jellyfin.Drawing.Skia/DefaultImageGenerator.cs +++ b/Jellyfin.Drawing.Skia/DefaultImageGenerator.cs @@ -10,74 +10,73 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using Microsoft.Extensions.Logging; -namespace Jellyfin.Drawing.Skia +namespace Jellyfin.Drawing.Skia; + +/// <summary> +/// The default image generator. +/// </summary> +public class DefaultImageGenerator : IImageGenerator { + private readonly IImageEncoder _imageEncoder; + private readonly IItemRepository _itemRepository; + private readonly ILogger _logger; + /// <summary> - /// The default image generator. + /// Initializes a new instance of the <see cref="DefaultImageGenerator"/> class. /// </summary> - public class DefaultImageGenerator : IImageGenerator + /// <param name="imageEncoder">Instance of the <see cref="IImageEncoder"/> interface.</param> + /// <param name="itemRepository">Instance of the <see cref="IItemRepository"/> interface.</param> + /// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param> + public DefaultImageGenerator( + IImageEncoder imageEncoder, + IItemRepository itemRepository, + ILogger<DefaultImageGenerator> logger) { - private readonly IImageEncoder _imageEncoder; - private readonly IItemRepository _itemRepository; - private readonly ILogger _logger; + _imageEncoder = imageEncoder; + _itemRepository = itemRepository; + _logger = logger; + } - /// <summary> - /// Initializes a new instance of the <see cref="DefaultImageGenerator"/> class. - /// </summary> - /// <param name="imageEncoder">Instance of the <see cref="IImageEncoder"/> interface.</param> - /// <param name="itemRepository">Instance of the <see cref="IItemRepository"/> interface.</param> - /// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param> - public DefaultImageGenerator( - IImageEncoder imageEncoder, - IItemRepository itemRepository, - ILogger<DefaultImageGenerator> logger) - { - _imageEncoder = imageEncoder; - _itemRepository = itemRepository; - _logger = logger; - } + /// <inheritdoc/> + public IReadOnlyList<GeneratedImageType> GetSupportedImages() + { + return new[] { GeneratedImageType.Splashscreen }; + } - /// <inheritdoc/> - public GeneratedImages[] GetSupportedImages() + /// <inheritdoc/> + public void Generate(GeneratedImageType imageTypeType, string outputPath) + { + var posters = GetItemsWithImageType(ImageType.Primary).Select(x => x.GetImages(ImageType.Primary).First().Path).ToList(); + var landscape = GetItemsWithImageType(ImageType.Thumb).Select(x => x.GetImages(ImageType.Thumb).First().Path).ToList(); + if (landscape.Count == 0) { - return new[] { GeneratedImages.Splashscreen }; + // Thumb images fit better because they include the title in the image but are not provided with TMDb. + // Using backdrops as a fallback to generate an image at all + _logger.LogDebug("No thumb images found. Using backdrops to generate splashscreen"); + landscape = GetItemsWithImageType(ImageType.Backdrop).Select(x => x.GetImages(ImageType.Backdrop).First().Path).ToList(); } - /// <inheritdoc/> - public void GenerateSplashscreen(string outputPath) - { - var posters = GetItemsWithImageType(ImageType.Primary).Select(x => x.GetImages(ImageType.Primary).First().Path).ToList(); - var landscape = GetItemsWithImageType(ImageType.Thumb).Select(x => x.GetImages(ImageType.Thumb).First().Path).ToList(); - if (landscape.Count == 0) - { - // Thumb images fit better because they include the title in the image but are not provided with TMDb. - // Using backdrops as a fallback to generate an image at all - _logger.LogDebug("No thumb images found. Using backdrops to generate splashscreen."); - landscape = GetItemsWithImageType(ImageType.Backdrop).Select(x => x.GetImages(ImageType.Backdrop).First().Path).ToList(); - } - - var splashBuilder = new SplashscreenBuilder((SkiaEncoder)_imageEncoder); - splashBuilder.GenerateSplash(posters, landscape, outputPath); - } + var splashBuilder = new SplashscreenBuilder((SkiaEncoder)_imageEncoder); + splashBuilder.GenerateSplash(posters, landscape, outputPath); + } - private IReadOnlyList<BaseItem> GetItemsWithImageType(ImageType imageType) + private IReadOnlyList<BaseItem> GetItemsWithImageType(ImageType imageType) + { + // todo make included libraries configurable + return _itemRepository.GetItemList(new InternalItemsQuery { - // todo make included libraries configurable - return _itemRepository.GetItemList(new InternalItemsQuery + CollapseBoxSetItems = false, + Recursive = true, + DtoOptions = new DtoOptions(false), + ImageTypes = new[] { imageType }, + Limit = 30, + // todo max parental rating configurable + MaxParentalRating = 10, + OrderBy = new ValueTuple<string, SortOrder>[] { - CollapseBoxSetItems = false, - Recursive = true, - DtoOptions = new DtoOptions(false), - ImageTypes = new ImageType[] { imageType }, - Limit = 30, - // todo max parental rating configurable - MaxParentalRating = 10, - OrderBy = new ValueTuple<string, SortOrder>[] - { - new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) - }, - IncludeItemTypes = new string[] { "Movie", "Series" } - }); - } + new(ItemSortBy.Random, SortOrder.Ascending) + }, + IncludeItemTypes = new[] { BaseItemKind.Movie, BaseItemKind.Series } + }); } } diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index ac7ab2dee..b2f9a518a 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -86,7 +86,7 @@ namespace Jellyfin.Server serviceCollection.AddSingleton<IDeviceManager, DeviceManager>(); // TODO search plugins - ServiceCollection.AddSingleton<IImageGenerator, DefaultImageGenerator>(); + serviceCollection.AddSingleton<IImageGenerator, DefaultImageGenerator>(); // TODO search the assemblies instead of adding them manually? serviceCollection.AddSingleton<IWebSocketListener, SessionWebSocketListener>(); diff --git a/MediaBrowser.Controller/Drawing/GeneratedImageType.cs b/MediaBrowser.Controller/Drawing/GeneratedImageType.cs new file mode 100644 index 000000000..a8db86d4f --- /dev/null +++ b/MediaBrowser.Controller/Drawing/GeneratedImageType.cs @@ -0,0 +1,12 @@ +namespace MediaBrowser.Controller.Drawing; + +/// <summary> +/// Which generated image type the <see cref="IImageGenerator"/> supports. +/// </summary> +public enum GeneratedImageType +{ + /// <summary> + /// The splashscreen. + /// </summary> + Splashscreen = 0 +} diff --git a/MediaBrowser.Controller/Drawing/GeneratedImages.cs b/MediaBrowser.Controller/Drawing/GeneratedImages.cs deleted file mode 100644 index 47b60979b..000000000 --- a/MediaBrowser.Controller/Drawing/GeneratedImages.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace MediaBrowser.Controller.Drawing -{ - /// <summary> - /// Which generated images an <see cref="IImageGenerator"/> supports. - /// </summary> - public enum GeneratedImages - { - /// <summary> - /// The splashscreen. - /// </summary> - Splashscreen - } -} diff --git a/MediaBrowser.Controller/Drawing/IImageGenerator.cs b/MediaBrowser.Controller/Drawing/IImageGenerator.cs index f7e7f83b2..773db02cb 100644 --- a/MediaBrowser.Controller/Drawing/IImageGenerator.cs +++ b/MediaBrowser.Controller/Drawing/IImageGenerator.cs @@ -1,20 +1,22 @@ -namespace MediaBrowser.Controller.Drawing +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Drawing; + +/// <summary> +/// Interface for an image generator. +/// </summary> +public interface IImageGenerator { /// <summary> - /// Interface for an image generator. + /// Gets the supported generated images of the image generator. /// </summary> - public interface IImageGenerator - { - /// <summary> - /// Gets the supported generated images of the image generator. - /// </summary> - /// <returns>The supported images.</returns> - GeneratedImages[] GetSupportedImages(); + /// <returns>The supported generated image types.</returns> + IReadOnlyList<GeneratedImageType> GetSupportedImages(); - /// <summary> - /// Generates a splashscreen. - /// </summary> - /// <param name="outputPath">The path where the splashscreen should be saved.</param> - void GenerateSplashscreen(string outputPath); - } + /// <summary> + /// Generates a splashscreen. + /// </summary> + /// <param name="imageTypeType">The image to generate.</param> + /// <param name="outputPath">The path where the splashscreen should be saved.</param> + void Generate(GeneratedImageType imageTypeType, string outputPath); } diff --git a/MediaBrowser.Model/Branding/BrandingOptions.cs b/MediaBrowser.Model/Branding/BrandingOptions.cs index 56e5a8715..01db70885 100644 --- a/MediaBrowser.Model/Branding/BrandingOptions.cs +++ b/MediaBrowser.Model/Branding/BrandingOptions.cs @@ -1,38 +1,38 @@ using System.Text.Json.Serialization; using System.Xml.Serialization; -#pragma warning disable CS1591 +namespace MediaBrowser.Model.Branding; -namespace MediaBrowser.Model.Branding +/// <summary> +/// The branding options. +/// </summary> +public class BrandingOptions { - public class BrandingOptions - { - /// <summary> - /// Gets or sets the login disclaimer. - /// </summary> - /// <value>The login disclaimer.</value> - public string? LoginDisclaimer { get; set; } + /// <summary> + /// Gets or sets the login disclaimer. + /// </summary> + /// <value>The login disclaimer.</value> + public string? LoginDisclaimer { get; set; } - /// <summary> - /// Gets or sets the custom CSS. - /// </summary> - /// <value>The custom CSS.</value> - public string? CustomCss { get; set; } + /// <summary> + /// Gets or sets the custom CSS. + /// </summary> + /// <value>The custom CSS.</value> + public string? CustomCss { get; set; } - /// <summary> - /// Gets or sets the splashscreen location on disk. - /// </summary> - /// <remarks> - /// Not served via the API. - /// Only used to save the custom uploaded user splashscreen in the configuration file. - /// </remarks> - [JsonIgnore] - public string? SplashscreenLocation { get; set; } + /// <summary> + /// Gets or sets the splashscreen location on disk. + /// </summary> + /// <remarks> + /// Not served via the API. + /// Only used to save the custom uploaded user splashscreen in the configuration file. + /// </remarks> + [JsonIgnore] + public string? SplashscreenLocation { get; set; } - /// <summary> - /// Gets the splashscreen url. - /// </summary> - [XmlIgnore] - public string? SplashscreenUrl => "/Branding/Splashscreen"; - } + /// <summary> + /// Gets the splashscreen url. + /// </summary> + [XmlIgnore] + public string SplashscreenUrl => "/Branding/Splashscreen"; } |
