Merge traits ToApub and FromApub into ApubObject

rewrite-collections
Felix Ableitner 2021-10-26 21:05:26 +02:00
parent f4bac6a17f
commit 20af10dddf
17 changed files with 164 additions and 229 deletions

View File

@ -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,

View File

@ -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(),

View File

@ -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(),

View File

@ -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(),
};

View File

@ -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()

View File

@ -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,

View File

@ -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,

View File

@ -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()?))
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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()?))
}

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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;
}