From 547ee885613591021ad5ff5595249b1f8448d742 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 15 Nov 2020 10:58:39 -0700 Subject: Remove api client generator errors --- Jellyfin.Api/Controllers/ImageController.cs | 736 ++++++++++++++++++++++++++-- 1 file changed, 683 insertions(+), 53 deletions(-) (limited to 'Jellyfin.Api/Controllers/ImageController.cs') diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs index 4a67c1aed..bb0f27312 100644 --- a/Jellyfin.Api/Controllers/ImageController.cs +++ b/Jellyfin.Api/Controllers/ImageController.cs @@ -85,7 +85,6 @@ namespace Jellyfin.Api.Controllers /// User does not have permission to delete the image. /// A . [HttpPost("Users/{userId}/Images/{imageType}")] - [HttpPost("Users/{userId}/Images/{imageType}/{index?}", Name = "PostUserImage_2")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status403Forbidden)] @@ -94,7 +93,53 @@ namespace Jellyfin.Api.Controllers public async Task PostUserImage( [FromRoute, Required] Guid userId, [FromRoute, Required] ImageType imageType, - [FromRoute] int? index = null) + [FromQuery] int? index = null) + { + if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true)) + { + return Forbid("User is not allowed to update the image."); + } + + var user = _userManager.GetUserById(userId); + await using var memoryStream = await GetMemoryStream(Request.Body).ConfigureAwait(false); + + // Handle image/png; charset=utf-8 + var mimeType = Request.ContentType.Split(';').FirstOrDefault(); + var userDataPath = Path.Combine(_serverConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, user.Username); + if (user.ProfileImage != null) + { + await _userManager.ClearProfileImageAsync(user).ConfigureAwait(false); + } + + user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType))); + + await _providerManager + .SaveImage(memoryStream, mimeType, user.ProfileImage.Path) + .ConfigureAwait(false); + await _userManager.UpdateUserAsync(user).ConfigureAwait(false); + + return NoContent(); + } + + /// + /// Sets the user image. + /// + /// User Id. + /// (Unused) Image type. + /// (Unused) Image index. + /// Image updated. + /// User does not have permission to delete the image. + /// A . + [HttpPost("Users/{userId}/Images/{imageType}/{index}")] + [Authorize(Policy = Policies.DefaultAuthorization)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")] + public async Task PostUserImageByIndex( + [FromRoute, Required] Guid userId, + [FromRoute, Required] ImageType imageType, + [FromRoute] int index) { if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true)) { @@ -131,8 +176,7 @@ namespace Jellyfin.Api.Controllers /// Image deleted. /// User does not have permission to delete the image. /// A . - [HttpDelete("Users/{userId}/Images/{itemType}")] - [HttpDelete("Users/{userId}/Images/{itemType}/{index?}", Name = "DeleteUserImage_2")] + [HttpDelete("Users/{userId}/Images/{imageType}")] [Authorize(Policy = Policies.DefaultAuthorization)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")] @@ -141,7 +185,46 @@ namespace Jellyfin.Api.Controllers public async Task DeleteUserImage( [FromRoute, Required] Guid userId, [FromRoute, Required] ImageType imageType, - [FromRoute] int? index = null) + [FromQuery] int? index = null) + { + if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true)) + { + return Forbid("User is not allowed to delete the image."); + } + + var user = _userManager.GetUserById(userId); + try + { + System.IO.File.Delete(user.ProfileImage.Path); + } + catch (IOException e) + { + _logger.LogError(e, "Error deleting user profile image:"); + } + + await _userManager.ClearProfileImageAsync(user).ConfigureAwait(false); + return NoContent(); + } + + /// + /// Delete the user's image. + /// + /// User Id. + /// (Unused) Image type. + /// (Unused) Image index. + /// Image deleted. + /// User does not have permission to delete the image. + /// A . + [HttpDelete("Users/{userId}/Images/{imageType}/{index}")] + [Authorize(Policy = Policies.DefaultAuthorization)] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task DeleteUserImageByIndex( + [FromRoute, Required] Guid userId, + [FromRoute, Required] ImageType imageType, + [FromRoute] int index) { if (!RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true)) { @@ -172,14 +255,13 @@ namespace Jellyfin.Api.Controllers /// Item not found. /// A on success, or a if item not found. [HttpDelete("Items/{itemId}/Images/{imageType}")] - [HttpDelete("Items/{itemId}/Images/{imageType}/{imageIndex?}", Name = "DeleteItemImage_2")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task DeleteItemImage( [FromRoute, Required] Guid itemId, [FromRoute, Required] ImageType imageType, - [FromRoute] int? imageIndex = null) + [FromQuery] int? imageIndex) { var item = _libraryManager.GetItemById(itemId); if (item == null) @@ -191,25 +273,83 @@ namespace Jellyfin.Api.Controllers return NoContent(); } + /// + /// Delete an item's image. + /// + /// Item id. + /// Image type. + /// The image index. + /// Image deleted. + /// Item not found. + /// A on success, or a if item not found. + [HttpDelete("Items/{itemId}/Images/{imageType}/{imageIndex}")] + [Authorize(Policy = Policies.RequiresElevation)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task DeleteItemImageByIndex( + [FromRoute, Required] Guid itemId, + [FromRoute, Required] ImageType imageType, + [FromRoute] int imageIndex) + { + var item = _libraryManager.GetItemById(itemId); + if (item == null) + { + return NotFound(); + } + + await item.DeleteImageAsync(imageType, imageIndex).ConfigureAwait(false); + return NoContent(); + } + /// /// Set item image. /// /// Item id. /// Image type. - /// (Unused) Image index. /// Image saved. /// Item not found. /// A on success, or a if item not found. [HttpPost("Items/{itemId}/Images/{imageType}")] - [HttpPost("Items/{itemId}/Images/{imageType}/{imageIndex?}", Name = "SetItemImage_2")] [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")] public async Task SetItemImage( + [FromRoute, Required] Guid itemId, + [FromRoute, Required] ImageType imageType) + { + var item = _libraryManager.GetItemById(itemId); + if (item == null) + { + return NotFound(); + } + + // Handle image/png; charset=utf-8 + var mimeType = Request.ContentType.Split(';').FirstOrDefault(); + await _providerManager.SaveImage(item, Request.Body, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false); + await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false); + + return NoContent(); + } + + /// + /// Set item image. + /// + /// Item id. + /// Image type. + /// (Unused) Image index. + /// Image saved. + /// Item not found. + /// A on success, or a if item not found. + [HttpPost("Items/{itemId}/Images/{imageType}/{imageIndex}")] + [Authorize(Policy = Policies.RequiresElevation)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")] + public async Task SetItemImageByIndex( [FromRoute, Required] Guid itemId, [FromRoute, Required] ImageType imageType, - [FromRoute] int? imageIndex = null) + [FromRoute] int imageIndex) { var item = _libraryManager.GetItemById(itemId); if (item == null) @@ -349,8 +489,6 @@ namespace Jellyfin.Api.Controllers /// [HttpGet("Items/{itemId}/Images/{imageType}")] [HttpHead("Items/{itemId}/Images/{imageType}", Name = "HeadItemImage")] - [HttpGet("Items/{itemId}/Images/{imageType}/{imageIndex?}", Name = "GetItemImage_2")] - [HttpHead("Items/{itemId}/Images/{imageType}/{imageIndex?}", Name = "HeadItemImage_2")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesImageFile] @@ -371,7 +509,86 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? blur, [FromQuery] string? backgroundColor, [FromQuery] string? foregroundLayer, - [FromRoute] int? imageIndex = null) + [FromQuery] int? imageIndex) + { + var item = _libraryManager.GetItemById(itemId); + if (item == null) + { + return NotFound(); + } + + return await GetImageInternal( + itemId, + imageType, + imageIndex, + tag, + format, + maxWidth, + maxHeight, + percentPlayed, + unplayedCount, + width, + height, + quality, + cropWhitespace, + addPlayedIndicator, + blur, + backgroundColor, + foregroundLayer, + item, + Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase)) + .ConfigureAwait(false); + } + + /// + /// Gets the item's image. + /// + /// Item id. + /// Image type. + /// Image index. + /// The maximum image width to return. + /// The maximum image height to return. + /// The fixed image width to return. + /// The fixed image height to return. + /// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases. + /// Optional. Supply the cache tag from the item object to receive strong caching headers. + /// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art. + /// Optional. The of the returned image. + /// Optional. Add a played indicator. + /// Optional. Percent to render for the percent played overlay. + /// Optional. Unplayed count overlay to render. + /// Optional. Blur image. + /// Optional. Apply a background color for transparent images. + /// Optional. Apply a foreground layer on top of the image. + /// Image stream returned. + /// Item not found. + /// + /// A containing the file stream on success, + /// or a if item not found. + /// + [HttpGet("Items/{itemId}/Images/{imageType}/{imageIndex}")] + [HttpHead("Items/{itemId}/Images/{imageType}/{imageIndex}", Name = "HeadItemImageByIndex")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesImageFile] + public async Task GetItemImageByIndex( + [FromRoute, Required] Guid itemId, + [FromRoute, Required] ImageType imageType, + [FromRoute] int imageIndex, + [FromQuery] int? maxWidth, + [FromQuery] int? maxHeight, + [FromQuery] int? width, + [FromQuery] int? height, + [FromQuery] int? quality, + [FromQuery] string? tag, + [FromQuery] bool? cropWhitespace, + [FromQuery] ImageFormat? format, + [FromQuery] bool? addPlayedIndicator, + [FromQuery] double? percentPlayed, + [FromQuery] int? unplayedCount, + [FromQuery] int? blur, + [FromQuery] string? backgroundColor, + [FromQuery] string? foregroundLayer) { var item = _libraryManager.GetItemById(itemId); if (item == null) @@ -507,8 +724,8 @@ namespace Jellyfin.Api.Controllers /// A containing the file stream on success, /// or a if item not found. /// - [HttpGet("Artists/{name}/Images/{imageType}/{imageIndex?}")] - [HttpHead("Artists/{name}/Images/{imageType}/{imageIndex?}", Name = "HeadArtistImage")] + [HttpGet("Artists/{name}/Images/{imageType}/{imageIndex}")] + [HttpHead("Artists/{name}/Images/{imageType}/{imageIndex}", Name = "HeadArtistImage")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesImageFile] @@ -586,8 +803,8 @@ namespace Jellyfin.Api.Controllers /// A containing the file stream on success, /// or a if item not found. /// - [HttpGet("Genres/{name}/Images/{imageType}/{imageIndex?}")] - [HttpHead("Genres/{name}/Images/{imageType}/{imageIndex?}", Name = "HeadGenreImage")] + [HttpGet("Genres/{name}/Images/{imageType}")] + [HttpHead("Genres/{name}/Images/{imageType}", Name = "HeadGenreImage")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesImageFile] @@ -608,7 +825,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? blur, [FromQuery] string? backgroundColor, [FromQuery] string? foregroundLayer, - [FromRoute] int? imageIndex = null) + [FromQuery] int? imageIndex) { var item = _libraryManager.GetGenre(name); if (item == null) @@ -640,10 +857,11 @@ namespace Jellyfin.Api.Controllers } /// - /// Get music genre image by name. + /// Get genre image by name. /// - /// Music genre name. + /// Genre name. /// Image type. + /// Image index. /// Optional. Supply the cache tag from the item object to receive strong caching headers. /// Determines the output format of the image - original,gif,jpg,png. /// The maximum image width to return. @@ -658,21 +876,21 @@ namespace Jellyfin.Api.Controllers /// Optional. Blur image. /// Optional. Apply a background color for transparent images. /// Optional. Apply a foreground layer on top of the image. - /// Image index. /// Image stream returned. /// Item not found. /// /// A containing the file stream on success, /// or a if item not found. /// - [HttpGet("MusicGenres/{name}/Images/{imageType}/{imageIndex?}")] - [HttpHead("MusicGenres/{name}/Images/{imageType}/{imageIndex?}", Name = "HeadMusicGenreImage")] + [HttpGet("Genres/{name}/Images/{imageType}/{imageIndex}")] + [HttpHead("Genres/{name}/Images/{imageType}/{imageIndex}", Name = "HeadGenreImageByIndex")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesImageFile] - public async Task GetMusicGenreImage( + public async Task GetGenreImageByIndex( [FromRoute, Required] string name, [FromRoute, Required] ImageType imageType, + [FromRoute, Required] int imageIndex, [FromQuery] string tag, [FromQuery] ImageFormat? format, [FromQuery] int? maxWidth, @@ -686,10 +904,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? addPlayedIndicator, [FromQuery] int? blur, [FromQuery] string? backgroundColor, - [FromQuery] string? foregroundLayer, - [FromRoute] int? imageIndex = null) + [FromQuery] string? foregroundLayer) { - var item = _libraryManager.GetMusicGenre(name); + var item = _libraryManager.GetGenre(name); if (item == null) { return NotFound(); @@ -719,9 +936,9 @@ namespace Jellyfin.Api.Controllers } /// - /// Get person image by name. + /// Get music genre image by name. /// - /// Person name. + /// Music genre name. /// Image type. /// Optional. Supply the cache tag from the item object to receive strong caching headers. /// Determines the output format of the image - original,gif,jpg,png. @@ -744,12 +961,12 @@ namespace Jellyfin.Api.Controllers /// A containing the file stream on success, /// or a if item not found. /// - [HttpGet("Persons/{name}/Images/{imageType}/{imageIndex?}")] - [HttpHead("Persons/{name}/Images/{imageType}/{imageIndex?}", Name = "HeadPersonImage")] + [HttpGet("MusicGenres/{name}/Images/{imageType}")] + [HttpHead("MusicGenres/{name}/Images/{imageType}", Name = "HeadMusicGenreImage")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesImageFile] - public async Task GetPersonImage( + public async Task GetMusicGenreImage( [FromRoute, Required] string name, [FromRoute, Required] ImageType imageType, [FromQuery] string tag, @@ -766,9 +983,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? blur, [FromQuery] string? backgroundColor, [FromQuery] string? foregroundLayer, - [FromRoute] int? imageIndex = null) + [FromQuery] int? imageIndex) { - var item = _libraryManager.GetPerson(name); + var item = _libraryManager.GetMusicGenre(name); if (item == null) { return NotFound(); @@ -798,10 +1015,11 @@ namespace Jellyfin.Api.Controllers } /// - /// Get studio image by name. + /// Get music genre image by name. /// - /// Studio name. + /// Music genre name. /// Image type. + /// Image index. /// Optional. Supply the cache tag from the item object to receive strong caching headers. /// Determines the output format of the image - original,gif,jpg,png. /// The maximum image width to return. @@ -816,23 +1034,23 @@ namespace Jellyfin.Api.Controllers /// Optional. Blur image. /// Optional. Apply a background color for transparent images. /// Optional. Apply a foreground layer on top of the image. - /// Image index. /// Image stream returned. /// Item not found. /// /// A containing the file stream on success, /// or a if item not found. /// - [HttpGet("Studios/{name}/Images/{imageType}/{imageIndex?}")] - [HttpHead("Studios/{name}/Images/{imageType}/{imageIndex?}", Name = "HeadStudioImage")] + [HttpGet("MusicGenres/{name}/Images/{imageType}/{imageIndex}")] + [HttpHead("MusicGenres/{name}/Images/{imageType}/{imageIndex}", Name = "HeadMusicGenreImageByIndex")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesImageFile] - public async Task GetStudioImage( + public async Task GetMusicGenreImageByIndex( [FromRoute, Required] string name, [FromRoute, Required] ImageType imageType, - [FromRoute, Required] string tag, - [FromRoute, Required] ImageFormat format, + [FromRoute, Required] int imageIndex, + [FromQuery] string tag, + [FromQuery] ImageFormat? format, [FromQuery] int? maxWidth, [FromQuery] int? maxHeight, [FromQuery] double? percentPlayed, @@ -844,10 +1062,9 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool? addPlayedIndicator, [FromQuery] int? blur, [FromQuery] string? backgroundColor, - [FromQuery] string? foregroundLayer, - [FromRoute] int? imageIndex = null) + [FromQuery] string? foregroundLayer) { - var item = _libraryManager.GetStudio(name); + var item = _libraryManager.GetMusicGenre(name); if (item == null) { return NotFound(); @@ -877,9 +1094,9 @@ namespace Jellyfin.Api.Controllers } /// - /// Get user profile image. + /// Get person image by name. /// - /// User id. + /// Person name. /// Image type. /// Optional. Supply the cache tag from the item object to receive strong caching headers. /// Determines the output format of the image - original,gif,jpg,png. @@ -902,15 +1119,15 @@ namespace Jellyfin.Api.Controllers /// A containing the file stream on success, /// or a if item not found. /// - [HttpGet("Users/{userId}/Images/{imageType}/{imageIndex?}")] - [HttpHead("Users/{userId}/Images/{imageType}/{imageIndex?}", Name = "HeadUserImage")] + [HttpGet("Persons/{name}/Images/{imageType}")] + [HttpHead("Persons/{name}/Images/{imageType}", Name = "HeadPersonImage")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesImageFile] - public async Task GetUserImage( - [FromRoute, Required] Guid userId, + public async Task GetPersonImage( + [FromRoute, Required] string name, [FromRoute, Required] ImageType imageType, - [FromQuery] string? tag, + [FromQuery] string tag, [FromQuery] ImageFormat? format, [FromQuery] int? maxWidth, [FromQuery] int? maxHeight, @@ -924,7 +1141,420 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? blur, [FromQuery] string? backgroundColor, [FromQuery] string? foregroundLayer, - [FromRoute] int? imageIndex = null) + [FromQuery] int? imageIndex) + { + var item = _libraryManager.GetPerson(name); + if (item == null) + { + return NotFound(); + } + + return await GetImageInternal( + item.Id, + imageType, + imageIndex, + tag, + format, + maxWidth, + maxHeight, + percentPlayed, + unplayedCount, + width, + height, + quality, + cropWhitespace, + addPlayedIndicator, + blur, + backgroundColor, + foregroundLayer, + item, + Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase)) + .ConfigureAwait(false); + } + + /// + /// Get person image by name. + /// + /// Person name. + /// Image type. + /// Image index. + /// Optional. Supply the cache tag from the item object to receive strong caching headers. + /// Determines the output format of the image - original,gif,jpg,png. + /// The maximum image width to return. + /// The maximum image height to return. + /// Optional. Percent to render for the percent played overlay. + /// Optional. Unplayed count overlay to render. + /// The fixed image width to return. + /// The fixed image height to return. + /// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases. + /// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art. + /// Optional. Add a played indicator. + /// Optional. Blur image. + /// Optional. Apply a background color for transparent images. + /// Optional. Apply a foreground layer on top of the image. + /// Image stream returned. + /// Item not found. + /// + /// A containing the file stream on success, + /// or a if item not found. + /// + [HttpGet("Persons/{name}/Images/{imageType}/{imageIndex}")] + [HttpHead("Persons/{name}/Images/{imageType}/{imageIndex}", Name = "HeadPersonImageByIndex")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesImageFile] + public async Task GetPersonImageByIndex( + [FromRoute, Required] string name, + [FromRoute, Required] ImageType imageType, + [FromRoute, Required] int imageIndex, + [FromQuery] string tag, + [FromQuery] ImageFormat? format, + [FromQuery] int? maxWidth, + [FromQuery] int? maxHeight, + [FromQuery] double? percentPlayed, + [FromQuery] int? unplayedCount, + [FromQuery] int? width, + [FromQuery] int? height, + [FromQuery] int? quality, + [FromQuery] bool? cropWhitespace, + [FromQuery] bool? addPlayedIndicator, + [FromQuery] int? blur, + [FromQuery] string? backgroundColor, + [FromQuery] string? foregroundLayer) + { + var item = _libraryManager.GetPerson(name); + if (item == null) + { + return NotFound(); + } + + return await GetImageInternal( + item.Id, + imageType, + imageIndex, + tag, + format, + maxWidth, + maxHeight, + percentPlayed, + unplayedCount, + width, + height, + quality, + cropWhitespace, + addPlayedIndicator, + blur, + backgroundColor, + foregroundLayer, + item, + Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase)) + .ConfigureAwait(false); + } + + /// + /// Get studio image by name. + /// + /// Studio name. + /// Image type. + /// Optional. Supply the cache tag from the item object to receive strong caching headers. + /// Determines the output format of the image - original,gif,jpg,png. + /// The maximum image width to return. + /// The maximum image height to return. + /// Optional. Percent to render for the percent played overlay. + /// Optional. Unplayed count overlay to render. + /// The fixed image width to return. + /// The fixed image height to return. + /// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases. + /// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art. + /// Optional. Add a played indicator. + /// Optional. Blur image. + /// Optional. Apply a background color for transparent images. + /// Optional. Apply a foreground layer on top of the image. + /// Image index. + /// Image stream returned. + /// Item not found. + /// + /// A containing the file stream on success, + /// or a if item not found. + /// + [HttpGet("Studios/{name}/Images/{imageType}")] + [HttpHead("Studios/{name}/Images/{imageType}", Name = "HeadStudioImage")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesImageFile] + public async Task GetStudioImage( + [FromRoute, Required] string name, + [FromRoute, Required] ImageType imageType, + [FromQuery] string? tag, + [FromQuery] ImageFormat? format, + [FromQuery] int? maxWidth, + [FromQuery] int? maxHeight, + [FromQuery] double? percentPlayed, + [FromQuery] int? unplayedCount, + [FromQuery] int? width, + [FromQuery] int? height, + [FromQuery] int? quality, + [FromQuery] bool? cropWhitespace, + [FromQuery] bool? addPlayedIndicator, + [FromQuery] int? blur, + [FromQuery] string? backgroundColor, + [FromQuery] string? foregroundLayer, + [FromQuery] int? imageIndex) + { + var item = _libraryManager.GetStudio(name); + if (item == null) + { + return NotFound(); + } + + return await GetImageInternal( + item.Id, + imageType, + imageIndex, + tag, + format, + maxWidth, + maxHeight, + percentPlayed, + unplayedCount, + width, + height, + quality, + cropWhitespace, + addPlayedIndicator, + blur, + backgroundColor, + foregroundLayer, + item, + Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase)) + .ConfigureAwait(false); + } + + /// + /// Get studio image by name. + /// + /// Studio name. + /// Image type. + /// Image index. + /// Optional. Supply the cache tag from the item object to receive strong caching headers. + /// Determines the output format of the image - original,gif,jpg,png. + /// The maximum image width to return. + /// The maximum image height to return. + /// Optional. Percent to render for the percent played overlay. + /// Optional. Unplayed count overlay to render. + /// The fixed image width to return. + /// The fixed image height to return. + /// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases. + /// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art. + /// Optional. Add a played indicator. + /// Optional. Blur image. + /// Optional. Apply a background color for transparent images. + /// Optional. Apply a foreground layer on top of the image. + /// Image stream returned. + /// Item not found. + /// + /// A containing the file stream on success, + /// or a if item not found. + /// + [HttpGet("Studios/{name}/Images/{imageType}/{imageIndex}")] + [HttpHead("Studios/{name}/Images/{imageType}/{imageIndex}", Name = "HeadStudioImageByIndex")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesImageFile] + public async Task GetStudioImageByIndex( + [FromRoute, Required] string name, + [FromRoute, Required] ImageType imageType, + [FromRoute, Required] int imageIndex, + [FromQuery] string? tag, + [FromQuery] ImageFormat? format, + [FromQuery] int? maxWidth, + [FromQuery] int? maxHeight, + [FromQuery] double? percentPlayed, + [FromQuery] int? unplayedCount, + [FromQuery] int? width, + [FromQuery] int? height, + [FromQuery] int? quality, + [FromQuery] bool? cropWhitespace, + [FromQuery] bool? addPlayedIndicator, + [FromQuery] int? blur, + [FromQuery] string? backgroundColor, + [FromQuery] string? foregroundLayer) + { + var item = _libraryManager.GetStudio(name); + if (item == null) + { + return NotFound(); + } + + return await GetImageInternal( + item.Id, + imageType, + imageIndex, + tag, + format, + maxWidth, + maxHeight, + percentPlayed, + unplayedCount, + width, + height, + quality, + cropWhitespace, + addPlayedIndicator, + blur, + backgroundColor, + foregroundLayer, + item, + Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase)) + .ConfigureAwait(false); + } + + /// + /// Get user profile image. + /// + /// User id. + /// Image type. + /// Optional. Supply the cache tag from the item object to receive strong caching headers. + /// Determines the output format of the image - original,gif,jpg,png. + /// The maximum image width to return. + /// The maximum image height to return. + /// Optional. Percent to render for the percent played overlay. + /// Optional. Unplayed count overlay to render. + /// The fixed image width to return. + /// The fixed image height to return. + /// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases. + /// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art. + /// Optional. Add a played indicator. + /// Optional. Blur image. + /// Optional. Apply a background color for transparent images. + /// Optional. Apply a foreground layer on top of the image. + /// Image index. + /// Image stream returned. + /// Item not found. + /// + /// A containing the file stream on success, + /// or a if item not found. + /// + [HttpGet("Users/{userId}/Images/{imageType}")] + [HttpHead("Users/{userId}/Images/{imageType}", Name = "HeadUserImage")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesImageFile] + public async Task GetUserImage( + [FromRoute, Required] Guid userId, + [FromRoute, Required] ImageType imageType, + [FromQuery] string? tag, + [FromQuery] ImageFormat? format, + [FromQuery] int? maxWidth, + [FromQuery] int? maxHeight, + [FromQuery] double? percentPlayed, + [FromQuery] int? unplayedCount, + [FromQuery] int? width, + [FromQuery] int? height, + [FromQuery] int? quality, + [FromQuery] bool? cropWhitespace, + [FromQuery] bool? addPlayedIndicator, + [FromQuery] int? blur, + [FromQuery] string? backgroundColor, + [FromQuery] string? foregroundLayer, + [FromQuery] int? imageIndex) + { + var user = _userManager.GetUserById(userId); + if (user == null) + { + return NotFound(); + } + + var info = new ItemImageInfo + { + Path = user.ProfileImage.Path, + Type = ImageType.Profile, + DateModified = user.ProfileImage.LastModified + }; + + if (width.HasValue) + { + info.Width = width.Value; + } + + if (height.HasValue) + { + info.Height = height.Value; + } + + return await GetImageInternal( + user.Id, + imageType, + imageIndex, + tag, + format, + maxWidth, + maxHeight, + percentPlayed, + unplayedCount, + width, + height, + quality, + cropWhitespace, + addPlayedIndicator, + blur, + backgroundColor, + foregroundLayer, + null, + Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase), + info) + .ConfigureAwait(false); + } + + /// + /// Get user profile image. + /// + /// User id. + /// Image type. + /// Image index. + /// Optional. Supply the cache tag from the item object to receive strong caching headers. + /// Determines the output format of the image - original,gif,jpg,png. + /// The maximum image width to return. + /// The maximum image height to return. + /// Optional. Percent to render for the percent played overlay. + /// Optional. Unplayed count overlay to render. + /// The fixed image width to return. + /// The fixed image height to return. + /// Optional. Quality setting, from 0-100. Defaults to 90 and should suffice in most cases. + /// Optional. Specify if whitespace should be cropped out of the image. True/False. If unspecified, whitespace will be cropped from logos and clear art. + /// Optional. Add a played indicator. + /// Optional. Blur image. + /// Optional. Apply a background color for transparent images. + /// Optional. Apply a foreground layer on top of the image. + /// Image stream returned. + /// Item not found. + /// + /// A containing the file stream on success, + /// or a if item not found. + /// + [HttpGet("Users/{userId}/Images/{imageType}/{imageIndex}")] + [HttpHead("Users/{userId}/Images/{imageType}/{imageIndex}", Name = "HeadUserImageByIndex")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesImageFile] + public async Task GetUserImageByIndex( + [FromRoute, Required] Guid userId, + [FromRoute, Required] ImageType imageType, + [FromRoute, Required] int imageIndex, + [FromQuery] string? tag, + [FromQuery] ImageFormat? format, + [FromQuery] int? maxWidth, + [FromQuery] int? maxHeight, + [FromQuery] double? percentPlayed, + [FromQuery] int? unplayedCount, + [FromQuery] int? width, + [FromQuery] int? height, + [FromQuery] int? quality, + [FromQuery] bool? cropWhitespace, + [FromQuery] bool? addPlayedIndicator, + [FromQuery] int? blur, + [FromQuery] string? backgroundColor, + [FromQuery] string? foregroundLayer) { var user = _userManager.GetUserById(userId); if (user == null) -- cgit v1.2.3