V14: Resize url endpoint (#16275)
* Add image resizing endpoint * Rename factory * Actually use height and width --------- Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.UrlSegment;
|
||||
|
||||
[VersionedApiBackOfficeRoute("imaging")]
|
||||
[ApiExplorerSettings(GroupName = "Imaging")]
|
||||
[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)]
|
||||
public class ImagingControllerBase : ManagementApiControllerBase
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Media;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.UrlSegment;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class ResizeImagingController : ImagingControllerBase
|
||||
{
|
||||
private readonly IMediaService _mediaService;
|
||||
private readonly IReziseImageUrlFactory _reziseImageUrlFactory;
|
||||
|
||||
public ResizeImagingController(IMediaService mediaService, IReziseImageUrlFactory reziseImageUrlFactory)
|
||||
{
|
||||
_mediaService = mediaService;
|
||||
_reziseImageUrlFactory = reziseImageUrlFactory;
|
||||
}
|
||||
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet("resize/urls")]
|
||||
[ProducesResponseType(typeof(IEnumerable<MediaUrlInfoResponseModel>), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> Urls([FromQuery(Name = "id")] HashSet<Guid> ids, int height = 200, int width = 200, ImageCropMode? mode = null)
|
||||
{
|
||||
IEnumerable<IMedia> items = _mediaService.GetByIds(ids);
|
||||
|
||||
return await Task.FromResult(Ok(_reziseImageUrlFactory.CreateUrlSets(items, height, width, mode)));
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ internal static class MediaBuilderExtensions
|
||||
builder.Services.AddTransient<IMediaEditingPresentationFactory, MediaEditingPresentationFactory>();
|
||||
builder.Services.AddTransient<IUrlAssembler, DefaultUrlAssembler>();
|
||||
builder.Services.AddTransient<IMediaUrlFactory, MediaUrlFactory>();
|
||||
builder.Services.AddTransient<IReziseImageUrlFactory, ReziseImageUrlFactory>();
|
||||
builder.Services.AddScoped<IAbsoluteUrlBuilder, DefaultAbsoluteUrlBuilder>();
|
||||
|
||||
builder.WithCollectionBuilder<MapDefinitionCollectionBuilder>().Add<MediaMapDefinition>();
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Media;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Factories;
|
||||
|
||||
public interface IReziseImageUrlFactory
|
||||
{
|
||||
IEnumerable<MediaUrlInfoResponseModel> CreateUrlSets(IEnumerable<IMedia> mediaItems, int height, int width, ImageCropMode? mode);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Media;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Media;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Factories;
|
||||
|
||||
public class ReziseImageUrlFactory : IReziseImageUrlFactory
|
||||
{
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
private readonly ContentSettings _contentSettings;
|
||||
private readonly MediaUrlGeneratorCollection _mediaUrlGenerators;
|
||||
private readonly IAbsoluteUrlBuilder _absoluteUrlBuilder;
|
||||
|
||||
public ReziseImageUrlFactory(IImageUrlGenerator imageUrlGenerator, IOptions<ContentSettings> contentSettings, MediaUrlGeneratorCollection mediaUrlGenerators, IAbsoluteUrlBuilder absoluteUrlBuilder)
|
||||
{
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
_contentSettings = contentSettings.Value;
|
||||
_mediaUrlGenerators = mediaUrlGenerators;
|
||||
_absoluteUrlBuilder = absoluteUrlBuilder;
|
||||
}
|
||||
|
||||
public IEnumerable<MediaUrlInfoResponseModel> CreateUrlSets(IEnumerable<IMedia> mediaItems, int height, int width, ImageCropMode? mode)
|
||||
{
|
||||
return mediaItems.Select(media => new MediaUrlInfoResponseModel(media.Key, CreateUrls(media, height, width, mode))).ToArray();
|
||||
}
|
||||
|
||||
private IEnumerable<MediaUrlInfo> CreateUrls(IMedia media, int height, int width, ImageCropMode? mode)
|
||||
{
|
||||
IEnumerable<string> urls = media
|
||||
.GetUrls(_contentSettings, _mediaUrlGenerators)
|
||||
.WhereNotNull();
|
||||
|
||||
return CreateThumbnailUrls(urls, height, width, mode);
|
||||
}
|
||||
|
||||
private IEnumerable<MediaUrlInfo> CreateThumbnailUrls(IEnumerable<string> urls, int height, int width, ImageCropMode? mode)
|
||||
{
|
||||
foreach (var url in urls)
|
||||
{
|
||||
// Have to remove first char here, as it always contains the "."
|
||||
var extension = Path.GetExtension(url).Remove(0, 1);
|
||||
if (_imageUrlGenerator.SupportedImageFileTypes.InvariantContains(extension) is false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var options = new ImageUrlGenerationOptions(url)
|
||||
{
|
||||
Height = height,
|
||||
Width = width,
|
||||
ImageCropMode = mode,
|
||||
};
|
||||
|
||||
var relativeUrl = _imageUrlGenerator.GetImageUrl(options);
|
||||
if (relativeUrl is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return new MediaUrlInfo
|
||||
{
|
||||
Culture = null,
|
||||
Url = _absoluteUrlBuilder.ToAbsoluteUrl(relativeUrl).ToString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10816,6 +10816,83 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/imaging/resize/urls": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Imaging"
|
||||
],
|
||||
"operationId": "GetImagingResizeUrls",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"uniqueItems": true,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "height",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "width",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "mode",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ImageCropModeModel"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MediaUrlInfoResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
},
|
||||
"403": {
|
||||
"description": "The authenticated user do not have access to this resource"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/indexer": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -36709,6 +36786,17 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ImageCropModeModel": {
|
||||
"enum": [
|
||||
"Crop",
|
||||
"Max",
|
||||
"Stretch",
|
||||
"Pad",
|
||||
"BoxPad",
|
||||
"Min"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ImportDictionaryRequestModel": {
|
||||
"required": [
|
||||
"temporaryFile"
|
||||
|
||||
Reference in New Issue
Block a user