mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-09 09:52:10 +00:00
Migrate towards using page.attachment field for url (ref #2144)
This commit is contained in:
parent
56b275acd4
commit
784f079f73
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -4,9 +4,9 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "activitystreams-kinds"
|
name = "activitystreams-kinds"
|
||||||
version = "0.1.2"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0784e99afd032199d3ed70cefb8eb3a8d1aef15f7f2c4e68d033c4e12bb6079e"
|
checksum = "6d014a4fb8828870b7b46bee6257b9a89d06188ae8d435381ba94f14c8c697d8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"url",
|
"url",
|
||||||
|
|
|
@ -21,7 +21,7 @@ lemmy_db_views_actor = { version = "=0.16.2", path = "../db_views_actor" }
|
||||||
lemmy_api_common = { version = "=0.16.2", path = "../api_common" }
|
lemmy_api_common = { version = "=0.16.2", path = "../api_common" }
|
||||||
lemmy_websocket = { version = "=0.16.2", path = "../websocket" }
|
lemmy_websocket = { version = "=0.16.2", path = "../websocket" }
|
||||||
diesel = "1.4.8"
|
diesel = "1.4.8"
|
||||||
activitystreams-kinds = "0.1.2"
|
activitystreams-kinds = "0.2.1"
|
||||||
bcrypt = "0.10.1"
|
bcrypt = "0.10.1"
|
||||||
chrono = { version = "0.4.19", features = ["serde"] }
|
chrono = { version = "0.4.19", features = ["serde"] }
|
||||||
serde_json = { version = "1.0.72", features = ["preserve_order"] }
|
serde_json = { version = "1.0.72", features = ["preserve_order"] }
|
||||||
|
|
|
@ -19,6 +19,12 @@
|
||||||
"mediaType": "text/markdown"
|
"mediaType": "text/markdown"
|
||||||
},
|
},
|
||||||
"url": "https://lemmy.ml/pictrs/image/xl8W7FZfk9.jpg",
|
"url": "https://lemmy.ml/pictrs/image/xl8W7FZfk9.jpg",
|
||||||
|
"attachment": [
|
||||||
|
{
|
||||||
|
"type": "Link",
|
||||||
|
"href": "https://lemmy.ml/pictrs/image/xl8W7FZfk9.jpg"
|
||||||
|
}
|
||||||
|
],
|
||||||
"commentsEnabled": true,
|
"commentsEnabled": true,
|
||||||
"sensitive": false,
|
"sensitive": false,
|
||||||
"stickied": false,
|
"stickied": false,
|
||||||
|
|
|
@ -19,6 +19,12 @@
|
||||||
"mediaType": "text/markdown"
|
"mediaType": "text/markdown"
|
||||||
},
|
},
|
||||||
"url": "https://lemmy.ml/pictrs/image/xl8W7FZfk9.jpg",
|
"url": "https://lemmy.ml/pictrs/image/xl8W7FZfk9.jpg",
|
||||||
|
"attachment": [
|
||||||
|
{
|
||||||
|
"type": "Link",
|
||||||
|
"href": "https://lemmy.ml/pictrs/image/xl8W7FZfk9.jpg"
|
||||||
|
}
|
||||||
|
],
|
||||||
"commentsEnabled": true,
|
"commentsEnabled": true,
|
||||||
"sensitive": false,
|
"sensitive": false,
|
||||||
"stickied": false,
|
"stickied": false,
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
"mediaType": "text/markdown"
|
"mediaType": "text/markdown"
|
||||||
},
|
},
|
||||||
"url": "https://enterprise.lemmy.ml/pictrs/image/eOtYb9iEiB.png",
|
"url": "https://enterprise.lemmy.ml/pictrs/image/eOtYb9iEiB.png",
|
||||||
|
"attachment": [
|
||||||
|
{
|
||||||
|
"type": "Link",
|
||||||
|
"href": "https://enterprise.lemmy.ml/pictrs/image/eOtYb9iEiB.png"
|
||||||
|
}
|
||||||
|
],
|
||||||
"image": {
|
"image": {
|
||||||
"type": "Image",
|
"type": "Image",
|
||||||
"url": "https://enterprise.lemmy.ml/pictrs/image/eOtYb9iEiB.png"
|
"url": "https://enterprise.lemmy.ml/pictrs/image/eOtYb9iEiB.png"
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl CreateOrUpdatePost {
|
||||||
|
|
||||||
let create_or_update = CreateOrUpdatePost::new(post, actor, &community, kind, context).await?;
|
let create_or_update = CreateOrUpdatePost::new(post, actor, &community, kind, context).await?;
|
||||||
let id = create_or_update.id.clone();
|
let id = create_or_update.id.clone();
|
||||||
let activity = AnnouncableActivities::CreateOrUpdatePost(create_or_update);
|
let activity = AnnouncableActivities::CreateOrUpdatePost(Box::new(create_or_update));
|
||||||
send_activity_in_community(activity, &id, actor, &community, vec![], context).await
|
send_activity_in_community(activity, &id, actor, &community, vec![], context).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ pub enum PersonInboxActivities {
|
||||||
#[activity_handler(LemmyContext)]
|
#[activity_handler(LemmyContext)]
|
||||||
pub enum AnnouncableActivities {
|
pub enum AnnouncableActivities {
|
||||||
CreateOrUpdateComment(CreateOrUpdateComment),
|
CreateOrUpdateComment(CreateOrUpdateComment),
|
||||||
CreateOrUpdatePost(CreateOrUpdatePost),
|
CreateOrUpdatePost(Box<CreateOrUpdatePost>),
|
||||||
Vote(Vote),
|
Vote(Vote),
|
||||||
UndoVote(UndoVote),
|
UndoVote(UndoVote),
|
||||||
Delete(Delete),
|
Delete(Delete),
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub enum PostOrComment {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum PageOrNote {
|
pub enum PageOrNote {
|
||||||
Page(Page),
|
Page(Box<Page>),
|
||||||
Note(Note),
|
Note(Note),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ impl ApubObject for PostOrComment {
|
||||||
) -> Result<Self, LemmyError> {
|
) -> Result<Self, LemmyError> {
|
||||||
Ok(match apub {
|
Ok(match apub {
|
||||||
PageOrNote::Page(p) => PostOrComment::Post(Box::new(
|
PageOrNote::Page(p) => PostOrComment::Post(Box::new(
|
||||||
ApubPost::from_apub(p, context, request_counter).await?,
|
ApubPost::from_apub(*p, context, request_counter).await?,
|
||||||
)),
|
)),
|
||||||
PageOrNote::Note(n) => PostOrComment::Comment(Box::new(
|
PageOrNote::Note(n) => PostOrComment::Comment(Box::new(
|
||||||
ApubComment::from_apub(n, context, request_counter).await?,
|
ApubComment::from_apub(n, context, request_counter).await?,
|
||||||
|
|
|
@ -130,6 +130,18 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn deserialize_skip_error<'de, T, D>(deserializer: D) -> Result<T, D::Error>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de> + Default,
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let result = Deserialize::deserialize(deserializer);
|
||||||
|
Ok(match result {
|
||||||
|
Ok(o) => o,
|
||||||
|
Err(_) => Default::default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub enum EndpointType {
|
pub enum EndpointType {
|
||||||
Community,
|
Community,
|
||||||
Person,
|
Person,
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
objects::read_from_string_or_source,
|
objects::read_from_string_or_source,
|
||||||
protocol::{
|
protocol::{
|
||||||
objects::{note::Note, tombstone::Tombstone},
|
objects::{note::Note, tombstone::Tombstone},
|
||||||
SourceCompat,
|
Source,
|
||||||
},
|
},
|
||||||
PostOrComment,
|
PostOrComment,
|
||||||
};
|
};
|
||||||
|
@ -118,7 +118,7 @@ impl ApubObject for ApubComment {
|
||||||
cc: maa.ccs,
|
cc: maa.ccs,
|
||||||
content: markdown_to_html(&self.content),
|
content: markdown_to_html(&self.content),
|
||||||
media_type: Some(MediaTypeHtml::Html),
|
media_type: Some(MediaTypeHtml::Html),
|
||||||
source: Some(SourceCompat::new(self.content.clone())),
|
source: Some(Source::new(self.content.clone())),
|
||||||
in_reply_to,
|
in_reply_to,
|
||||||
published: Some(convert_datetime(self.published)),
|
published: Some(convert_datetime(self.published)),
|
||||||
updated: self.updated.map(convert_datetime),
|
updated: self.updated.map(convert_datetime),
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
protocol::{
|
protocol::{
|
||||||
objects::{group::Group, tombstone::Tombstone, Endpoints},
|
objects::{group::Group, tombstone::Tombstone, Endpoints},
|
||||||
ImageObject,
|
ImageObject,
|
||||||
SourceCompat,
|
Source,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use activitystreams_kinds::actor::GroupType;
|
use activitystreams_kinds::actor::GroupType;
|
||||||
|
@ -87,7 +87,7 @@ impl ApubObject for ApubCommunity {
|
||||||
preferred_username: self.name.clone(),
|
preferred_username: self.name.clone(),
|
||||||
name: Some(self.title.clone()),
|
name: Some(self.title.clone()),
|
||||||
summary: self.description.as_ref().map(|b| markdown_to_html(b)),
|
summary: self.description.as_ref().map(|b| markdown_to_html(b)),
|
||||||
source: self.description.clone().map(SourceCompat::new),
|
source: self.description.clone().map(Source::new),
|
||||||
icon: self.icon.clone().map(ImageObject::new),
|
icon: self.icon.clone().map(ImageObject::new),
|
||||||
image: self.banner.clone().map(ImageObject::new),
|
image: self.banner.clone().map(ImageObject::new),
|
||||||
sensitive: Some(self.nsfw),
|
sensitive: Some(self.nsfw),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
check_is_apub_id_valid,
|
check_is_apub_id_valid,
|
||||||
objects::{read_from_string_or_source_opt, verify_image_domain_matches},
|
objects::{read_from_string_or_source_opt, verify_image_domain_matches},
|
||||||
protocol::{objects::instance::Instance, ImageObject, SourceCompat},
|
protocol::{objects::instance::Instance, ImageObject, Source},
|
||||||
};
|
};
|
||||||
use activitystreams_kinds::actor::ServiceType;
|
use activitystreams_kinds::actor::ServiceType;
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
|
@ -77,7 +77,7 @@ impl ApubObject for ApubSite {
|
||||||
id: ObjectId::new(self.actor_id()),
|
id: ObjectId::new(self.actor_id()),
|
||||||
name: self.name.clone(),
|
name: self.name.clone(),
|
||||||
content: self.sidebar.as_ref().map(|d| markdown_to_html(d)),
|
content: self.sidebar.as_ref().map(|d| markdown_to_html(d)),
|
||||||
source: self.sidebar.clone().map(SourceCompat::new),
|
source: self.sidebar.clone().map(Source::new),
|
||||||
summary: self.description.clone(),
|
summary: self.description.clone(),
|
||||||
media_type: self.sidebar.as_ref().map(|_| MediaTypeHtml::Html),
|
media_type: self.sidebar.as_ref().map(|_| MediaTypeHtml::Html),
|
||||||
icon: self.icon.clone().map(ImageObject::new),
|
icon: self.icon.clone().map(ImageObject::new),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::protocol::{ImageObject, SourceCompat};
|
use crate::protocol::{ImageObject, Source};
|
||||||
use html2md::parse_html;
|
use html2md::parse_html;
|
||||||
use lemmy_apub_lib::verify::verify_domains_match;
|
use lemmy_apub_lib::verify::verify_domains_match;
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
|
@ -11,8 +11,8 @@ pub mod person;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
pub mod private_message;
|
pub mod private_message;
|
||||||
|
|
||||||
pub(crate) fn read_from_string_or_source(raw: &str, source: &Option<SourceCompat>) -> String {
|
pub(crate) fn read_from_string_or_source(raw: &str, source: &Option<Source>) -> String {
|
||||||
if let Some(SourceCompat::Lemmy(s)) = source {
|
if let Some(s) = source {
|
||||||
s.content.clone()
|
s.content.clone()
|
||||||
} else {
|
} else {
|
||||||
parse_html(raw)
|
parse_html(raw)
|
||||||
|
@ -21,9 +21,9 @@ pub(crate) fn read_from_string_or_source(raw: &str, source: &Option<SourceCompat
|
||||||
|
|
||||||
pub(crate) fn read_from_string_or_source_opt(
|
pub(crate) fn read_from_string_or_source_opt(
|
||||||
raw: &Option<String>,
|
raw: &Option<String>,
|
||||||
source: &Option<SourceCompat>,
|
source: &Option<Source>,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
if let Some(SourceCompat::Lemmy(s2)) = source {
|
if let Some(s2) = source {
|
||||||
Some(s2.content.clone())
|
Some(s2.content.clone())
|
||||||
} else {
|
} else {
|
||||||
raw.as_ref().map(|s| parse_html(s))
|
raw.as_ref().map(|s| parse_html(s))
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
Endpoints,
|
Endpoints,
|
||||||
},
|
},
|
||||||
ImageObject,
|
ImageObject,
|
||||||
SourceCompat,
|
Source,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
|
@ -99,7 +99,7 @@ impl ApubObject for ApubPerson {
|
||||||
preferred_username: self.name.clone(),
|
preferred_username: self.name.clone(),
|
||||||
name: self.display_name.clone(),
|
name: self.display_name.clone(),
|
||||||
summary: self.bio.as_ref().map(|b| markdown_to_html(b)),
|
summary: self.bio.as_ref().map(|b| markdown_to_html(b)),
|
||||||
source: self.bio.clone().map(SourceCompat::new),
|
source: self.bio.clone().map(Source::new),
|
||||||
icon: self.avatar.clone().map(ImageObject::new),
|
icon: self.avatar.clone().map(ImageObject::new),
|
||||||
image: self.banner.clone().map(ImageObject::new),
|
image: self.banner.clone().map(ImageObject::new),
|
||||||
matrix_user_id: self.matrix_user_id.clone(),
|
matrix_user_id: self.matrix_user_id.clone(),
|
||||||
|
|
|
@ -4,11 +4,11 @@ use crate::{
|
||||||
objects::read_from_string_or_source_opt,
|
objects::read_from_string_or_source_opt,
|
||||||
protocol::{
|
protocol::{
|
||||||
objects::{
|
objects::{
|
||||||
page::{Page, PageType},
|
page::{Attachment, Page, PageType},
|
||||||
tombstone::Tombstone,
|
tombstone::Tombstone,
|
||||||
},
|
},
|
||||||
ImageObject,
|
ImageObject,
|
||||||
SourceCompat,
|
Source,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use activitystreams_kinds::public;
|
use activitystreams_kinds::public;
|
||||||
|
@ -110,8 +110,9 @@ impl ApubObject for ApubPost {
|
||||||
name: self.name.clone(),
|
name: self.name.clone(),
|
||||||
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(MediaTypeHtml::Html),
|
media_type: Some(MediaTypeHtml::Html),
|
||||||
source: self.body.clone().map(SourceCompat::new),
|
source: self.body.clone().map(Source::new),
|
||||||
url: self.url.clone().map(|u| u.into()),
|
url: self.url.clone().map(|u| u.into()),
|
||||||
|
attachment: self.url.clone().map(Attachment::new).into_iter().collect(),
|
||||||
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),
|
||||||
|
@ -160,8 +161,13 @@ impl ApubObject for ApubPost {
|
||||||
.await?;
|
.await?;
|
||||||
let community = page.extract_community(context, request_counter).await?;
|
let community = page.extract_community(context, request_counter).await?;
|
||||||
|
|
||||||
|
let url = if let Some(attachment) = page.attachment.first() {
|
||||||
|
Some(attachment.href.clone())
|
||||||
|
} else {
|
||||||
|
page.url
|
||||||
|
};
|
||||||
let thumbnail_url: Option<Url> = page.image.map(|i| i.url);
|
let thumbnail_url: Option<Url> = page.image.map(|i| i.url);
|
||||||
let (metadata_res, pictrs_thumbnail) = if let Some(url) = &page.url {
|
let (metadata_res, pictrs_thumbnail) = if let Some(url) = &url {
|
||||||
fetch_site_data(context.client(), &context.settings(), Some(url)).await
|
fetch_site_data(context.client(), &context.settings(), Some(url)).await
|
||||||
} else {
|
} else {
|
||||||
(None, thumbnail_url)
|
(None, thumbnail_url)
|
||||||
|
@ -173,8 +179,8 @@ impl ApubObject for ApubPost {
|
||||||
let body_slurs_removed = read_from_string_or_source_opt(&page.content, &page.source)
|
let body_slurs_removed = read_from_string_or_source_opt(&page.content, &page.source)
|
||||||
.map(|s| remove_slurs(&s, &context.settings().slur_regex()));
|
.map(|s| remove_slurs(&s, &context.settings().slur_regex()));
|
||||||
let form = PostForm {
|
let form = PostForm {
|
||||||
name: page.name,
|
name: page.name.clone(),
|
||||||
url: page.url.map(|u| u.into()),
|
url: url.map(Into::into),
|
||||||
body: body_slurs_removed,
|
body: body_slurs_removed,
|
||||||
creator_id: creator.id,
|
creator_id: creator.id,
|
||||||
community_id: community.id,
|
community_id: community.id,
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
objects::read_from_string_or_source,
|
objects::read_from_string_or_source,
|
||||||
protocol::{
|
protocol::{
|
||||||
objects::chat_message::{ChatMessage, ChatMessageType},
|
objects::chat_message::{ChatMessage, ChatMessageType},
|
||||||
SourceCompat,
|
Source,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
|
@ -90,7 +90,7 @@ impl ApubObject for ApubPrivateMessage {
|
||||||
to: [ObjectId::new(recipient.actor_id)],
|
to: [ObjectId::new(recipient.actor_id)],
|
||||||
content: markdown_to_html(&self.content),
|
content: markdown_to_html(&self.content),
|
||||||
media_type: Some(MediaTypeHtml::Html),
|
media_type: Some(MediaTypeHtml::Html),
|
||||||
source: Some(SourceCompat::new(self.content.clone())),
|
source: Some(Source::new(self.content.clone())),
|
||||||
published: Some(convert_datetime(self.published)),
|
published: Some(convert_datetime(self.published)),
|
||||||
updated: self.updated.map(convert_datetime),
|
updated: self.updated.map(convert_datetime),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use activitystreams_kinds::object::ImageType;
|
use activitystreams_kinds::object::ImageType;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
use lemmy_apub_lib::values::MediaTypeMarkdown;
|
use lemmy_apub_lib::values::MediaTypeMarkdown;
|
||||||
use lemmy_db_schema::newtypes::DbUrl;
|
use lemmy_db_schema::newtypes::DbUrl;
|
||||||
use serde_json::Value;
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
pub mod activities;
|
pub mod activities;
|
||||||
pub(crate) mod collections;
|
pub(crate) mod collections;
|
||||||
|
@ -18,20 +16,12 @@ pub struct Source {
|
||||||
pub(crate) media_type: MediaTypeMarkdown,
|
pub(crate) media_type: MediaTypeMarkdown,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
impl Source {
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub(crate) enum SourceCompat {
|
|
||||||
Lemmy(Source),
|
|
||||||
Other(Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SourceCompat {
|
|
||||||
pub(crate) fn new(content: String) -> Self {
|
pub(crate) fn new(content: String) -> Self {
|
||||||
SourceCompat::Lemmy(Source {
|
Source {
|
||||||
content,
|
content,
|
||||||
media_type: MediaTypeMarkdown::Markdown,
|
media_type: MediaTypeMarkdown::Markdown,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
|
objects::{person::ApubPerson, private_message::ApubPrivateMessage},
|
||||||
protocol::SourceCompat,
|
protocol::Source,
|
||||||
};
|
};
|
||||||
use chrono::{DateTime, FixedOffset};
|
use chrono::{DateTime, FixedOffset};
|
||||||
use lemmy_apub_lib::{object_id::ObjectId, values::MediaTypeHtml};
|
use lemmy_apub_lib::{object_id::ObjectId, values::MediaTypeHtml};
|
||||||
|
@ -19,7 +19,9 @@ pub struct ChatMessage {
|
||||||
pub(crate) content: String,
|
pub(crate) content: String,
|
||||||
|
|
||||||
pub(crate) media_type: Option<MediaTypeHtml>,
|
pub(crate) media_type: Option<MediaTypeHtml>,
|
||||||
pub(crate) source: Option<SourceCompat>,
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_skip_error")]
|
||||||
|
pub(crate) source: Option<Source>,
|
||||||
pub(crate) published: Option<DateTime<FixedOffset>>,
|
pub(crate) published: Option<DateTime<FixedOffset>>,
|
||||||
pub(crate) updated: Option<DateTime<FixedOffset>>,
|
pub(crate) updated: Option<DateTime<FixedOffset>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
read_from_string_or_source_opt,
|
read_from_string_or_source_opt,
|
||||||
verify_image_domain_matches,
|
verify_image_domain_matches,
|
||||||
},
|
},
|
||||||
protocol::{objects::Endpoints, ImageObject, SourceCompat},
|
protocol::{objects::Endpoints, ImageObject, Source},
|
||||||
};
|
};
|
||||||
use activitystreams_kinds::actor::GroupType;
|
use activitystreams_kinds::actor::GroupType;
|
||||||
use chrono::{DateTime, FixedOffset};
|
use chrono::{DateTime, FixedOffset};
|
||||||
|
@ -40,7 +40,9 @@ pub struct Group {
|
||||||
/// title
|
/// title
|
||||||
pub(crate) name: Option<String>,
|
pub(crate) name: Option<String>,
|
||||||
pub(crate) summary: Option<String>,
|
pub(crate) summary: Option<String>,
|
||||||
pub(crate) source: Option<SourceCompat>,
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_skip_error")]
|
||||||
|
pub(crate) source: Option<Source>,
|
||||||
pub(crate) icon: Option<ImageObject>,
|
pub(crate) icon: Option<ImageObject>,
|
||||||
/// banner
|
/// banner
|
||||||
pub(crate) image: Option<ImageObject>,
|
pub(crate) image: Option<ImageObject>,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
objects::instance::ApubSite,
|
objects::instance::ApubSite,
|
||||||
protocol::{ImageObject, SourceCompat},
|
protocol::{ImageObject, Source},
|
||||||
};
|
};
|
||||||
use activitystreams_kinds::actor::ServiceType;
|
use activitystreams_kinds::actor::ServiceType;
|
||||||
use chrono::{DateTime, FixedOffset};
|
use chrono::{DateTime, FixedOffset};
|
||||||
|
@ -25,7 +25,9 @@ pub struct Instance {
|
||||||
|
|
||||||
// sidebar
|
// sidebar
|
||||||
pub(crate) content: Option<String>,
|
pub(crate) content: Option<String>,
|
||||||
pub(crate) source: Option<SourceCompat>,
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_skip_error")]
|
||||||
|
pub(crate) source: Option<Source>,
|
||||||
// short instance description
|
// short instance description
|
||||||
pub(crate) summary: Option<String>,
|
pub(crate) summary: Option<String>,
|
||||||
pub(crate) media_type: Option<MediaTypeHtml>,
|
pub(crate) media_type: Option<MediaTypeHtml>,
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
fetcher::post_or_comment::PostOrComment,
|
fetcher::post_or_comment::PostOrComment,
|
||||||
mentions::Mention,
|
mentions::Mention,
|
||||||
objects::{comment::ApubComment, person::ApubPerson, post::ApubPost},
|
objects::{comment::ApubComment, person::ApubPerson, post::ApubPost},
|
||||||
protocol::SourceCompat,
|
protocol::Source,
|
||||||
};
|
};
|
||||||
use activitystreams_kinds::object::NoteType;
|
use activitystreams_kinds::object::NoteType;
|
||||||
use chrono::{DateTime, FixedOffset};
|
use chrono::{DateTime, FixedOffset};
|
||||||
|
@ -32,7 +32,9 @@ pub struct Note {
|
||||||
pub(crate) in_reply_to: ObjectId<PostOrComment>,
|
pub(crate) in_reply_to: ObjectId<PostOrComment>,
|
||||||
|
|
||||||
pub(crate) media_type: Option<MediaTypeHtml>,
|
pub(crate) media_type: Option<MediaTypeHtml>,
|
||||||
pub(crate) source: Option<SourceCompat>,
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_skip_error")]
|
||||||
|
pub(crate) source: Option<Source>,
|
||||||
pub(crate) published: Option<DateTime<FixedOffset>>,
|
pub(crate) published: Option<DateTime<FixedOffset>>,
|
||||||
pub(crate) updated: Option<DateTime<FixedOffset>>,
|
pub(crate) updated: Option<DateTime<FixedOffset>>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost},
|
objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost},
|
||||||
protocol::{ImageObject, SourceCompat},
|
protocol::{ImageObject, Source},
|
||||||
};
|
};
|
||||||
|
use activitystreams_kinds::link::LinkType;
|
||||||
use chrono::{DateTime, FixedOffset};
|
use chrono::{DateTime, FixedOffset};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use lemmy_apub_lib::{
|
use lemmy_apub_lib::{
|
||||||
|
@ -10,6 +11,7 @@ use lemmy_apub_lib::{
|
||||||
traits::{ActivityHandler, ApubObject},
|
traits::{ActivityHandler, ApubObject},
|
||||||
values::MediaTypeHtml,
|
values::MediaTypeHtml,
|
||||||
};
|
};
|
||||||
|
use lemmy_db_schema::newtypes::DbUrl;
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -39,8 +41,15 @@ pub struct Page {
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
pub(crate) content: Option<String>,
|
pub(crate) content: Option<String>,
|
||||||
pub(crate) media_type: Option<MediaTypeHtml>,
|
pub(crate) media_type: Option<MediaTypeHtml>,
|
||||||
pub(crate) source: Option<SourceCompat>,
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_skip_error")]
|
||||||
|
pub(crate) source: Option<Source>,
|
||||||
|
/// deprecated, use attachment field
|
||||||
pub(crate) url: Option<Url>,
|
pub(crate) url: Option<Url>,
|
||||||
|
/// most software uses array type for attachment field, so we do the same. nevertheless, we only
|
||||||
|
/// use the first item
|
||||||
|
#[serde(default)]
|
||||||
|
pub(crate) attachment: Vec<Attachment>,
|
||||||
pub(crate) image: Option<ImageObject>,
|
pub(crate) image: Option<ImageObject>,
|
||||||
pub(crate) comments_enabled: Option<bool>,
|
pub(crate) comments_enabled: Option<bool>,
|
||||||
pub(crate) sensitive: Option<bool>,
|
pub(crate) sensitive: Option<bool>,
|
||||||
|
@ -49,6 +58,13 @@ pub struct Page {
|
||||||
pub(crate) updated: Option<DateTime<FixedOffset>>,
|
pub(crate) updated: Option<DateTime<FixedOffset>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Attachment {
|
||||||
|
pub(crate) href: Url,
|
||||||
|
pub(crate) r#type: LinkType,
|
||||||
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
/// Only mods can change the post's stickied/locked status. So if either of these is changed from
|
/// Only mods can change the post's stickied/locked status. So if either of these is changed from
|
||||||
/// the current value, it is a mod action and needs to be verified as such.
|
/// the current value, it is a mod action and needs to be verified as such.
|
||||||
|
@ -89,6 +105,15 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Attachment {
|
||||||
|
pub(crate) fn new(url: DbUrl) -> Attachment {
|
||||||
|
Attachment {
|
||||||
|
href: url.into(),
|
||||||
|
r#type: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Used for community outbox, so that it can be compatible with Pleroma/Mastodon.
|
// Used for community outbox, so that it can be compatible with Pleroma/Mastodon.
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ActivityHandler for Page {
|
impl ActivityHandler for Page {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
objects::person::ApubPerson,
|
objects::person::ApubPerson,
|
||||||
protocol::{objects::Endpoints, ImageObject, SourceCompat},
|
protocol::{objects::Endpoints, ImageObject, Source},
|
||||||
};
|
};
|
||||||
use chrono::{DateTime, FixedOffset};
|
use chrono::{DateTime, FixedOffset};
|
||||||
use lemmy_apub_lib::{object_id::ObjectId, signatures::PublicKey};
|
use lemmy_apub_lib::{object_id::ObjectId, signatures::PublicKey};
|
||||||
|
@ -31,7 +31,9 @@ pub struct Person {
|
||||||
/// displayname
|
/// displayname
|
||||||
pub(crate) name: Option<String>,
|
pub(crate) name: Option<String>,
|
||||||
pub(crate) summary: Option<String>,
|
pub(crate) summary: Option<String>,
|
||||||
pub(crate) source: Option<SourceCompat>,
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_skip_error")]
|
||||||
|
pub(crate) source: Option<Source>,
|
||||||
/// user avatar
|
/// user avatar
|
||||||
pub(crate) icon: Option<ImageObject>,
|
pub(crate) icon: Option<ImageObject>,
|
||||||
/// user banner
|
/// user banner
|
||||||
|
|
Loading…
Reference in a new issue