Add oEmbed endpoint to the management api (#16188)

* OEmbed query endpoint

* Log provider instead of url from user
This commit is contained in:
Bjarke Berg
2024-04-30 14:21:50 +02:00
committed by GitHub
parent e3a4d4dae2
commit 3eef9b9579
26 changed files with 411 additions and 39 deletions

View File

@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Api.Management.Controllers.OEmbed;
[VersionedApiBackOfficeRoute("oembed")]
[ApiExplorerSettings(GroupName = "oEmbed")]
public abstract class OEmbedControllerBase : ManagementApiControllerBase
{
protected IActionResult OEmbedOperationStatusResult(OEmbedOperationStatus status)
=> OperationStatusResult(status, problemDetailsBuilder => status switch
{
OEmbedOperationStatus.NoSupportedProvider => BadRequest(problemDetailsBuilder
.WithTitle("The specified url is not supported.")
.WithDetail("No oEmbed provider was found for the specified url.")
.Build()),
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
.WithTitle("Unknown oEmbed operation status.")
.Build()),
});
}

View File

@@ -0,0 +1,35 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.OEmbed;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.OEmbed;
[Authorize(Policy = AuthorizationPolicies.SectionAccessContent)]
[ApiVersion("1.0")]
public class QueryOEmbedController : OEmbedControllerBase
{
private readonly IOEmbedService _oEmbedService;
public QueryOEmbedController(IOEmbedService oEmbedService)
{
_oEmbedService = oEmbedService;
}
[HttpGet("query")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(OEmbedResponseModel), StatusCodes.Status200OK)]
public async Task<IActionResult> Query(CancellationToken cancellationToken, Uri url, int? maxWidth = null, int? maxHeight = null)
{
Attempt<string, OEmbedOperationStatus> result = await _oEmbedService.GetMarkupAsync(url, maxWidth, maxHeight, cancellationToken);
return result.Success
? Ok(new OEmbedResponseModel() { Markup = result.Result })
: OEmbedOperationStatusResult(result.Status);
}
}

View File

@@ -8331,6 +8331,20 @@
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/PublicAccessResponseModel"
}
]
}
}
}
},
"404": {
"description": "Not Found",
"content": {
@@ -19479,6 +19493,67 @@
]
}
},
"/umbraco/management/api/v1/oembed/query": {
"get": {
"tags": [
"oEmbed"
],
"operationId": "GetOembedQuery",
"parameters": [
{
"name": "url",
"in": "query",
"schema": {
"type": "string",
"format": "uri"
}
},
{
"name": "maxWidth",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "maxHeight",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/OEmbedResponseModel"
}
]
}
}
}
},
"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/package/{name}/run-migration": {
"post": {
"tags": [
@@ -38540,6 +38615,18 @@
},
"additionalProperties": false
},
"OEmbedResponseModel": {
"required": [
"markup"
],
"type": "object",
"properties": {
"markup": {
"type": "string"
}
},
"additionalProperties": false
},
"ObjectTypeResponseModel": {
"required": [
"id"
@@ -40394,6 +40481,52 @@
},
"additionalProperties": false
},
"PublicAccessResponseModel": {
"required": [
"errorDocument",
"groups",
"loginDocument",
"members"
],
"type": "object",
"properties": {
"loginDocument": {
"oneOf": [
{
"$ref": "#/components/schemas/ReferenceByIdModel"
}
]
},
"errorDocument": {
"oneOf": [
{
"$ref": "#/components/schemas/ReferenceByIdModel"
}
]
},
"members": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/MemberItemResponseModel"
}
]
}
},
"groups": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/MemberGroupItemResponseModel"
}
]
}
}
},
"additionalProperties": false
},
"PublishDocumentRequestModel": {
"required": [
"publishSchedules"

View File

@@ -0,0 +1,6 @@
namespace Umbraco.Cms.Api.Management.ViewModels.OEmbed;
public class OEmbedResponseModel
{
public required string Markup { get; set; }
}

View File

@@ -323,6 +323,7 @@ namespace Umbraco.Cms.Core.DependencyInjection
Services.AddUnique<ITemporaryFileService, TemporaryFileService>();
Services.AddUnique<ITemplateContentParserService, TemplateContentParserService>();
Services.AddUnique<IEntityService, EntityService>();
Services.AddUnique<IOEmbedService, OEmbedService>();
Services.AddUnique<IRelationService, RelationService>();
Services.AddUnique<IMemberTypeService, MemberTypeService>();
Services.AddUnique<IMemberContentEditingService, MemberContentEditingService>();

View File

@@ -23,11 +23,17 @@ public class DailyMotion : OEmbedProviderBase
{ "format", "xml" },
};
public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
XmlDocument xmlDocument = base.GetXmlResponse(requestUrl);
XmlDocument xmlDocument = await base.GetXmlResponseAsync(requestUrl, cancellationToken);
return GetXmlProperty(xmlDocument, "/oembed/html");
}
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
}

