include url content type when sending post over apub (fixes #2611)

This commit is contained in:
Felix Ableitner 2023-10-27 16:21:06 +02:00
parent c8c355dbe2
commit 5507d2d680
7 changed files with 32 additions and 11 deletions

1
Cargo.lock generated
View file

@ -2654,6 +2654,7 @@ dependencies = [
"lemmy_db_views", "lemmy_db_views",
"lemmy_db_views_actor", "lemmy_db_views_actor",
"lemmy_utils", "lemmy_utils",
"mime",
"moka", "moka",
"once_cell", "once_cell",
"reqwest", "reqwest",

View file

@ -129,6 +129,7 @@ tokio-postgres = "0.7.10"
tokio-postgres-rustls = "0.10.0" tokio-postgres-rustls = "0.10.0"
urlencoding = "2.1.3" urlencoding = "2.1.3"
enum-map = "2.7" enum-map = "2.7"
mime = "0.3.17"
[dependencies] [dependencies]
lemmy_api = { workspace = true } lemmy_api = { workspace = true }

View file

@ -34,6 +34,7 @@ full = [
"futures", "futures",
"once_cell", "once_cell",
"jsonwebtoken", "jsonwebtoken",
"mime"
] ]
[dependencies] [dependencies]
@ -62,6 +63,7 @@ actix-web = { workspace = true, optional = true }
enum-map = { workspace = true } enum-map = { workspace = true }
urlencoding = { workspace = true } urlencoding = { workspace = true }
async-trait = { workspace = true } async-trait = { workspace = true }
mime = { workspace = true, optional = true }
webpage = { version = "1.6", default-features = false, features = [ webpage = { version = "1.6", default-features = false, features = [
"serde", "serde",
], optional = true } ], optional = true }
@ -70,7 +72,6 @@ jsonwebtoken = { version = "8.3.0", optional = true }
# necessary for wasmt compilation # necessary for wasmt compilation
getrandom = { version = "0.2.10", features = ["js"] } getrandom = { version = "0.2.10", features = ["js"] }
task-local-extensions = "0.1.4" task-local-extensions = "0.1.4"
mime = "0.3.17"
[dev-dependencies] [dev-dependencies]
serial_test = { workspace = true } serial_test = { workspace = true }

View file

@ -29,6 +29,8 @@ pub fn client_builder(settings: &Settings) -> ClientBuilder {
} }
/// Fetches metadata for the given link and optionally generates thumbnail. /// Fetches metadata for the given link and optionally generates thumbnail.
///
/// TODO: consider caching the results as it will be called by api then apub send right after each other
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
pub async fn fetch_link_metadata( pub async fn fetch_link_metadata(
url: &Url, url: &Url,
@ -253,7 +255,7 @@ async fn generate_pictrs_thumbnail(
} }
} }
// TODO: get rid of this // TODO: get rid of this by storing content type in db
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn is_image_content_type(client: &ClientWithMiddleware, url: &Url) -> Result<(), LemmyError> { async fn is_image_content_type(client: &ClientWithMiddleware, url: &Url) -> Result<(), LemmyError> {
let response = client.get(url.as_str()).send().await?; let response = client.get(url.as_str()).send().await?;

View file

@ -37,10 +37,11 @@ async-trait = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
reqwest = { workspace = true } reqwest = { workspace = true }
once_cell = { workspace = true } once_cell = { workspace = true }
serde_with = { workspace = true }
mime = { workspace = true }
html2md = "0.2.14" html2md = "0.2.14"
html2text = "0.6.0" html2text = "0.6.0"
stringreader = "0.1.1" stringreader = "0.1.1"
serde_with = { workspace = true }
enum_delegate = "0.2.0" enum_delegate = "0.2.0"
moka = { version = "0.11", features = ["future"] } moka = { version = "0.11", features = ["future"] }

View file

@ -112,6 +112,19 @@ impl Object for ApubPost {
let community = Community::read(&mut context.pool(), community_id).await?; let community = Community::read(&mut context.pool(), community_id).await?;
let language = LanguageTag::new_single(self.language_id, &mut context.pool()).await?; let language = LanguageTag::new_single(self.language_id, &mut context.pool()).await?;
let metadata = match &self.url {
Some(url) => fetch_link_metadata(url, false, &context)
.await
.unwrap_or_default(),
_ => Default::default(),
};
let attachment = self
.url
.clone()
.map(|url| Attachment::new(url, metadata.content_type))
.into_iter()
.collect();
let page = Page { let page = Page {
kind: PageType::Page, kind: PageType::Page,
id: self.ap_id.clone().into(), id: self.ap_id.clone().into(),
@ -122,7 +135,7 @@ impl Object for ApubPost {
content: self.body.as_ref().map(|b| markdown_to_html(b)), content: self.body.as_ref().map(|b| markdown_to_html(b)),
media_type: Some(MediaTypeMarkdownOrHtml::Html), media_type: Some(MediaTypeMarkdownOrHtml::Html),
source: self.body.clone().map(Source::new), source: self.body.clone().map(Source::new),
attachment: self.url.clone().map(Attachment::new).into_iter().collect(), attachment,
image: self.thumbnail_url.clone().map(ImageObject::new), image: self.thumbnail_url.clone().map(ImageObject::new),
comments_enabled: Some(!self.locked), comments_enabled: Some(!self.locked),
sensitive: Some(self.nsfw), sensitive: Some(self.nsfw),

View file

@ -72,24 +72,25 @@ pub struct Page {
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub(crate) struct Link { pub(crate) struct Link {
pub(crate) href: Url, href: Url,
pub(crate) r#type: LinkType, content_type: Option<String>,
r#type: LinkType,
} }
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub(crate) struct Image { pub(crate) struct Image {
#[serde(rename = "type")] #[serde(rename = "type")]
pub(crate) kind: ImageType, kind: ImageType,
pub(crate) url: Url, url: Url,
} }
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub(crate) struct Document { pub(crate) struct Document {
#[serde(rename = "type")] #[serde(rename = "type")]
pub(crate) kind: DocumentType, kind: DocumentType,
pub(crate) url: Url, url: Url,
} }
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
@ -167,9 +168,10 @@ impl Page {
} }
impl Attachment { impl Attachment {
pub(crate) fn new(url: DbUrl) -> Attachment { pub(crate) fn new(url: DbUrl, content_type: Option<String>) -> Attachment {
Attachment::Link(Link { Attachment::Link(Link {
href: url.into(), href: url.into(),
content_type,
r#type: Default::default(), r#type: Default::default(),
}) })
} }