mirror of https://github.com/LemmyNet/lemmy.git
Merge traits ToApub and FromApub into ApubObject
parent
f4bac6a17f
commit
20af10dddf
|
@ -21,7 +21,7 @@ use activitystreams::{base::AnyBase, link::Mention, primitives::OneOrMany, unpar
|
|||
use lemmy_api_common::{blocking, check_post_deleted_or_removed};
|
||||
use lemmy_apub_lib::{
|
||||
data::Data,
|
||||
traits::{ActivityFields, ActivityHandler, ActorType, FromApub, ToApub},
|
||||
traits::{ActivityFields, ActivityHandler, ActorType, ApubObject},
|
||||
values::PublicUrl,
|
||||
verify::verify_domains_match,
|
||||
};
|
||||
|
@ -77,7 +77,7 @@ impl CreateOrUpdateComment {
|
|||
let create_or_update = CreateOrUpdateComment {
|
||||
actor: ObjectId::new(actor.actor_id()),
|
||||
to: [PublicUrl::Public],
|
||||
object: comment.to_apub(context.pool()).await?,
|
||||
object: comment.to_apub(context).await?,
|
||||
cc: maa.ccs,
|
||||
tag: maa.tags,
|
||||
kind,
|
||||
|
|
|
@ -22,7 +22,7 @@ use activitystreams::{
|
|||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::{
|
||||
data::Data,
|
||||
traits::{ActivityFields, ActivityHandler, ActorType, ToApub},
|
||||
traits::{ActivityFields, ActivityHandler, ActorType, ApubObject},
|
||||
values::PublicUrl,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
|
@ -66,7 +66,7 @@ impl UpdateCommunity {
|
|||
let update = UpdateCommunity {
|
||||
actor: ObjectId::new(actor.actor_id()),
|
||||
to: [PublicUrl::Public],
|
||||
object: community.to_apub(context.pool()).await?,
|
||||
object: community.to_apub(context).await?,
|
||||
cc: [ObjectId::new(community.actor_id())],
|
||||
kind: UpdateType::Update,
|
||||
id: id.clone(),
|
||||
|
|
|
@ -21,7 +21,7 @@ use anyhow::anyhow;
|
|||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::{
|
||||
data::Data,
|
||||
traits::{ActivityFields, ActivityHandler, ActorType, FromApub, ToApub},
|
||||
traits::{ActivityFields, ActivityHandler, ActorType, ApubObject},
|
||||
values::PublicUrl,
|
||||
verify::{verify_domains_match, verify_urls_match},
|
||||
};
|
||||
|
@ -68,7 +68,7 @@ impl CreateOrUpdatePost {
|
|||
let create_or_update = CreateOrUpdatePost {
|
||||
actor: ObjectId::new(actor.actor_id()),
|
||||
to: [PublicUrl::Public],
|
||||
object: post.to_apub(context.pool()).await?,
|
||||
object: post.to_apub(context).await?,
|
||||
cc: [ObjectId::new(community.actor_id())],
|
||||
kind,
|
||||
id: id.clone(),
|
||||
|
|
|
@ -12,7 +12,7 @@ use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed};
|
|||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::{
|
||||
data::Data,
|
||||
traits::{ActivityFields, ActivityHandler, ActorType, FromApub, ToApub},
|
||||
traits::{ActivityFields, ActivityHandler, ActorType, ApubObject},
|
||||
verify::verify_domains_match,
|
||||
};
|
||||
use lemmy_db_schema::{source::person::Person, traits::Crud};
|
||||
|
@ -58,7 +58,7 @@ impl CreateOrUpdatePrivateMessage {
|
|||
id: id.clone(),
|
||||
actor: ObjectId::new(actor.actor_id()),
|
||||
to: ObjectId::new(recipient.actor_id()),
|
||||
object: private_message.to_apub(context.pool()).await?,
|
||||
object: private_message.to_apub(context).await?,
|
||||
kind,
|
||||
unparsed: Default::default(),
|
||||
};
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
use crate::fetcher::should_refetch_actor;
|
||||
use anyhow::anyhow;
|
||||
use diesel::NotFound;
|
||||
use lemmy_apub_lib::{
|
||||
traits::{ApubObject, FromApub},
|
||||
APUB_JSON_CONTENT_TYPE,
|
||||
};
|
||||
use lemmy_apub_lib::{traits::ApubObject, APUB_JSON_CONTENT_TYPE};
|
||||
use lemmy_db_schema::newtypes::DbUrl;
|
||||
use lemmy_utils::{request::retry, settings::structs::Settings, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
@ -25,13 +22,13 @@ static REQUEST_LIMIT: i32 = 25;
|
|||
#[serde(transparent)]
|
||||
pub struct ObjectId<Kind>(Url, #[serde(skip)] PhantomData<Kind>)
|
||||
where
|
||||
Kind: FromApub<DataType = LemmyContext> + ApubObject<DataType = LemmyContext> + Send + 'static,
|
||||
for<'de2> <Kind as FromApub>::ApubType: serde::Deserialize<'de2>;
|
||||
Kind: ApubObject<DataType = LemmyContext> + Send + 'static,
|
||||
for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>;
|
||||
|
||||
impl<Kind> ObjectId<Kind>
|
||||
where
|
||||
Kind: FromApub<DataType = LemmyContext> + ApubObject<DataType = LemmyContext> + Send + 'static,
|
||||
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
|
||||
Kind: ApubObject<DataType = LemmyContext> + Send + 'static,
|
||||
for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
|
||||
{
|
||||
pub fn new<T>(url: T) -> Self
|
||||
where
|
||||
|
@ -129,8 +126,8 @@ where
|
|||
|
||||
impl<Kind> Display for ObjectId<Kind>
|
||||
where
|
||||
Kind: FromApub<DataType = LemmyContext> + ApubObject<DataType = LemmyContext> + Send + 'static,
|
||||
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
|
||||
Kind: ApubObject<DataType = LemmyContext> + Send + 'static,
|
||||
for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
|
||||
{
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0.to_string())
|
||||
|
@ -139,8 +136,8 @@ where
|
|||
|
||||
impl<Kind> From<ObjectId<Kind>> for Url
|
||||
where
|
||||
Kind: FromApub<DataType = LemmyContext> + ApubObject<DataType = LemmyContext> + Send + 'static,
|
||||
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
|
||||
Kind: ApubObject<DataType = LemmyContext> + Send + 'static,
|
||||
for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
|
||||
{
|
||||
fn from(id: ObjectId<Kind>) -> Self {
|
||||
id.0
|
||||
|
@ -149,8 +146,8 @@ where
|
|||
|
||||
impl<Kind> From<ObjectId<Kind>> for DbUrl
|
||||
where
|
||||
Kind: FromApub<DataType = LemmyContext> + ApubObject<DataType = LemmyContext> + Send + 'static,
|
||||
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
|
||||
Kind: ApubObject<DataType = LemmyContext> + Send + 'static,
|
||||
for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
|
||||
{
|
||||
fn from(id: ObjectId<Kind>) -> Self {
|
||||
id.0.into()
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::objects::{
|
|||
post::{ApubPost, Page},
|
||||
};
|
||||
use activitystreams::chrono::NaiveDateTime;
|
||||
use lemmy_apub_lib::traits::{ApubObject, FromApub};
|
||||
use lemmy_apub_lib::traits::ApubObject;
|
||||
use lemmy_db_schema::source::{comment::CommentForm, post::PostForm};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
@ -31,6 +31,8 @@ pub enum PageOrNote {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl ApubObject for PostOrComment {
|
||||
type DataType = LemmyContext;
|
||||
type ApubType = PageOrNote;
|
||||
type TombstoneType = ();
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||
None
|
||||
|
@ -59,12 +61,14 @@ impl ApubObject for PostOrComment {
|
|||
PostOrComment::Comment(c) => c.delete(data).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl FromApub for PostOrComment {
|
||||
type ApubType = PageOrNote;
|
||||
type DataType = LemmyContext;
|
||||
async fn to_apub(&self, _data: &Self::DataType) -> Result<Self::ApubType, LemmyError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn to_tombstone(&self) -> Result<Self::TombstoneType, LemmyError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn from_apub(
|
||||
apub: &PageOrNote,
|
||||
|
|
|
@ -12,7 +12,7 @@ use anyhow::anyhow;
|
|||
use itertools::Itertools;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::{
|
||||
traits::{ApubObject, FromApub},
|
||||
traits::ApubObject,
|
||||
webfinger::{webfinger_resolve_actor, WebfingerType},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
|
@ -110,6 +110,8 @@ pub enum SearchableApubTypes {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl ApubObject for SearchableObjects {
|
||||
type DataType = LemmyContext;
|
||||
type ApubType = SearchableApubTypes;
|
||||
type TombstoneType = ();
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||
match self {
|
||||
|
@ -156,12 +158,14 @@ impl ApubObject for SearchableObjects {
|
|||
SearchableObjects::Comment(c) => c.delete(data).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl FromApub for SearchableObjects {
|
||||
type ApubType = SearchableApubTypes;
|
||||
type DataType = LemmyContext;
|
||||
async fn to_apub(&self, _data: &Self::DataType) -> Result<Self::ApubType, LemmyError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn to_tombstone(&self) -> Result<Self::TombstoneType, LemmyError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn from_apub(
|
||||
apub: &Self::ApubType,
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
use actix_web::{body::Body, web, web::Path, HttpResponse};
|
||||
use diesel::result::Error::NotFound;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::traits::ToApub;
|
||||
use lemmy_apub_lib::traits::ApubObject;
|
||||
use lemmy_db_schema::{newtypes::CommentId, source::comment::Comment, traits::Crud};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
@ -30,9 +30,7 @@ pub(crate) async fn get_apub_comment(
|
|||
}
|
||||
|
||||
if !comment.deleted {
|
||||
Ok(create_apub_response(
|
||||
&comment.to_apub(context.pool()).await?,
|
||||
))
|
||||
Ok(create_apub_response(&comment.to_apub(&**context).await?))
|
||||
} else {
|
||||
Ok(create_apub_tombstone_response(&comment.to_tombstone()?))
|
||||
}
|
||||
|
|
|
@ -6,13 +6,9 @@ use crate::{
|
|||
report::Report,
|
||||
},
|
||||
context::lemmy_context,
|
||||
generate_moderators_url,
|
||||
generate_outbox_url,
|
||||
generate_moderators_url, generate_outbox_url,
|
||||
http::{
|
||||
create_apub_response,
|
||||
create_apub_tombstone_response,
|
||||
payload_to_string,
|
||||
receive_activity,
|
||||
create_apub_response, create_apub_tombstone_response, payload_to_string, receive_activity,
|
||||
},
|
||||
objects::community::ApubCommunity,
|
||||
};
|
||||
|
@ -23,11 +19,10 @@ use activitystreams::{
|
|||
};
|
||||
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler, ToApub};
|
||||
use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler, ApubObject};
|
||||
use lemmy_db_schema::source::{activity::Activity, community::Community};
|
||||
use lemmy_db_views_actor::{
|
||||
community_follower_view::CommunityFollowerView,
|
||||
community_moderator_view::CommunityModeratorView,
|
||||
community_follower_view::CommunityFollowerView, community_moderator_view::CommunityModeratorView,
|
||||
};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
@ -51,7 +46,7 @@ pub(crate) async fn get_apub_community_http(
|
|||
.into();
|
||||
|
||||
if !community.deleted {
|
||||
let apub = community.to_apub(context.pool()).await?;
|
||||
let apub = community.to_apub(&**context).await?;
|
||||
|
||||
Ok(create_apub_response(&apub))
|
||||
} else {
|
||||
|
|
|
@ -24,7 +24,7 @@ use activitystreams::{
|
|||
};
|
||||
use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse};
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler, ToApub};
|
||||
use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler, ApubObject};
|
||||
use lemmy_db_schema::source::person::Person;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
@ -51,7 +51,7 @@ pub(crate) async fn get_apub_person_http(
|
|||
.into();
|
||||
|
||||
if !person.deleted {
|
||||
let apub = person.to_apub(context.pool()).await?;
|
||||
let apub = person.to_apub(&context).await?;
|
||||
|
||||
Ok(create_apub_response(&apub))
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
use actix_web::{body::Body, web, HttpResponse};
|
||||
use diesel::result::Error::NotFound;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::traits::ToApub;
|
||||
use lemmy_apub_lib::traits::ApubObject;
|
||||
use lemmy_db_schema::{newtypes::PostId, source::post::Post, traits::Crud};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
@ -30,7 +30,7 @@ pub(crate) async fn get_apub_post(
|
|||
}
|
||||
|
||||
if !post.deleted {
|
||||
Ok(create_apub_response(&post.to_apub(context.pool()).await?))
|
||||
Ok(create_apub_response(&post.to_apub(&context).await?))
|
||||
} else {
|
||||
Ok(create_apub_tombstone_response(&post.to_tombstone()?))
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use chrono::{DateTime, FixedOffset};
|
|||
use html2md::parse_html;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::{
|
||||
traits::{ApubObject, FromApub, ToApub},
|
||||
traits::ApubObject,
|
||||
values::{MediaTypeHtml, MediaTypeMarkdown},
|
||||
verify::verify_domains_match,
|
||||
};
|
||||
|
@ -31,7 +31,6 @@ use lemmy_db_schema::{
|
|||
post::Post,
|
||||
},
|
||||
traits::Crud,
|
||||
DbPool,
|
||||
};
|
||||
use lemmy_utils::{
|
||||
utils::{convert_datetime, remove_slurs},
|
||||
|
@ -159,6 +158,8 @@ impl From<Comment> for ApubComment {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl ApubObject for ApubComment {
|
||||
type DataType = LemmyContext;
|
||||
type ApubType = Note;
|
||||
type TombstoneType = Tombstone;
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||
None
|
||||
|
@ -184,23 +185,17 @@ impl ApubObject for ApubComment {
|
|||
.await??;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ToApub for ApubComment {
|
||||
type ApubType = Note;
|
||||
type TombstoneType = Tombstone;
|
||||
type DataType = DbPool;
|
||||
|
||||
async fn to_apub(&self, pool: &DbPool) -> Result<Note, LemmyError> {
|
||||
async fn to_apub(&self, context: &LemmyContext) -> Result<Note, LemmyError> {
|
||||
let creator_id = self.creator_id;
|
||||
let creator = blocking(pool, move |conn| Person::read(conn, creator_id)).await??;
|
||||
let creator = blocking(context.pool(), move |conn| Person::read(conn, creator_id)).await??;
|
||||
|
||||
let post_id = self.post_id;
|
||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
||||
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||
|
||||
let in_reply_to = if let Some(comment_id) = self.parent_id {
|
||||
let parent_comment = blocking(pool, move |conn| Comment::read(conn, comment_id)).await??;
|
||||
let parent_comment =
|
||||
blocking(context.pool(), move |conn| Comment::read(conn, comment_id)).await??;
|
||||
ObjectId::<PostOrComment>::new(parent_comment.ap_id.into_inner())
|
||||
} else {
|
||||
ObjectId::<PostOrComment>::new(post.ap_id.into_inner())
|
||||
|
@ -235,12 +230,6 @@ impl ToApub for ApubComment {
|
|||
NoteType::Note,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl FromApub for ApubComment {
|
||||
type ApubType = Note;
|
||||
type DataType = LemmyContext;
|
||||
|
||||
/// Converts a `Note` to `Comment`.
|
||||
///
|
||||
|
@ -339,7 +328,7 @@ mod tests {
|
|||
assert!(!comment.local);
|
||||
assert_eq!(request_counter, 0);
|
||||
|
||||
let to_apub = comment.to_apub(context.pool()).await.unwrap();
|
||||
let to_apub = comment.to_apub(&context).await.unwrap();
|
||||
assert_json_include!(actual: json, expected: to_apub);
|
||||
|
||||
Comment::delete(&*context.pool().get().unwrap(), comment.id).unwrap();
|
||||
|
|
|
@ -20,7 +20,7 @@ use itertools::Itertools;
|
|||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::{
|
||||
signatures::PublicKey,
|
||||
traits::{ActorType, ApubObject, FromApub, ToApub},
|
||||
traits::{ActorType, ApubObject},
|
||||
values::MediaTypeMarkdown,
|
||||
verify::verify_domains_match,
|
||||
};
|
||||
|
@ -138,6 +138,8 @@ impl From<Community> for ApubCommunity {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl ApubObject for ApubCommunity {
|
||||
type DataType = LemmyContext;
|
||||
type ApubType = Group;
|
||||
type TombstoneType = Tombstone;
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||
Some(self.last_refreshed_at)
|
||||
|
@ -163,41 +165,8 @@ impl ApubObject for ApubCommunity {
|
|||
.await??;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ActorType for ApubCommunity {
|
||||
fn is_local(&self) -> bool {
|
||||
self.local
|
||||
}
|
||||
fn actor_id(&self) -> Url {
|
||||
self.actor_id.to_owned().into()
|
||||
}
|
||||
fn name(&self) -> String {
|
||||
self.name.clone()
|
||||
}
|
||||
fn public_key(&self) -> Option<String> {
|
||||
self.public_key.to_owned()
|
||||
}
|
||||
fn private_key(&self) -> Option<String> {
|
||||
self.private_key.to_owned()
|
||||
}
|
||||
|
||||
fn inbox_url(&self) -> Url {
|
||||
self.inbox_url.clone().into()
|
||||
}
|
||||
|
||||
fn shared_inbox_url(&self) -> Option<Url> {
|
||||
self.shared_inbox_url.clone().map(|s| s.into_inner())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ToApub for ApubCommunity {
|
||||
type ApubType = Group;
|
||||
type TombstoneType = Tombstone;
|
||||
type DataType = DbPool;
|
||||
|
||||
async fn to_apub(&self, _pool: &DbPool) -> Result<Group, LemmyError> {
|
||||
async fn to_apub(&self, _context: &LemmyContext) -> Result<Group, LemmyError> {
|
||||
let source = self.description.clone().map(|bio| Source {
|
||||
content: bio,
|
||||
media_type: MediaTypeMarkdown::Markdown,
|
||||
|
@ -246,12 +215,6 @@ impl ToApub for ApubCommunity {
|
|||
GroupType::Group,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl FromApub for ApubCommunity {
|
||||
type ApubType = Group;
|
||||
type DataType = LemmyContext;
|
||||
|
||||
/// Converts a `Group` to `Community`, inserts it into the database and updates moderators.
|
||||
async fn from_apub(
|
||||
|
@ -280,6 +243,32 @@ impl FromApub for ApubCommunity {
|
|||
}
|
||||
}
|
||||
|
||||
impl ActorType for ApubCommunity {
|
||||
fn is_local(&self) -> bool {
|
||||
self.local
|
||||
}
|
||||
fn actor_id(&self) -> Url {
|
||||
self.actor_id.to_owned().into()
|
||||
}
|
||||
fn name(&self) -> String {
|
||||
self.name.clone()
|
||||
}
|
||||
fn public_key(&self) -> Option<String> {
|
||||
self.public_key.to_owned()
|
||||
}
|
||||
fn private_key(&self) -> Option<String> {
|
||||
self.private_key.to_owned()
|
||||
}
|
||||
|
||||
fn inbox_url(&self) -> Url {
|
||||
self.inbox_url.clone().into()
|
||||
}
|
||||
|
||||
fn shared_inbox_url(&self) -> Option<Url> {
|
||||
self.shared_inbox_url.clone().map(|s| s.into_inner())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl CommunityType for Community {
|
||||
fn followers_url(&self) -> Url {
|
||||
|
@ -345,7 +334,7 @@ mod tests {
|
|||
// this makes two requests to the (intentionally) broken outbox/moderators collections
|
||||
assert_eq!(request_counter, 2);
|
||||
|
||||
let to_apub = community.to_apub(context.pool()).await.unwrap();
|
||||
let to_apub = community.to_apub(&context).await.unwrap();
|
||||
assert_json_include!(actual: json_orig, expected: to_apub);
|
||||
|
||||
Community::delete(&*context.pool().get().unwrap(), community.id).unwrap();
|
||||
|
|
|
@ -16,14 +16,13 @@ use chrono::{DateTime, FixedOffset};
|
|||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::{
|
||||
signatures::PublicKey,
|
||||
traits::{ActorType, ApubObject, FromApub, ToApub},
|
||||
traits::{ActorType, ApubObject},
|
||||
values::MediaTypeMarkdown,
|
||||
verify::verify_domains_match,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
naive_now,
|
||||
source::person::{Person as DbPerson, PersonForm},
|
||||
DbPool,
|
||||
};
|
||||
use lemmy_utils::{
|
||||
utils::{check_slurs, check_slurs_opt, convert_datetime, markdown_to_html},
|
||||
|
@ -99,6 +98,8 @@ impl From<DbPerson> for ApubPerson {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl ApubObject for ApubPerson {
|
||||
type DataType = LemmyContext;
|
||||
type ApubType = Person;
|
||||
type TombstoneType = Tombstone;
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||
Some(self.last_refreshed_at)
|
||||
|
@ -124,43 +125,8 @@ impl ApubObject for ApubPerson {
|
|||
.await??;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ActorType for ApubPerson {
|
||||
fn is_local(&self) -> bool {
|
||||
self.local
|
||||
}
|
||||
fn actor_id(&self) -> Url {
|
||||
self.actor_id.to_owned().into_inner()
|
||||
}
|
||||
fn name(&self) -> String {
|
||||
self.name.clone()
|
||||
}
|
||||
|
||||
fn public_key(&self) -> Option<String> {
|
||||
self.public_key.to_owned()
|
||||
}
|
||||
|
||||
fn private_key(&self) -> Option<String> {
|
||||
self.private_key.to_owned()
|
||||
}
|
||||
|
||||
fn inbox_url(&self) -> Url {
|
||||
self.inbox_url.clone().into()
|
||||
}
|
||||
|
||||
fn shared_inbox_url(&self) -> Option<Url> {
|
||||
self.shared_inbox_url.clone().map(|s| s.into_inner())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ToApub for ApubPerson {
|
||||
type ApubType = Person;
|
||||
type TombstoneType = Tombstone;
|
||||
type DataType = DbPool;
|
||||
|
||||
async fn to_apub(&self, _pool: &DbPool) -> Result<Person, LemmyError> {
|
||||
async fn to_apub(&self, _pool: &LemmyContext) -> Result<Person, LemmyError> {
|
||||
let kind = if self.bot_account {
|
||||
UserTypes::Service
|
||||
} else {
|
||||
|
@ -203,15 +169,10 @@ impl ToApub for ApubPerson {
|
|||
};
|
||||
Ok(person)
|
||||
}
|
||||
|
||||
fn to_tombstone(&self) -> Result<Tombstone, LemmyError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl FromApub for ApubPerson {
|
||||
type ApubType = Person;
|
||||
type DataType = LemmyContext;
|
||||
|
||||
async fn from_apub(
|
||||
person: &Person,
|
||||
|
@ -265,6 +226,34 @@ impl FromApub for ApubPerson {
|
|||
}
|
||||
}
|
||||
|
||||
impl ActorType for ApubPerson {
|
||||
fn is_local(&self) -> bool {
|
||||
self.local
|
||||
}
|
||||
fn actor_id(&self) -> Url {
|
||||
self.actor_id.to_owned().into_inner()
|
||||
}
|
||||
fn name(&self) -> String {
|
||||
self.name.clone()
|
||||
}
|
||||
|
||||
fn public_key(&self) -> Option<String> {
|
||||
self.public_key.to_owned()
|
||||
}
|
||||
|
||||
fn private_key(&self) -> Option<String> {
|
||||
self.private_key.to_owned()
|
||||
}
|
||||
|
||||
fn inbox_url(&self) -> Url {
|
||||
self.inbox_url.clone().into()
|
||||
}
|
||||
|
||||
fn shared_inbox_url(&self) -> Option<Url> {
|
||||
self.shared_inbox_url.clone().map(|s| s.into_inner())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -291,7 +280,7 @@ mod tests {
|
|||
assert_eq!(person.bio.as_ref().unwrap().len(), 39);
|
||||
assert_eq!(request_counter, 0);
|
||||
|
||||
let to_apub = person.to_apub(context.pool()).await.unwrap();
|
||||
let to_apub = person.to_apub(&context).await.unwrap();
|
||||
assert_json_include!(actual: json, expected: to_apub);
|
||||
|
||||
DbPerson::delete(&*context.pool().get().unwrap(), person.id).unwrap();
|
||||
|
|
|
@ -17,7 +17,7 @@ use activitystreams::{
|
|||
use chrono::{DateTime, FixedOffset, NaiveDateTime};
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::{
|
||||
traits::{ActorType, ApubObject, FromApub, ToApub},
|
||||
traits::{ActorType, ApubObject},
|
||||
values::{MediaTypeHtml, MediaTypeMarkdown},
|
||||
verify::verify_domains_match,
|
||||
};
|
||||
|
@ -29,7 +29,6 @@ use lemmy_db_schema::{
|
|||
post::{Post, PostForm},
|
||||
},
|
||||
traits::Crud,
|
||||
DbPool,
|
||||
};
|
||||
use lemmy_utils::{
|
||||
request::fetch_site_data,
|
||||
|
@ -133,6 +132,8 @@ impl From<Post> for ApubPost {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl ApubObject for ApubPost {
|
||||
type DataType = LemmyContext;
|
||||
type ApubType = Page;
|
||||
type TombstoneType = Tombstone;
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||
None
|
||||
|
@ -158,20 +159,16 @@ impl ApubObject for ApubPost {
|
|||
.await??;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ToApub for ApubPost {
|
||||
type ApubType = Page;
|
||||
type TombstoneType = Tombstone;
|
||||
type DataType = DbPool;
|
||||
|
||||
// Turn a Lemmy post into an ActivityPub page that can be sent out over the network.
|
||||
async fn to_apub(&self, pool: &DbPool) -> Result<Page, LemmyError> {
|
||||
async fn to_apub(&self, context: &LemmyContext) -> Result<Page, LemmyError> {
|
||||
let creator_id = self.creator_id;
|
||||
let creator = blocking(pool, move |conn| Person::read(conn, creator_id)).await??;
|
||||
let creator = blocking(context.pool(), move |conn| Person::read(conn, creator_id)).await??;
|
||||
let community_id = self.community_id;
|
||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
||||
let community = blocking(context.pool(), move |conn| {
|
||||
Community::read(conn, community_id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let source = self.body.clone().map(|body| Source {
|
||||
content: body,
|
||||
|
@ -212,12 +209,6 @@ impl ToApub for ApubPost {
|
|||
PageType::Page,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl FromApub for ApubPost {
|
||||
type ApubType = Page;
|
||||
type DataType = LemmyContext;
|
||||
|
||||
async fn from_apub(
|
||||
page: &Page,
|
||||
|
@ -315,7 +306,7 @@ mod tests {
|
|||
assert!(post.stickied);
|
||||
assert_eq!(request_counter, 0);
|
||||
|
||||
let to_apub = post.to_apub(context.pool()).await.unwrap();
|
||||
let to_apub = post.to_apub(&context).await.unwrap();
|
||||
assert_json_include!(actual: json, expected: to_apub);
|
||||
|
||||
Post::delete(&*context.pool().get().unwrap(), post.id).unwrap();
|
||||
|
|
|
@ -15,7 +15,7 @@ use chrono::{DateTime, FixedOffset};
|
|||
use html2md::parse_html;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub_lib::{
|
||||
traits::{ApubObject, FromApub, ToApub},
|
||||
traits::ApubObject,
|
||||
values::{MediaTypeHtml, MediaTypeMarkdown},
|
||||
verify::verify_domains_match,
|
||||
};
|
||||
|
@ -25,7 +25,6 @@ use lemmy_db_schema::{
|
|||
private_message::{PrivateMessage, PrivateMessageForm},
|
||||
},
|
||||
traits::Crud,
|
||||
DbPool,
|
||||
};
|
||||
use lemmy_utils::{utils::convert_datetime, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
|
@ -104,6 +103,8 @@ impl From<PrivateMessage> for ApubPrivateMessage {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl ApubObject for ApubPrivateMessage {
|
||||
type DataType = LemmyContext;
|
||||
type ApubType = Note;
|
||||
type TombstoneType = Tombstone;
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||
None
|
||||
|
@ -126,20 +127,14 @@ impl ApubObject for ApubPrivateMessage {
|
|||
// do nothing, because pm can't be fetched over http
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ToApub for ApubPrivateMessage {
|
||||
type ApubType = Note;
|
||||
type TombstoneType = Tombstone;
|
||||
type DataType = DbPool;
|
||||
|
||||
async fn to_apub(&self, pool: &DbPool) -> Result<Note, LemmyError> {
|
||||
async fn to_apub(&self, context: &LemmyContext) -> Result<Note, LemmyError> {
|
||||
let creator_id = self.creator_id;
|
||||
let creator = blocking(pool, move |conn| Person::read(conn, creator_id)).await??;
|
||||
let creator = blocking(context.pool(), move |conn| Person::read(conn, creator_id)).await??;
|
||||
|
||||
let recipient_id = self.recipient_id;
|
||||
let recipient = blocking(pool, move |conn| Person::read(conn, recipient_id)).await??;
|
||||
let recipient =
|
||||
blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
|
||||
|
||||
let note = Note {
|
||||
context: lemmy_context(),
|
||||
|
@ -168,12 +163,6 @@ impl ToApub for ApubPrivateMessage {
|
|||
NoteType::Note,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl FromApub for ApubPrivateMessage {
|
||||
type ApubType = Note;
|
||||
type DataType = LemmyContext;
|
||||
|
||||
async fn from_apub(
|
||||
note: &Note,
|
||||
|
@ -253,7 +242,7 @@ mod tests {
|
|||
assert_eq!(pm.content.len(), 20);
|
||||
assert_eq!(request_counter, 0);
|
||||
|
||||
let to_apub = pm.to_apub(context.pool()).await.unwrap();
|
||||
let to_apub = pm.to_apub(&context).await.unwrap();
|
||||
assert_json_include!(actual: json, expected: to_apub);
|
||||
|
||||
PrivateMessage::delete(&*context.pool().get().unwrap(), pm.id).unwrap();
|
||||
|
|
|
@ -30,6 +30,9 @@ pub trait ActivityHandler {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
pub trait ApubObject {
|
||||
type DataType;
|
||||
type ApubType;
|
||||
type TombstoneType;
|
||||
|
||||
/// If this object should be refetched after a certain interval, it should return the last refresh
|
||||
/// time here. This is mainly used to update remote actors.
|
||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime>;
|
||||
|
@ -42,6 +45,25 @@ pub trait ApubObject {
|
|||
Self: Sized;
|
||||
/// Marks the object as deleted in local db. Called when a tombstone is received.
|
||||
async fn delete(self, data: &Self::DataType) -> Result<(), LemmyError>;
|
||||
|
||||
/// Trait for converting an object or actor into the respective ActivityPub type.
|
||||
async fn to_apub(&self, data: &Self::DataType) -> Result<Self::ApubType, LemmyError>;
|
||||
fn to_tombstone(&self) -> Result<Self::TombstoneType, LemmyError>;
|
||||
|
||||
/// Converts an object from ActivityPub type to Lemmy internal type.
|
||||
///
|
||||
/// * `apub` The object to read from
|
||||
/// * `context` LemmyContext which holds DB pool, HTTP client etc
|
||||
/// * `expected_domain` Domain where the object was received from. None in case of mod action.
|
||||
/// * `mod_action_allowed` True if the object can be a mod activity, ignore `expected_domain` in this case
|
||||
async fn from_apub(
|
||||
apub: &Self::ApubType,
|
||||
data: &Self::DataType,
|
||||
expected_domain: &Url,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<Self, LemmyError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
/// Common methods provided by ActivityPub actors (community and person). Not all methods are
|
||||
|
@ -71,35 +93,3 @@ pub trait ActorType {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for converting an object or actor into the respective ActivityPub type.
|
||||
#[async_trait::async_trait(?Send)]
|
||||
pub trait ToApub {
|
||||
type ApubType;
|
||||
type TombstoneType;
|
||||
type DataType;
|
||||
|
||||
async fn to_apub(&self, data: &Self::DataType) -> Result<Self::ApubType, LemmyError>;
|
||||
fn to_tombstone(&self) -> Result<Self::TombstoneType, LemmyError>;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
pub trait FromApub {
|
||||
type ApubType;
|
||||
type DataType;
|
||||
|
||||
/// Converts an object from ActivityPub type to Lemmy internal type.
|
||||
///
|
||||
/// * `apub` The object to read from
|
||||
/// * `context` LemmyContext which holds DB pool, HTTP client etc
|
||||
/// * `expected_domain` Domain where the object was received from. None in case of mod action.
|
||||
/// * `mod_action_allowed` True if the object can be a mod activity, ignore `expected_domain` in this case
|
||||
async fn from_apub(
|
||||
apub: &Self::ApubType,
|
||||
data: &Self::DataType,
|
||||
expected_domain: &Url,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<Self, LemmyError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue