From 3561be6e37b7ec1e610b375de9775965a929d047 Mon Sep 17 00:00:00 2001
From: Andrea Piovanelli <83577153+AndreaPiovanelli@users.noreply.github.com>
Date: Tue, 4 Feb 2025 12:55:39 +0100
Subject: [PATCH] Moved embed video import to a dedicated service. (#8827)

---
 .../Controllers/OEmbedController.cs           | 40 +++------------
 .../Orchard.MediaLibrary.csproj               |  2 +
 .../Services/IOEmbedService.cs                |  7 +++
 .../Services/OEmbedService.cs                 | 51 +++++++++++++++++++
 4 files changed, 67 insertions(+), 33 deletions(-)
 create mode 100644 src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/IOEmbedService.cs
 create mode 100644 src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/OEmbedService.cs

diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/OEmbedController.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/OEmbedController.cs
index 2d42832ef..4ebb94fbd 100644
--- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/OEmbedController.cs
+++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/OEmbedController.cs
@@ -17,12 +17,16 @@ namespace Orchard.MediaLibrary.Controllers {
     [Admin, Themed(false)]
     public class OEmbedController : Controller {
         private readonly IMediaLibraryService _mediaLibraryService;
+        private readonly IOEmbedService _oEmbedService;
 
         public OEmbedController(
             IOrchardServices services,
-            IMediaLibraryService mediaManagerService) {
-            _mediaLibraryService = mediaManagerService;
+            IMediaLibraryService mediaManagerService,
+            IOEmbedService oEmbedService) {
+
             Services = services;
+            _mediaLibraryService = mediaManagerService;
+            _oEmbedService = oEmbedService;
             T = NullLocalizer.Instance;
         }
 
@@ -78,39 +82,9 @@ namespace Orchard.MediaLibrary.Controllers {
                 }
             }
 
-            var webClient = new WebClient { Encoding = Encoding.UTF8 };
             try {
-                // <link rel="alternate" href="http://vimeo.com/api/oembed.xml?url=http%3A%2F%2Fvimeo.com%2F23608259" type="text/xml+oembed">
+                viewModel.Content = _oEmbedService.DownloadMediaData(url);
 
-                var source = webClient.DownloadString(url);
-
-                // seek type="text/xml+oembed" or application/xml+oembed
-                var oembedSignature = source.IndexOf("type=\"text/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
-                if (oembedSignature == -1) {
-                    oembedSignature = source.IndexOf("type=\"application/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
-                }
-                if (oembedSignature != -1) {
-                    var tagStart = source.Substring(0, oembedSignature).LastIndexOf('<');
-                    var tagEnd = source.IndexOf('>', oembedSignature);
-                    var tag = source.Substring(tagStart, tagEnd - tagStart);
-                    var matches = new Regex("href=\"([^\"]+)\"").Matches(tag);
-                    if (matches.Count > 0) {
-                        var href = matches[0].Groups[1].Value;
-                        try {
-                            var content = webClient.DownloadString(Server.HtmlDecode(href));
-                            viewModel.Content = XDocument.Parse(content);
-                        }
-                        catch {
-                            // bubble exception
-                        }
-                    }
-                }
-                if (viewModel.Content == null) {
-                    viewModel.Content = new XDocument(
-                        new XDeclaration("1.0", "utf-8", "yes"),
-                        new XElement("oembed")
-                        );
-                }
                 var root = viewModel.Content.Root;
                 if (!String.IsNullOrWhiteSpace(url)) {
                     root.El("url", url);
diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Orchard.MediaLibrary.csproj b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Orchard.MediaLibrary.csproj
index c896c8e71..bf6e595e4 100644
--- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Orchard.MediaLibrary.csproj
+++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Orchard.MediaLibrary.csproj
@@ -200,7 +200,9 @@
     <Compile Include="Security\MediaAuthorizationEventHandler.cs" />
     <Compile Include="Services\IMediaLibraryService.cs" />
     <Compile Include="Providers\IMediaFolderProvider.cs" />
+    <Compile Include="Services\IOEmbedService.cs" />
     <Compile Include="Services\MediaLibraryService.cs" />
+    <Compile Include="Services\OEmbedService.cs" />
     <Compile Include="Services\Shapes.cs" />
     <Compile Include="Services\XmlRpcHandler.cs" />
     <Compile Include="Settings\MediaLibraryPickerFieldEditorEvents.cs" />
diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/IOEmbedService.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/IOEmbedService.cs
new file mode 100644
index 000000000..a5cb56127
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/IOEmbedService.cs
@@ -0,0 +1,7 @@
+using System.Xml.Linq;
+
+namespace Orchard.MediaLibrary.Services {
+    public interface IOEmbedService : IDependency {
+        XDocument DownloadMediaData(string url);
+    }
+}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/OEmbedService.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/OEmbedService.cs
new file mode 100644
index 000000000..927c1d4af
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/OEmbedService.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Net;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Web;
+using System.Xml.Linq;
+
+namespace Orchard.MediaLibrary.Services {
+    public class OEmbedService : IOEmbedService {
+        public XDocument DownloadMediaData(string url) {
+            var webClient = new WebClient { Encoding = Encoding.UTF8 };
+            XDocument doc = null;
+            try {
+                // <link rel="alternate" href="http://vimeo.com/api/oembed.xml?url=http%3A%2F%2Fvimeo.com%2F23608259" type="text/xml+oembed">
+                var source = webClient.DownloadString(url);
+
+                // seek type="text/xml+oembed" or application/xml+oembed
+                var oembedSignature = source.IndexOf("type=\"text/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
+                if (oembedSignature == -1) {
+                    oembedSignature = source.IndexOf("type=\"application/xml+oembed\"", StringComparison.OrdinalIgnoreCase);
+                }
+                if (oembedSignature != -1) {
+                    var tagStart = source.Substring(0, oembedSignature).LastIndexOf('<');
+                    var tagEnd = source.IndexOf('>', oembedSignature);
+                    var tag = source.Substring(tagStart, tagEnd - tagStart);
+                    var matches = new Regex("href=\"([^\"]+)\"").Matches(tag);
+                    if (matches.Count > 0) {
+                        var href = matches[0].Groups[1].Value;
+                        try {
+                            var content = webClient.DownloadString(HttpUtility.HtmlDecode(href));
+                            doc = XDocument.Parse(content);
+                        } catch {
+                            // bubble exception
+                        }
+                    }
+                }
+            } catch {
+                doc = null;
+            }
+
+            if (doc == null) {
+                doc = new XDocument(
+                    new XDeclaration("1.0", "utf-8", "yes"),
+                    new XElement("oembed")
+                    );
+            }
+
+            return doc;
+        }
+    }
+}
\ No newline at end of file