Add oEmbed endpoint to the management api (#16188)
* OEmbed query endpoint * Log provider instead of url from user
This commit is contained in:
@@ -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()),
|
||||
});
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.OEmbed;
|
||||
|
||||
public class OEmbedResponseModel
|
||||
{
|
||||
public required string Markup { get; set; }
|
||||
}
|
||||
@@ -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>();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -18,5 +18,7 @@ public interface IEmbedProvider
|
||||
/// <example>?key=value&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));
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace Umbraco.Cms.Core.Media;
|
||||
|
||||
public enum OEmbedStatus
|
||||
{
|
||||
NotSupported,
|
||||
Error,
|
||||
Success,
|
||||
}
|
||||
8
src/Umbraco.Core/Services/IOEmbedService.cs
Normal file
8
src/Umbraco.Core/Services/IOEmbedService.cs
Normal 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);
|
||||
}
|
||||
48
src/Umbraco.Core/Services/OEmbedService.cs
Normal file
48
src/Umbraco.Core/Services/OEmbedService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
public enum OEmbedOperationStatus
|
||||
{
|
||||
Success,
|
||||
NoSupportedProvider,
|
||||
ProviderReturnedInvalidResult,
|
||||
UnexpectedException
|
||||
}
|
||||
Reference in New Issue
Block a user