Merge pull request #5208 from crobibero/api-post-image
Add image file accept to openapi
This commit is contained in:
commit
76d66e0dee
28
Jellyfin.Api/Attributes/AcceptsFileAttribute.cs
Normal file
28
Jellyfin.Api/Attributes/AcceptsFileAttribute.cs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Jellyfin.Api.Attributes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Internal produces image attribute.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class AcceptsFileAttribute : Attribute
|
||||||
|
{
|
||||||
|
private readonly string[] _contentTypes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AcceptsFileAttribute"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="contentTypes">Content types this endpoint produces.</param>
|
||||||
|
public AcceptsFileAttribute(params string[] contentTypes)
|
||||||
|
{
|
||||||
|
_contentTypes = contentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the configured content types.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>the configured content types.</returns>
|
||||||
|
public string[] GetContentTypes() => _contentTypes;
|
||||||
|
}
|
||||||
|
}
|
18
Jellyfin.Api/Attributes/AcceptsImageFileAttribute.cs
Normal file
18
Jellyfin.Api/Attributes/AcceptsImageFileAttribute.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
namespace Jellyfin.Api.Attributes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Produces file attribute of "image/*".
|
||||||
|
/// </summary>
|
||||||
|
public class AcceptsImageFileAttribute : AcceptsFileAttribute
|
||||||
|
{
|
||||||
|
private const string ContentType = "image/*";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="AcceptsImageFileAttribute"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public AcceptsImageFileAttribute()
|
||||||
|
: base(ContentType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -87,6 +87,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <returns>A <see cref="NoContentResult"/>.</returns>
|
/// <returns>A <see cref="NoContentResult"/>.</returns>
|
||||||
[HttpPost("Users/{userId}/Images/{imageType}")]
|
[HttpPost("Users/{userId}/Images/{imageType}")]
|
||||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||||
|
[AcceptsImageFile]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")]
|
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")]
|
||||||
|
@ -133,6 +134,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <returns>A <see cref="NoContentResult"/>.</returns>
|
/// <returns>A <see cref="NoContentResult"/>.</returns>
|
||||||
[HttpPost("Users/{userId}/Images/{imageType}/{index}")]
|
[HttpPost("Users/{userId}/Images/{imageType}/{index}")]
|
||||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||||
|
[AcceptsImageFile]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")]
|
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")]
|
||||||
|
@ -312,6 +314,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if item not found.</returns>
|
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if item not found.</returns>
|
||||||
[HttpPost("Items/{itemId}/Images/{imageType}")]
|
[HttpPost("Items/{itemId}/Images/{imageType}")]
|
||||||
[Authorize(Policy = Policies.RequiresElevation)]
|
[Authorize(Policy = Policies.RequiresElevation)]
|
||||||
|
[AcceptsImageFile]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
|
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
|
||||||
|
@ -346,6 +349,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if item not found.</returns>
|
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if item not found.</returns>
|
||||||
[HttpPost("Items/{itemId}/Images/{imageType}/{imageIndex}")]
|
[HttpPost("Items/{itemId}/Images/{imageType}/{imageIndex}")]
|
||||||
[Authorize(Policy = Policies.RequiresElevation)]
|
[Authorize(Policy = Policies.RequiresElevation)]
|
||||||
|
[AcceptsImageFile]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
|
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
|
||||||
|
|
|
@ -316,6 +316,7 @@ namespace Jellyfin.Server.Extensions
|
||||||
|
|
||||||
c.OperationFilter<SecurityRequirementsOperationFilter>();
|
c.OperationFilter<SecurityRequirementsOperationFilter>();
|
||||||
c.OperationFilter<FileResponseFilter>();
|
c.OperationFilter<FileResponseFilter>();
|
||||||
|
c.OperationFilter<FileRequestFilter>();
|
||||||
c.OperationFilter<ParameterObsoleteFilter>();
|
c.OperationFilter<ParameterObsoleteFilter>();
|
||||||
c.DocumentFilter<WebsocketModelFilter>();
|
c.DocumentFilter<WebsocketModelFilter>();
|
||||||
});
|
});
|
||||||
|
|
43
Jellyfin.Server/Filters/FileRequestFilter.cs
Normal file
43
Jellyfin.Server/Filters/FileRequestFilter.cs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Jellyfin.Api.Attributes;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
|
||||||
|
namespace Jellyfin.Server.Filters
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public class FileRequestFilter : IOperationFilter
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||||
|
{
|
||||||
|
foreach (var attribute in context.ApiDescription.ActionDescriptor.EndpointMetadata)
|
||||||
|
{
|
||||||
|
if (attribute is AcceptsFileAttribute acceptsFileAttribute)
|
||||||
|
{
|
||||||
|
operation.RequestBody = GetRequestBody(acceptsFileAttribute.GetContentTypes());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static OpenApiRequestBody GetRequestBody(IEnumerable<string> contentTypes)
|
||||||
|
{
|
||||||
|
var body = new OpenApiRequestBody();
|
||||||
|
var mediaType = new OpenApiMediaType
|
||||||
|
{
|
||||||
|
Schema = new OpenApiSchema
|
||||||
|
{
|
||||||
|
Type = "string",
|
||||||
|
Format = "binary"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
foreach (var contentType in contentTypes)
|
||||||
|
{
|
||||||
|
body.Content.Add(contentType, mediaType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user