diff --git a/src/Umbraco.Core/Media/IEmbedProvider.cs b/src/Umbraco.Core/Media/IEmbedProvider.cs
index 62faa45563..99b162e0b7 100644
--- a/src/Umbraco.Core/Media/IEmbedProvider.cs
+++ b/src/Umbraco.Core/Media/IEmbedProvider.cs
@@ -1,8 +1,24 @@
-namespace Umbraco.Core.Media
+using System.Collections.Generic;
+
+namespace Umbraco.Core.Media
{
public interface IEmbedProvider
{
- bool SupportsDimensions { get; }
+ ///
+ /// The OEmbed API Endpoint
+ ///
+ string ApiEndpoint { get; }
+
+ ///
+ /// A string array of Regex patterns to match against the pasted OEmbed URL
+ ///
+ string[] UrlSchemeRegex { get; }
+
+ ///
+ /// A collection of querystring request parameters to append to the API Url
+ ///
+ /// ?key=value&key2=value2
+ Dictionary RequestParams { get; }
string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0);
}
diff --git a/src/Umbraco.Core/Media/IEmbedSettingProvider.cs b/src/Umbraco.Core/Media/IEmbedSettingProvider.cs
deleted file mode 100644
index b9ba611100..0000000000
--- a/src/Umbraco.Core/Media/IEmbedSettingProvider.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Xml;
-
-namespace Umbraco.Core.Media
-{
- public interface IEmbedSettingProvider
- {
- object GetSetting(XmlNode settingNode);
- }
-}
diff --git a/src/Umbraco.Core/Media/Result.cs b/src/Umbraco.Core/Media/OEmbedResult.cs
similarity index 53%
rename from src/Umbraco.Core/Media/Result.cs
rename to src/Umbraco.Core/Media/OEmbedResult.cs
index a8683d03d5..bed07d9b5e 100644
--- a/src/Umbraco.Core/Media/Result.cs
+++ b/src/Umbraco.Core/Media/OEmbedResult.cs
@@ -1,10 +1,8 @@
namespace Umbraco.Core.Media
{
-
- // TODO: Could definitely have done with a better name
- public class Result
+ public class OEmbedResult
{
- public Status Status { get; set; }
+ public OEmbedStatus OEmbedStatus { get; set; }
public bool SupportsDimensions { get; set; }
public string Markup { get; set; }
}
diff --git a/src/Umbraco.Core/Media/Status.cs b/src/Umbraco.Core/Media/OEmbedStatus.cs
similarity index 55%
rename from src/Umbraco.Core/Media/Status.cs
rename to src/Umbraco.Core/Media/OEmbedStatus.cs
index abbcca97da..0f1f22b0e2 100644
--- a/src/Umbraco.Core/Media/Status.cs
+++ b/src/Umbraco.Core/Media/OEmbedStatus.cs
@@ -1,8 +1,6 @@
namespace Umbraco.Core.Media
{
-
- //NOTE: Could definitely have done with a better name
- public enum Status
+ public enum OEmbedStatus
{
NotSupported,
Error,
diff --git a/src/Umbraco.Core/Media/ProviderSetting.cs b/src/Umbraco.Core/Media/ProviderSetting.cs
deleted file mode 100644
index 9fef5efabf..0000000000
--- a/src/Umbraco.Core/Media/ProviderSetting.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System;
-
-namespace Umbraco.Core.Media
-{
- public class ProviderSetting : Attribute
- {
- }
-}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 242b4f67bc..b327a9281d 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -650,10 +650,8 @@
-
-
-
-
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/embed/embed.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/embed/embed.controller.js
index fb66552731..06a5f028ef 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/embed/embed.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/embed/embed.controller.js
@@ -54,21 +54,22 @@
$scope.model.embed.preview = "";
- switch (response.data.Status) {
+
+ switch (response.data.OEmbedStatus) {
case 0:
- //not supported
- $scope.model.embed.info = "Not supported";
- break;
+ //not supported
+ $scope.model.embed.info = "Not supported";
+ break;
case 1:
- //error
- $scope.model.embed.info = "Could not embed media - please ensure the URL is valid";
- break;
+ //error
+ $scope.model.embed.info = "Could not embed media - please ensure the URL is valid";
+ break;
case 2:
- $scope.model.embed.preview = response.data.Markup;
- vm.trustedPreview = $sce.trustAsHtml(response.data.Markup);
- $scope.model.embed.supportsDimensions = response.data.SupportsDimensions;
- $scope.model.embed.success = true;
- break;
+ $scope.model.embed.preview = response.data.Markup;
+ vm.trustedPreview = $sce.trustAsHtml(response.data.Markup);
+ $scope.model.embed.supportsDimensions = response.data.SupportsDimensions;
+ $scope.model.embed.success = true;
+ break;
}
}, function() {
$scope.model.embed.supportsDimensions = false;
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 38f43f344f..e0660f8f12 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -178,9 +178,6 @@
Designer
-
- EmbeddedMedia.config
-
Designer
@@ -300,7 +297,6 @@
Designer
-
diff --git a/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config b/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config
deleted file mode 100644
index 442493e3d6..0000000000
--- a/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config
+++ /dev/null
@@ -1,134 +0,0 @@
-
-
diff --git a/src/Umbraco.Web.UI/config/EmbeddedMedia.config b/src/Umbraco.Web.UI/config/EmbeddedMedia.config
deleted file mode 100644
index c466b14f1c..0000000000
--- a/src/Umbraco.Web.UI/config/EmbeddedMedia.config
+++ /dev/null
@@ -1,134 +0,0 @@
-
-
diff --git a/src/Umbraco.Web/CompositionExtensions.cs b/src/Umbraco.Web/CompositionExtensions.cs
index 6039d97a72..4302cdaeee 100644
--- a/src/Umbraco.Web/CompositionExtensions.cs
+++ b/src/Umbraco.Web/CompositionExtensions.cs
@@ -6,6 +6,7 @@ using Umbraco.Web.ContentApps;
using Umbraco.Web.Dashboards;
using Umbraco.Web.Editors;
using Umbraco.Web.HealthCheck;
+using Umbraco.Web.Media.EmbedProviders;
using Umbraco.Web.Mvc;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
@@ -101,6 +102,13 @@ namespace Umbraco.Web
public static DashboardCollectionBuilder Dashboards(this Composition composition)
=> composition.WithCollectionBuilder();
+ ///
+ /// Gets the backoffice OEmbed Providers collection builder.
+ ///
+ /// The composition.
+ public static EmbedProvidersCollectionBuilder OEmbedProviders(this Composition composition)
+ => composition.WithCollectionBuilder();
+
#endregion
#region Uniques
diff --git a/src/Umbraco.Web/Media/EmbedProviders/AbstractProvider.cs b/src/Umbraco.Web/Media/EmbedProviders/AbstractProvider.cs
deleted file mode 100644
index 32f9f5c5c9..0000000000
--- a/src/Umbraco.Web/Media/EmbedProviders/AbstractProvider.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using Umbraco.Core.Media;
-
-namespace Umbraco.Web.Media.EmbedProviders
-{
- public abstract class AbstractProvider : IEmbedProvider
- {
- public virtual bool SupportsDimensions
- {
- get { return true; }
- }
-
- public abstract string GetMarkup(string url, int maxWidth, int maxHeight);
- }
-}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/DailyMotion.cs b/src/Umbraco.Web/Media/EmbedProviders/DailyMotion.cs
new file mode 100644
index 0000000000..78ea0b8662
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/DailyMotion.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class DailyMotion : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "https://www.dailymotion.com/services/oembed";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"dailymotion.com/video/.*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary()
+ {
+ //ApiUrl/?format=xml
+ {"format", "xml"}
+ };
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var xmlDocument = base.GetXmlResponse(requestUrl);
+
+ return GetXmlProperty(xmlDocument, "/oembed/html");
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/AbstractOEmbedProvider.cs b/src/Umbraco.Web/Media/EmbedProviders/EmbedProviderBase.cs
similarity index 73%
rename from src/Umbraco.Web/Media/EmbedProviders/AbstractOEmbedProvider.cs
rename to src/Umbraco.Web/Media/EmbedProviders/EmbedProviderBase.cs
index c73e732268..9e34815def 100644
--- a/src/Umbraco.Web/Media/EmbedProviders/AbstractOEmbedProvider.cs
+++ b/src/Umbraco.Web/Media/EmbedProviders/EmbedProviderBase.cs
@@ -1,46 +1,39 @@
-using System;
-using System.Text;
-using System.Xml;
+using Newtonsoft.Json;
+using System;
using System.Collections.Generic;
-using System.Net;
+using System.Linq;
using System.Net.Http;
+using System.Text;
using System.Web;
-using Newtonsoft.Json;
+using System.Xml;
using Umbraco.Core.Media;
namespace Umbraco.Web.Media.EmbedProviders
{
- // TODO: Make all Http calls async
-
- public abstract class AbstractOEmbedProvider : IEmbedProvider
+ public abstract class EmbedProviderBase : IEmbedProvider
{
private static HttpClient _httpClient;
- public virtual bool SupportsDimensions
- {
- get { return true; }
- }
+ public abstract string ApiEndpoint { get; }
- [ProviderSetting]
- public string APIEndpoint { get; set; }
+ public abstract string[] UrlSchemeRegex { get; }
- [ProviderSetting]
- public Dictionary RequestParams { get; set; }
+ public abstract Dictionary RequestParams { get; }
+
+ public abstract string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0);
- public abstract string GetMarkup(string url, int maxWidth, int maxHeight);
-
- public virtual string BuildFullUrl(string url, int maxWidth, int maxHeight)
+ public virtual string GetEmbedProviderUrl(string url, int maxWidth, int maxHeight)
{
if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute) == false)
throw new ArgumentException("Not a valid Url");
var fullUrl = new StringBuilder();
- fullUrl.Append(APIEndpoint);
+ fullUrl.Append(ApiEndpoint);
fullUrl.Append("?url=" + HttpUtility.UrlEncode(url));
- foreach (var p in RequestParams)
- fullUrl.Append(string.Format("&{0}={1}", p.Key, p.Value));
+ foreach (var param in RequestParams)
+ fullUrl.Append($"&{param.Key}={param.Value}");
if (maxWidth > 0)
fullUrl.Append("&maxwidth=" + maxWidth);
@@ -50,7 +43,7 @@ namespace Umbraco.Web.Media.EmbedProviders
return fullUrl.ToString();
}
-
+
public virtual string DownloadResponse(string url)
{
if (_httpClient == null)
@@ -83,6 +76,5 @@ namespace Umbraco.Web.Media.EmbedProviders
var selectSingleNode = doc.SelectSingleNode(property);
return selectSingleNode != null ? selectSingleNode.InnerText : string.Empty;
}
-
}
-}
+};
diff --git a/src/Umbraco.Web/Media/EmbedProviders/EmbedProvidersCollection.cs b/src/Umbraco.Web/Media/EmbedProviders/EmbedProvidersCollection.cs
new file mode 100644
index 0000000000..88a317c545
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/EmbedProvidersCollection.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using Umbraco.Core.Composing;
+using Umbraco.Core.Media;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class EmbedProvidersCollection : BuilderCollectionBase
+ {
+ public EmbedProvidersCollection(IEnumerable items)
+ : base(items)
+ { }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/EmbedProvidersCollectionBuilder.cs b/src/Umbraco.Web/Media/EmbedProviders/EmbedProvidersCollectionBuilder.cs
new file mode 100644
index 0000000000..0c6ea7a3e3
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/EmbedProvidersCollectionBuilder.cs
@@ -0,0 +1,10 @@
+using Umbraco.Core.Composing;
+using Umbraco.Core.Media;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class EmbedProvidersCollectionBuilder : OrderedCollectionBuilderBase
+ {
+ protected override EmbedProvidersCollectionBuilder This => this;
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Flickr.cs b/src/Umbraco.Web/Media/EmbedProviders/Flickr.cs
new file mode 100644
index 0000000000..2ce014c639
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/Flickr.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+using System.Web;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class Flickr : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "http://www.flickr.com/services/oembed/";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"flickr.com\/photos\/*",
+ @"flic.kr\/p\/*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary();
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var xmlDocument = base.GetXmlResponse(requestUrl);
+
+ var imageUrl = GetXmlProperty(xmlDocument, "/oembed/url");
+ var imageWidth = GetXmlProperty(xmlDocument, "/oembed/width");
+ var imageHeight = GetXmlProperty(xmlDocument, "/oembed/height");
+ var imageTitle = GetXmlProperty(xmlDocument, "/oembed/title");
+
+ return string.Format("
", imageUrl, imageWidth, imageHeight, HttpUtility.HtmlEncode(imageTitle));
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/GettyImages.cs b/src/Umbraco.Web/Media/EmbedProviders/GettyImages.cs
new file mode 100644
index 0000000000..34b383614d
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/GettyImages.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class GettyImages : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "http://embed.gettyimages.com/oembed";
+
+ //http://gty.im/74917285
+ //http://www.gettyimages.com/detail/74917285
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"gty\.im/*",
+ @"gettyimages.com\/detail\/*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary();
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var oembed = base.GetJsonResponse(requestUrl);
+
+ return oembed.GetHtml();
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Hulu.cs b/src/Umbraco.Web/Media/EmbedProviders/Hulu.cs
new file mode 100644
index 0000000000..150439832a
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/Hulu.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class Hulu : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "http://www.hulu.com/api/oembed.json";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"hulu.com/watch/.*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary();
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var oembed = base.GetJsonResponse(requestUrl);
+
+ return oembed.GetHtml();
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Instagram.cs b/src/Umbraco.Web/Media/EmbedProviders/Instagram.cs
new file mode 100644
index 0000000000..1862d77cad
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/Instagram.cs
@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class Instagram : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "http://api.instagram.com/oembed";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"instagram.com\/p\/*",
+ @"instagr.am\/p\/*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary();
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var oembed = base.GetJsonResponse(requestUrl);
+
+ return oembed.GetHtml();
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Issuu.cs b/src/Umbraco.Web/Media/EmbedProviders/Issuu.cs
new file mode 100644
index 0000000000..2b33473453
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/Issuu.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class Issuu : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "https://issuu.com/oembed";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"issuu.com/.*/docs/.*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary()
+ {
+ //ApiUrl/?format=xml
+ {"format", "xml"}
+ };
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var xmlDocument = base.GetXmlResponse(requestUrl);
+
+ return GetXmlProperty(xmlDocument, "/oembed/html");
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Kickstarter.cs b/src/Umbraco.Web/Media/EmbedProviders/Kickstarter.cs
new file mode 100644
index 0000000000..4de45ae2e3
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/Kickstarter.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class Kickstarter : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "http://www.kickstarter.com/services/oembed";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"kickstarter\.com/projects/*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary();
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var oembed = base.GetJsonResponse(requestUrl);
+
+ return oembed.GetHtml();
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/OEmbedJson.cs b/src/Umbraco.Web/Media/EmbedProviders/OEmbedJson.cs
deleted file mode 100644
index 161294be76..0000000000
--- a/src/Umbraco.Web/Media/EmbedProviders/OEmbedJson.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Umbraco.Web.Media.EmbedProviders
-{
- public class OEmbedJson : AbstractOEmbedProvider
- {
- public override string GetMarkup(string url, int maxWidth, int maxHeight)
- {
- string requestUrl = BuildFullUrl(url, maxWidth, maxHeight);
-
- var jsonResponse = GetJsonResponse(requestUrl);
- return jsonResponse.GetHtml();
- }
- }
-}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/OEmbedPhoto.cs b/src/Umbraco.Web/Media/EmbedProviders/OEmbedPhoto.cs
deleted file mode 100644
index 26dbf38d31..0000000000
--- a/src/Umbraco.Web/Media/EmbedProviders/OEmbedPhoto.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Web;
-using System.Xml;
-
-namespace Umbraco.Web.Media.EmbedProviders
-{
- public class OEmbedPhoto : AbstractOEmbedProvider
- {
- public override string GetMarkup(string url, int maxWidth, int maxHeight)
- {
- string requestUrl = BuildFullUrl(url, maxWidth, maxHeight);
-
- XmlDocument doc = GetXmlResponse(requestUrl);
- string imageUrl = GetXmlProperty(doc, "/oembed/url");
- string imageWidth = GetXmlProperty(doc, "/oembed/width");
- string imageHeight = GetXmlProperty(doc, "/oembed/height");
- string imageTitle = GetXmlProperty(doc, "/oembed/title");
-
- return string.Format("
",
- imageUrl, imageWidth, imageHeight, HttpUtility.HtmlEncode(imageTitle));
- }
- }
-}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/OEmbedResponse.cs b/src/Umbraco.Web/Media/EmbedProviders/OEmbedResponse.cs
index e6577dea1f..64b18f52d3 100644
--- a/src/Umbraco.Web/Media/EmbedProviders/OEmbedResponse.cs
+++ b/src/Umbraco.Web/Media/EmbedProviders/OEmbedResponse.cs
@@ -31,18 +31,18 @@ namespace Umbraco.Web.Media.EmbedProviders
public string ThumbnailUrl { get; set; }
[JsonProperty("thumbnail_height")]
- public int? ThumbnailHeight { get; set; }
+ public double? ThumbnailHeight { get; set; }
[JsonProperty("thumbnail_width")]
- public int? ThumbnailWidth { get; set; }
+ public double? ThumbnailWidth { get; set; }
public string Html { get; set; }
public string Url { get; set; }
- public int? Height { get; set; }
+ public double? Height { get; set; }
- public int? Width { get; set; }
+ public double? Width { get; set; }
///
/// Gets the HTML.
diff --git a/src/Umbraco.Web/Media/EmbedProviders/OEmbedRich.cs b/src/Umbraco.Web/Media/EmbedProviders/OEmbedRich.cs
deleted file mode 100644
index 8f578ada59..0000000000
--- a/src/Umbraco.Web/Media/EmbedProviders/OEmbedRich.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Umbraco.Web.Media.EmbedProviders
-{
- public class OEmbedRich : OEmbedVideo
- {
- }
-}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/OEmbedVideo.cs b/src/Umbraco.Web/Media/EmbedProviders/OEmbedVideo.cs
deleted file mode 100644
index 53bc8602d8..0000000000
--- a/src/Umbraco.Web/Media/EmbedProviders/OEmbedVideo.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Xml;
-
-namespace Umbraco.Web.Media.EmbedProviders
-{
- public class OEmbedVideo : AbstractOEmbedProvider
- {
- public override string GetMarkup(string url, int maxWidth, int maxHeight)
- {
- string requestUrl = BuildFullUrl(url, maxWidth, maxHeight);
-
- XmlDocument doc = GetXmlResponse(requestUrl);
- return GetXmlProperty(doc, "/oembed/html");
- }
- }
-}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Settings/Dictionary.cs b/src/Umbraco.Web/Media/EmbedProviders/Settings/Dictionary.cs
deleted file mode 100644
index 1c0a98205a..0000000000
--- a/src/Umbraco.Web/Media/EmbedProviders/Settings/Dictionary.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Linq;
-using System.Xml;
-using Umbraco.Core.Media;
-
-namespace Umbraco.Web.Media.EmbedProviders.Settings
-{
- public class Dictionary : IEmbedSettingProvider
- {
- public object GetSetting(XmlNode settingNode)
- {
- return settingNode.ChildNodes.Cast().ToDictionary(item => item.Attributes != null ? item.Attributes["name"].Value : null, item => item.InnerText);
- }
- }
-}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Settings/String.cs b/src/Umbraco.Web/Media/EmbedProviders/Settings/String.cs
deleted file mode 100644
index f1d3642d79..0000000000
--- a/src/Umbraco.Web/Media/EmbedProviders/Settings/String.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Xml;
-using Umbraco.Core.Media;
-
-namespace Umbraco.Web.Media.EmbedProviders.Settings
-{
- public class String : IEmbedSettingProvider
- {
- public object GetSetting(XmlNode settingNode)
- {
- return settingNode.InnerText;
- }
- }
-}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Slideshare.cs b/src/Umbraco.Web/Media/EmbedProviders/Slideshare.cs
new file mode 100644
index 0000000000..6d3a010c7a
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/Slideshare.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class Slideshare : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "http://www.slideshare.net/api/oembed/2";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"slideshare\.net/"
+ };
+
+ public override Dictionary RequestParams => new Dictionary();
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var xmlDocument = base.GetXmlResponse(requestUrl);
+
+ return GetXmlProperty(xmlDocument, "/oembed/html");
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/SoundCloud.cs b/src/Umbraco.Web/Media/EmbedProviders/SoundCloud.cs
new file mode 100644
index 0000000000..080437a246
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/SoundCloud.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class Soundcloud : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "https://soundcloud.com/oembed";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"soundcloud.com\/*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary();
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var xmlDocument = base.GetXmlResponse(requestUrl);
+
+ return GetXmlProperty(xmlDocument, "/oembed/html");
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Ted.cs b/src/Umbraco.Web/Media/EmbedProviders/Ted.cs
new file mode 100644
index 0000000000..aa14423349
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/Ted.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class Ted : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "http://www.ted.com/talks/oembed.xml";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"ted.com\/talks\/*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary();
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var xmlDocument = base.GetXmlResponse(requestUrl);
+
+ return GetXmlProperty(xmlDocument, "/oembed/html");
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Twitgoo.cs b/src/Umbraco.Web/Media/EmbedProviders/Twitgoo.cs
deleted file mode 100644
index 3b7816a902..0000000000
--- a/src/Umbraco.Web/Media/EmbedProviders/Twitgoo.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using HtmlAgilityPack;
-
-namespace Umbraco.Web.Media.EmbedProviders
-{
- public class Twitgoo : AbstractProvider
- {
- public override bool SupportsDimensions
- {
- get { return false; }
- }
-
- public override string GetMarkup(string url, int maxWidth, int maxHeight)
- {
- var web = new HtmlWeb();
- var doc = web.Load(url);
-
- var img = doc.DocumentNode.SelectSingleNode("//img [@id = 'fullsize']").Attributes["src"];
-
- return string.Format("
",
- img.Value);
- }
- }
-}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Twitter.cs b/src/Umbraco.Web/Media/EmbedProviders/Twitter.cs
new file mode 100644
index 0000000000..9286934a4d
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/Twitter.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class Twitter : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "http://publish.twitter.com/oembed";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"twitter.com/.*/status/.*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary();
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var oembed = base.GetJsonResponse(requestUrl);
+
+ return oembed.GetHtml();
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Vimeo.cs b/src/Umbraco.Web/Media/EmbedProviders/Vimeo.cs
new file mode 100644
index 0000000000..806f40a10c
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/Vimeo.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class Vimeo : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "https://vimeo.com/api/oembed.xml";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"vimeo\.com/"
+ };
+
+ public override Dictionary RequestParams => new Dictionary();
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var xmlDocument = base.GetXmlResponse(requestUrl);
+
+ return GetXmlProperty(xmlDocument, "/oembed/html");
+ }
+ }
+}
diff --git a/src/Umbraco.Web/Media/EmbedProviders/Youtube.cs b/src/Umbraco.Web/Media/EmbedProviders/Youtube.cs
new file mode 100644
index 0000000000..4e6f437047
--- /dev/null
+++ b/src/Umbraco.Web/Media/EmbedProviders/Youtube.cs
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Web.Media.EmbedProviders
+{
+ public class YouTube : EmbedProviderBase
+ {
+ public override string ApiEndpoint => "https://www.youtube.com/oembed";
+
+ public override string[] UrlSchemeRegex => new string[]
+ {
+ @"youtu.be/.*",
+ @"youtube.com/watch.*"
+ };
+
+ public override Dictionary RequestParams => new Dictionary()
+ {
+ //ApiUrl/?format=json
+ {"format", "json"}
+ };
+
+ public override string GetMarkup(string url, int maxWidth = 0, int maxHeight = 0)
+ {
+ var requestUrl = base.GetEmbedProviderUrl(url, maxWidth, maxHeight);
+ var oembed = base.GetJsonResponse(requestUrl);
+
+ return oembed.GetHtml();
+ }
+ }
+}
diff --git a/src/Umbraco.Web/PropertyEditors/RteEmbedController.cs b/src/Umbraco.Web/PropertyEditors/RteEmbedController.cs
index 4cebc5c829..b3498c16ae 100644
--- a/src/Umbraco.Web/PropertyEditors/RteEmbedController.cs
+++ b/src/Umbraco.Web/PropertyEditors/RteEmbedController.cs
@@ -1,14 +1,10 @@
using System;
-using System.Linq;
using System.Text.RegularExpressions;
-using System.Xml;
-using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Web.Editors;
using Umbraco.Web.Mvc;
using Umbraco.Core.Media;
-using System.IO;
-using Umbraco.Core.IO;
+using Umbraco.Web.Media.EmbedProviders;
namespace Umbraco.Web.PropertyEditors
{
@@ -18,60 +14,56 @@ namespace Umbraco.Web.PropertyEditors
[PluginController("UmbracoApi")]
public class RteEmbedController : UmbracoAuthorizedJsonController
{
- public Result GetEmbed(string url, int width, int height)
+ private EmbedProvidersCollection _embedCollection;
+
+ public RteEmbedController(EmbedProvidersCollection embedCollection)
{
- var result = new Result();
+ _embedCollection = embedCollection ?? throw new ArgumentNullException(nameof(embedCollection));
+ }
- // TODO: cache embed doc
- var xmlConfig = new XmlDocument();
- xmlConfig.Load(IOHelper.GetRootDirectorySafe() + Path.DirectorySeparatorChar + "config" + Path.DirectorySeparatorChar + "EmbeddedMedia.config");
+ public OEmbedResult GetEmbed(string url, int width, int height)
+ {
+ var result = new OEmbedResult();
+ var foundMatch = false;
+ IEmbedProvider matchedProvider = null;
- foreach (XmlNode node in xmlConfig.SelectNodes("//provider"))
+ foreach (var provider in _embedCollection)
{
- var regexPattern = new Regex(node.SelectSingleNode("./urlShemeRegex").InnerText, RegexOptions.IgnoreCase);
-
- if (regexPattern.IsMatch(url))
+ //Url Scheme Regex is an array of possible regex patterns to match against the URL
+ foreach(var urlPattern in provider.UrlSchemeRegex)
{
- var prov = (IEmbedProvider)Activator.CreateInstance(Type.GetType(node.Attributes["type"].Value));
-
- if (node.Attributes["supportsDimensions"] != null)
- result.SupportsDimensions = node.Attributes["supportsDimensions"].Value == "True";
- else
- result.SupportsDimensions = prov.SupportsDimensions;
-
- var settings = node.ChildNodes.Cast().ToDictionary(settingNode => settingNode.Name);
-
- foreach (var prop in prov.GetType().GetProperties().Where(prop => prop.IsDefined(typeof(ProviderSetting), true)))
+ var regexPattern = new Regex(urlPattern, RegexOptions.IgnoreCase);
+ if (regexPattern.IsMatch(url))
{
-
- if (settings.Any(s => s.Key.ToLower() == prop.Name.ToLower()))
- {
- var setting = settings.FirstOrDefault(s => s.Key.ToLower() == prop.Name.ToLower()).Value;
- var settingType = typeof(Media.EmbedProviders.Settings.String);
-
- if (setting.Attributes["type"] != null)
- settingType = Type.GetType(setting.Attributes["type"].Value);
-
- var settingProv = (IEmbedSettingProvider)Activator.CreateInstance(settingType);
- prop.SetValue(prov, settingProv.GetSetting(settings.FirstOrDefault(s => s.Key.ToLower() == prop.Name.ToLower()).Value), null);
- }
+ foundMatch = true;
+ matchedProvider = provider;
+ break;
}
- try
- {
- result.Markup = prov.GetMarkup(url, width, height);
- result.Status = Status.Success;
- }
- catch(Exception ex)
- {
- Logger.Error(ex, "Error embedding url {Url} - width: {Width} height: {Height}", url, width, height);
- result.Status = Status.Error;
- }
-
- return result;
}
+
+ if (foundMatch)
+ break;
+ }
+
+ if(foundMatch == false)
+ {
+ //No matches return/ exit
+ result.OEmbedStatus = OEmbedStatus.NotSupported;
+ return result;
+ }
+
+ try
+ {
+ result.SupportsDimensions = true;
+ result.Markup = matchedProvider.GetMarkup(url, width, height);
+ result.OEmbedStatus = OEmbedStatus.Success;
+ }
+ catch(Exception ex)
+ {
+ Logger.Error(ex, "Error embedding url {Url} - width: {Width} height: {Height}", url, width, height);
+ result.OEmbedStatus = OEmbedStatus.Error;
}
- result.Status = Status.NotSupported;
return result;
}
}
diff --git a/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs b/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs
index 4070ee9ece..b81f2db486 100644
--- a/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs
+++ b/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs
@@ -23,6 +23,7 @@ using Umbraco.Web.Dictionary;
using Umbraco.Web.Editors;
using Umbraco.Web.Features;
using Umbraco.Web.HealthCheck;
+using Umbraco.Web.Media.EmbedProviders;
using Umbraco.Web.Models.PublishedContent;
using Umbraco.Web.Mvc;
using Umbraco.Web.PublishedCache;
@@ -212,6 +213,24 @@ namespace Umbraco.Web.Runtime
// and will filter out those that are not attributed with TreeAttribute
composition.WithCollectionBuilder()
.AddTreeControllers(umbracoApiControllerTypes.Where(x => typeof(TreeControllerBase).IsAssignableFrom(x)));
+
+ // register OEmbed providers - no type scanning - all explicit opt-in of adding types
+ // note: IEmbedProvider is not IDiscoverable - think about it if going for type scanning
+ composition.WithCollectionBuilder()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append();
}
}
}
+
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 709d938ba4..63836931a7 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -143,6 +143,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -657,9 +674,6 @@
-
-
-
@@ -1071,13 +1085,6 @@
-
-
-
-
-
-
-