View File

@@ -20,10 +20,16 @@ public class Flickr : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
XmlDocument xmlDocument = base.GetXmlResponse(requestUrl);
XmlDocument xmlDocument = await base.GetXmlResponseAsync(requestUrl, cancellationToken);
var imageUrl = GetXmlProperty(xmlDocument, "/oembed/url");
var imageWidth = GetXmlProperty(xmlDocument, "/oembed/width");

View File

@@ -20,10 +20,16 @@ public class GettyImages : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
OEmbedResponse? oembed = base.GetJsonResponse<OEmbedResponse>(requestUrl);
OEmbedResponse? oembed = await base.GetJsonResponseAsync<OEmbedResponse>(requestUrl, cancellationToken);
return oembed?.GetHtml();
}

View File

@@ -18,10 +18,16 @@ public class Giphy : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
OEmbedResponse? oembed = base.GetJsonResponse<OEmbedResponse>(requestUrl);
OEmbedResponse? oembed = await base.GetJsonResponseAsync<OEmbedResponse>(requestUrl, cancellationToken);
return oembed?.GetHtml();
}

View File

@@ -18,10 +18,16 @@ public class Hulu : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
OEmbedResponse? oembed = base.GetJsonResponse<OEmbedResponse>(requestUrl);
OEmbedResponse? oembed = await base.GetJsonResponseAsync<OEmbedResponse>(requestUrl, cancellationToken);
return oembed?.GetHtml();
}

View File

@@ -26,10 +26,16 @@ public class Issuu : OEmbedProviderBase
{ "format", "xml" },
};
public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
XmlDocument xmlDocument = base.GetXmlResponse(requestUrl);
XmlDocument xmlDocument = await base.GetXmlResponseAsync(requestUrl, cancellationToken);
return GetXmlProperty(xmlDocument, "/oembed/html");
}

View File

@@ -18,10 +18,16 @@ public class Kickstarter : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
OEmbedResponse? oembed = base.GetJsonResponse<OEmbedResponse>(requestUrl);
OEmbedResponse? oembed = await base.GetJsonResponseAsync<OEmbedResponse>(requestUrl, cancellationToken);
return oembed?.GetHtml();
}

View File

@@ -19,10 +19,16 @@ public class LottieFiles : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = this.GetEmbedProviderUrl(url, maxWidth, maxHeight);
OEmbedResponse? oembed = this.GetJsonResponse<OEmbedResponse>(requestUrl);
OEmbedResponse? oembed = await this.GetJsonResponseAsync<OEmbedResponse>(requestUrl, cancellationToken);
var html = oembed?.GetHtml();
// LottieFiles doesn't seem to support maxwidth and maxheight via oembed

View File

