From 339eab01fd6baee187a041742a4b76827f353946 Mon Sep 17 00:00:00 2001
From: Nutomic <me@nutomic.com>
Date: Thu, 2 Jun 2022 21:44:47 +0000
Subject: [PATCH] Embed Peertube videos (#2261)

* Use og:video attribute for embeds, change Post.embed_html to embed_url

* fix clippy
---
 crates/api_common/src/post.rs                 |  6 ++---
 crates/api_common/src/request.rs              | 25 +++++++++++--------
 crates/api_crud/src/post/create.rs            | 12 ++++-----
 crates/api_crud/src/post/update.rs            | 12 ++++-----
 crates/apub/src/objects/post.rs               | 15 ++++++-----
 crates/db_schema/src/impls/post.rs            |  4 +--
 crates/db_schema/src/schema.rs                |  2 +-
 crates/db_schema/src/source/post.rs           |  4 +--
 crates/db_views/src/comment_view.rs           |  2 +-
 crates/db_views/src/post_view.rs              |  2 +-
 .../2022-05-20-135341_embed-url/down.sql      |  2 ++
 migrations/2022-05-20-135341_embed-url/up.sql |  2 ++
 12 files changed, 47 insertions(+), 41 deletions(-)
 create mode 100644 migrations/2022-05-20-135341_embed-url/down.sql
 create mode 100644 migrations/2022-05-20-135341_embed-url/up.sql

diff --git a/crates/api_common/src/post.rs b/crates/api_common/src/post.rs
index 38aceed9..8c05790e 100644
--- a/crates/api_common/src/post.rs
+++ b/crates/api_common/src/post.rs
@@ -1,6 +1,6 @@
 use crate::sensitive::Sensitive;
 use lemmy_db_schema::{
-  newtypes::{CommunityId, PostId, PostReportId},
+  newtypes::{CommunityId, DbUrl, PostId, PostReportId},
   ListingType,
   SortType,
 };
@@ -166,6 +166,6 @@ pub struct GetSiteMetadataResponse {
 pub struct SiteMetadata {
   pub title: Option<String>,
   pub description: Option<String>,
-  pub(crate) image: Option<Url>,
-  pub html: Option<String>,
+  pub(crate) image: Option<DbUrl>,
+  pub embed_video_url: Option<DbUrl>,
 }
diff --git a/crates/api_common/src/request.rs b/crates/api_common/src/request.rs
index c5f75011..85789960 100644
--- a/crates/api_common/src/request.rs
+++ b/crates/api_common/src/request.rs
@@ -1,5 +1,6 @@
 use crate::post::SiteMetadata;
 use encoding::{all::encodings, DecoderTrap};
+use lemmy_db_schema::newtypes::DbUrl;
 use lemmy_utils::{error::LemmyError, settings::structs::Settings, version::VERSION};
 use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
 use reqwest_middleware::ClientWithMiddleware;
@@ -77,16 +78,17 @@ fn html_to_site_metadata(html_bytes: &[u8]) -> Result<SiteMetadata, LemmyError>
     .images
     .get(0)
     .and_then(|ogo| Url::parse(&ogo.url).ok());
-
-  let title = og_title.or(page_title);
-  let description = og_description.or(page_description);
-  let image = og_image;
+  let og_embed_url = page
+    .opengraph
+    .videos
+    .first()
+    .and_then(|v| Url::parse(&v.url).ok());
 
   Ok(SiteMetadata {
-    title,
-    description,
-    image,
-    html: None,
+    title: og_title.or(page_title),
+    description: og_description.or(page_description),
+    image: og_image.map(Into::into),
+    embed_video_url: og_embed_url.map(Into::into),
   })
 }
 
@@ -139,7 +141,7 @@ pub async fn fetch_site_data(
   client: &ClientWithMiddleware,
   settings: &Settings,
   url: Option<&Url>,
-) -> (Option<SiteMetadata>, Option<Url>) {
+) -> (Option<SiteMetadata>, Option<DbUrl>) {
   match &url {
     Some(url) => {
       // Fetch metadata
@@ -179,7 +181,7 @@ pub async fn fetch_site_data(
         .ok()
         .flatten();
 
-      (metadata_option, pictrs_thumbnail)
+      (metadata_option, pictrs_thumbnail.map(Into::into))
     }
     None => (None, None),
   }
@@ -235,8 +237,9 @@ mod tests {
         image: Some(
           Url::parse("https://gitlab.com/uploads/-/system/project/avatar/4877469/iod_logo.png")
             .unwrap()
+            .into()
         ),
-        html: None,
+        embed_video_url: None,
       },
       sample_res
     );
diff --git a/crates/api_crud/src/post/create.rs b/crates/api_crud/src/post/create.rs
index 6ef706d0..9151e3ba 100644
--- a/crates/api_crud/src/post/create.rs
+++ b/crates/api_crud/src/post/create.rs
@@ -86,11 +86,11 @@ impl PerformCrud for CreatePost {
 
     // Fetch post links and pictrs cached image
     let data_url = data.url.as_ref();
-    let (metadata_res, pictrs_thumbnail) =
+    let (metadata_res, thumbnail_url) =
       fetch_site_data(context.client(), &context.settings(), data_url).await;
-    let (embed_title, embed_description, embed_html) = metadata_res
-      .map(|u| (u.title, u.description, u.html))
-      .unwrap_or((None, None, None));
+    let (embed_title, embed_description, embed_video_url) = metadata_res
+      .map(|u| (u.title, u.description, u.embed_video_url))
+      .unwrap_or_default();
 
     let post_form = PostForm {
       name: data.name.trim().to_owned(),
@@ -101,8 +101,8 @@ impl PerformCrud for CreatePost {
       nsfw: data.nsfw,
       embed_title,
       embed_description,
-      embed_html,
-      thumbnail_url: pictrs_thumbnail.map(|u| u.into()),
+      embed_video_url,
+      thumbnail_url,
       ..PostForm::default()
     };
 
diff --git a/crates/api_crud/src/post/update.rs b/crates/api_crud/src/post/update.rs
index 285a08b5..3f3e0c2a 100644
--- a/crates/api_crud/src/post/update.rs
+++ b/crates/api_crud/src/post/update.rs
@@ -69,11 +69,11 @@ impl PerformCrud for EditPost {
 
     // Fetch post links and Pictrs cached image
     let data_url = data.url.as_ref();
-    let (metadata_res, pictrs_thumbnail) =
+    let (metadata_res, thumbnail_url) =
       fetch_site_data(context.client(), &context.settings(), data_url).await;
-    let (embed_title, embed_description, embed_html) = metadata_res
-      .map(|u| (u.title, u.description, u.html))
-      .unwrap_or((None, None, None));
+    let (embed_title, embed_description, embed_video_url) = metadata_res
+      .map(|u| (u.title, u.description, u.embed_video_url))
+      .unwrap_or_default();
 
     let post_form = PostForm {
       creator_id: orig_post.creator_id.to_owned(),
@@ -85,8 +85,8 @@ impl PerformCrud for EditPost {
       updated: Some(naive_now()),
       embed_title,
       embed_description,
-      embed_html,
-      thumbnail_url: pictrs_thumbnail.map(|u| u.into()),
+      embed_video_url,
+      thumbnail_url,
       ..PostForm::default()
     };
 
diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs
index bdefe280..65bcbda6 100644
--- a/crates/apub/src/objects/post.rs
+++ b/crates/apub/src/objects/post.rs
@@ -167,15 +167,14 @@ impl ApubObject for ApubPost {
         // url sent by lemmy (old)
         page.url
       };
-      let thumbnail_url: Option<Url> = page.image.map(|i| i.url);
-      let (metadata_res, pictrs_thumbnail) = if let Some(url) = &url {
+      let (metadata_res, thumbnail_url) = if let Some(url) = &url {
         fetch_site_data(context.client(), &context.settings(), Some(url)).await
       } else {
-        (None, thumbnail_url)
+        (None, page.image.map(|i| i.url.into()))
       };
-      let (embed_title, embed_description, embed_html) = metadata_res
-        .map(|u| (u.title, u.description, u.html))
-        .unwrap_or((None, None, None));
+      let (embed_title, embed_description, embed_video_url) = metadata_res
+        .map(|u| (u.title, u.description, u.embed_video_url))
+        .unwrap_or_default();
       let body_slurs_removed =
         read_from_string_or_source_opt(&page.content, &page.media_type, &page.source)
           .map(|s| remove_slurs(&s, &context.settings().slur_regex()));
@@ -195,8 +194,8 @@ impl ApubObject for ApubPost {
         stickied: page.stickied,
         embed_title,
         embed_description,
-        embed_html,
-        thumbnail_url: pictrs_thumbnail.map(|u| u.into()),
+        embed_video_url,
+        thumbnail_url,
         ap_id: Some(page.id.clone().into()),
         local: Some(false),
       }
diff --git a/crates/db_schema/src/impls/post.rs b/crates/db_schema/src/impls/post.rs
index c878931a..03a4b719 100644
--- a/crates/db_schema/src/impls/post.rs
+++ b/crates/db_schema/src/impls/post.rs
@@ -251,7 +251,7 @@ impl DeleteableOrRemoveable for Post {
     self.body = None;
     self.embed_title = None;
     self.embed_description = None;
-    self.embed_html = None;
+    self.embed_video_url = None;
     self.thumbnail_url = None;
 
     self
@@ -316,7 +316,7 @@ mod tests {
       updated: None,
       embed_title: None,
       embed_description: None,
-      embed_html: None,
+      embed_video_url: None,
       thumbnail_url: None,
       ap_id: inserted_post.ap_id.to_owned(),
       local: true,
diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs
index 666986a6..6146b9e3 100644
--- a/crates/db_schema/src/schema.rs
+++ b/crates/db_schema/src/schema.rs
@@ -357,7 +357,7 @@ table! {
         stickied -> Bool,
         embed_title -> Nullable<Text>,
         embed_description -> Nullable<Text>,
-        embed_html -> Nullable<Text>,
+        embed_video_url -> Nullable<Text>,
         thumbnail_url -> Nullable<Text>,
         ap_id -> Varchar,
         local -> Bool,
diff --git a/crates/db_schema/src/source/post.rs b/crates/db_schema/src/source/post.rs
index a3054e40..f8e7dc36 100644
--- a/crates/db_schema/src/source/post.rs
+++ b/crates/db_schema/src/source/post.rs
@@ -23,7 +23,7 @@ pub struct Post {
   pub stickied: bool,
   pub embed_title: Option<String>,
   pub embed_description: Option<String>,
-  pub embed_html: Option<String>,
+  pub embed_video_url: Option<DbUrl>,
   pub thumbnail_url: Option<DbUrl>,
   pub ap_id: DbUrl,
   pub local: bool,
@@ -47,7 +47,7 @@ pub struct PostForm {
   pub stickied: Option<bool>,
   pub embed_title: Option<String>,
   pub embed_description: Option<String>,
-  pub embed_html: Option<String>,
+  pub embed_video_url: Option<DbUrl>,
   pub thumbnail_url: Option<DbUrl>,
   pub ap_id: Option<DbUrl>,
   pub local: Option<bool>,
diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs
index 87ec3c07..53aac951 100644
--- a/crates/db_views/src/comment_view.rs
+++ b/crates/db_views/src/comment_view.rs
@@ -673,7 +673,7 @@ mod tests {
         nsfw: false,
         embed_title: None,
         embed_description: None,
-        embed_html: None,
+        embed_video_url: None,
         thumbnail_url: None,
         ap_id: inserted_post.ap_id.to_owned(),
         local: true,
diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs
index 2fe6d216..809b9986 100644
--- a/crates/db_views/src/post_view.rs
+++ b/crates/db_views/src/post_view.rs
@@ -646,7 +646,7 @@ mod tests {
         nsfw: false,
         embed_title: None,
         embed_description: None,
-        embed_html: None,
+        embed_video_url: None,
         thumbnail_url: None,
         ap_id: inserted_post.ap_id.to_owned(),
         local: true,
diff --git a/migrations/2022-05-20-135341_embed-url/down.sql b/migrations/2022-05-20-135341_embed-url/down.sql
new file mode 100644
index 00000000..1c4ff1f6
--- /dev/null
+++ b/migrations/2022-05-20-135341_embed-url/down.sql
@@ -0,0 +1,2 @@
+alter table post drop column embed_url;
+alter table post add column embed_video_url text;
\ No newline at end of file
diff --git a/migrations/2022-05-20-135341_embed-url/up.sql b/migrations/2022-05-20-135341_embed-url/up.sql
new file mode 100644
index 00000000..47d0df68
--- /dev/null
+++ b/migrations/2022-05-20-135341_embed-url/up.sql
@@ -0,0 +1,2 @@
+alter table post drop column embed_html;
+alter table post add column embed_video_url text;
\ No newline at end of file
-- 
2.44.1