@@ -18,8 +18,12 @@ public abstract class OEmbedProviderBase : IEmbedProvider
public abstract Dictionary<string, string> RequestParams { get; }
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public abstract string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0);
public virtual Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken) => Task.FromResult(GetMarkup(url, maxWidth ?? 0, maxHeight ?? 0));
public virtual string GetEmbedProviderUrl(string url, int? maxWidth, int? maxHeight) => GetEmbedProviderUrl(url, maxWidth ?? 0, maxHeight ?? 0);
public virtual string GetEmbedProviderUrl(string url, int maxWidth, int maxHeight)
{
if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute) == false)
@@ -50,6 +54,7 @@ public abstract class OEmbedProviderBase : IEmbedProvider
return fullUrl.ToString();
}
[Obsolete("Use DownloadResponseAsync instead. This will be removed in Umbraco 15.")]
public virtual string DownloadResponse(string url)
{
if (_httpClient == null)
@@ -65,6 +70,22 @@ public abstract class OEmbedProviderBase : IEmbedProvider
}
}
public virtual async Task<string> DownloadResponseAsync(string url, CancellationToken cancellationToken)
{
if (_httpClient == null)
{
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd(Constants.HttpClients.Headers.UserAgentProductName);
}
using (var request = new HttpRequestMessage(HttpMethod.Get, url))
{
using HttpResponseMessage response = await _httpClient.SendAsync(request, cancellationToken);
return await response.Content.ReadAsStringAsync(cancellationToken);
}
}
[Obsolete("Use GetJsonResponseAsync instead. This will be removed in Umbraco 15.")]
public virtual T? GetJsonResponse<T>(string url)
where T : class
{
@@ -72,6 +93,23 @@ public abstract class OEmbedProviderBase : IEmbedProvider
return _jsonSerializer.Deserialize<T>(response);
}
public virtual async Task<T?> GetJsonResponseAsync<T>(string url, CancellationToken cancellationToken)
where T : class
{
var response = await DownloadResponseAsync(url, cancellationToken);
return _jsonSerializer.Deserialize<T>(response);
}
public virtual async Task<XmlDocument> GetXmlResponseAsync(string url, CancellationToken cancellationToken)
{
var response = await DownloadResponseAsync(url, cancellationToken);
var doc = new XmlDocument();
doc.LoadXml(response);
return doc;
}
[Obsolete("Use GetXmlResponseAsync instead. This will be removed in Umbraco 15.")]
public virtual XmlDocument GetXmlResponse(string url)
{
var response = DownloadResponse(url);

View File

@@ -19,10 +19,16 @@ public class Slideshare : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
XmlDocument xmlDocument = base.GetXmlResponse(requestUrl);
XmlDocument xmlDocument = await base.GetXmlResponseAsync(requestUrl, cancellationToken);
return GetXmlProperty(xmlDocument, "/oembed/html");
}

View File

@@ -19,10 +19,17 @@ public class Soundcloud : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
XmlDocument xmlDocument = base.GetXmlResponse(requestUrl);
XmlDocument xmlDocument = await base.GetXmlResponseAsync(requestUrl, cancellationToken);
return GetXmlProperty(xmlDocument, "/oembed/html");
}

View File

@@ -19,11 +19,18 @@ public class Ted : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
XmlDocument xmlDocument = base.GetXmlResponse(requestUrl);
XmlDocument xmlDocument = await base.GetXmlResponseAsync(requestUrl, cancellationToken);
return GetXmlProperty(xmlDocument, "/oembed/html");
}
}

View File

@@ -18,10 +18,16 @@ public class Twitter : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
OEmbedResponse? oembed = base.GetJsonResponse<OEmbedResponse>(requestUrl);
OEmbedResponse? oembed = await base.GetJsonResponseAsync<OEmbedResponse>(requestUrl, cancellationToken);
return oembed?.GetHtml();
}

View File

@@ -19,10 +19,16 @@ public class Vimeo : OEmbedProviderBase
public override Dictionary<string, string> RequestParams => new();
public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
XmlDocument xmlDocument = base.GetXmlResponse(requestUrl);
XmlDocument xmlDocument = await base.GetXmlResponseAsync(requestUrl, cancellationToken);
return GetXmlProperty(xmlDocument, "/oembed/html");
}

View File

@@ -22,10 +22,16 @@ public class YouTube : OEmbedProviderBase
{ "format", "json" },
};
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
public override string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
{
return GeOEmbedDataAsync(url, maxWidth, maxHeight, CancellationToken.None).GetAwaiter().GetResult();
}
public override async Task<string?> GeOEmbedDataAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
OEmbedResponse? oembed = base.GetJsonResponse<OEmbedResponse>(requestUrl);
OEmbedResponse? oembed = await base.GetJsonResponseAsync<OEmbedResponse>(requestUrl, cancellationToken);
return oembed?.GetHtml();
}

View File

@@ -18,5 +18,7 @@ public interface IEmbedProvider
/// <example>?key=value&amp;key2=value2</example>
Dictionary<string, string> RequestParams { get; }
[Obsolete("Use GetMarkupAsync instead. This will be removed in Umbraco 15.")]
string? GetMarkup(string url, int maxWidth = 0, int maxHeight = 0);
Task<string?> GetMarkupAsync(string url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken) => Task.FromResult(GetMarkup(url, maxWidth ?? 0, maxHeight ?? 0));
}

View File

@@ -1,10 +0,0 @@
namespace Umbraco.Cms.Core.Media;
public class OEmbedResult
{
public OEmbedStatus OEmbedStatus { get; set; }
public bool SupportsDimensions { get; set; }
public string? Markup { get; set; }
}

View File

@@ -1,8 +0,0 @@
namespace Umbraco.Cms.Core.Media;
public enum OEmbedStatus
{
NotSupported,
Error,
Success,
}

View File

@@ -0,0 +1,8 @@
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Core.Services;
public interface IOEmbedService
{
Task<Attempt<string, OEmbedOperationStatus>> GetMarkupAsync(Uri url, int? width, int? height, CancellationToken cancellationToken);
}

View File

@@ -0,0 +1,48 @@
using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Media;
using Umbraco.Cms.Core.Media.EmbedProviders;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Core.Services;
public class OEmbedService : IOEmbedService
{
private readonly EmbedProvidersCollection _embedProvidersCollection;
private readonly ILogger<OEmbedService> _logger;
public OEmbedService(EmbedProvidersCollection embedProvidersCollection, ILogger<OEmbedService> logger)
{
_embedProvidersCollection = embedProvidersCollection;
_logger = logger;
}
public async Task<Attempt<string, OEmbedOperationStatus>> GetMarkupAsync(Uri url, int? maxWidth, int? maxHeight, CancellationToken cancellationToken)
{
// Find the first provider that supports the URL
IEmbedProvider? matchedProvider = _embedProvidersCollection
.FirstOrDefault(provider => provider.UrlSchemeRegex.Any(regex=>new Regex(regex, RegexOptions.IgnoreCase).IsMatch(url.OriginalString)));
if (matchedProvider is null)
{
return Attempt.FailWithStatus(OEmbedOperationStatus.NoSupportedProvider, string.Empty);
}
try
{
var result = await matchedProvider.GetMarkupAsync(url.OriginalString, maxWidth, maxHeight, cancellationToken);
if (result is not null)
{
return Attempt.SucceedWithStatus(OEmbedOperationStatus.Success, result);
}
}
catch (Exception e)
{
_logger.LogError(e, "Unexpected exception happened while trying to get oembed markup. Provider: {Provider}",matchedProvider.GetType().Name);
Attempt.FailWithStatus(OEmbedOperationStatus.UnexpectedException, string.Empty, e);
}
return Attempt.FailWithStatus(OEmbedOperationStatus.ProviderReturnedInvalidResult, string.Empty);
}
}

View File

@@ -0,0 +1,9 @@
namespace Umbraco.Cms.Core.Services.OperationStatus;
public enum OEmbedOperationStatus
{
Success,
NoSupportedProvider,
ProviderReturnedInvalidResult,
UnexpectedException
}