+++ /dev/null
-use crate::fetcher::post_or_comment::PostOrComment;
-use lemmy_api_common::blocking;
-use lemmy_db_queries::source::{
- comment::Comment_,
- community::Community_,
- person::Person_,
- post::Post_,
-};
-use lemmy_db_schema::source::{
- comment::Comment,
- community::Community,
- person::Person,
- post::Post,
- private_message::PrivateMessage,
-};
-use lemmy_utils::LemmyError;
-use lemmy_websocket::LemmyContext;
-
-// TODO: merge this trait with ApubObject (means that db_schema needs to depend on apub_lib)
-#[async_trait::async_trait(?Send)]
-pub trait DeletableApubObject {
- // TODO: pass in tombstone with summary field, to decide between remove/delete
- async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError>;
-}
-
-#[async_trait::async_trait(?Send)]
-impl DeletableApubObject for Community {
- async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> {
- let id = self.id;
- blocking(context.pool(), move |conn| {
- Community::update_deleted(conn, id, true)
- })
- .await??;
- Ok(())
- }
-}
-
-#[async_trait::async_trait(?Send)]
-impl DeletableApubObject for Person {
- async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> {
- let id = self.id;
- blocking(context.pool(), move |conn| Person::delete_account(conn, id)).await??;
- Ok(())
- }
-}
-
-#[async_trait::async_trait(?Send)]
-impl DeletableApubObject for Post {
- async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> {
- let id = self.id;
- blocking(context.pool(), move |conn| {
- Post::update_deleted(conn, id, true)
- })
- .await??;
- Ok(())
- }
-}
-
-#[async_trait::async_trait(?Send)]
-impl DeletableApubObject for Comment {
- async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> {
- let id = self.id;
- blocking(context.pool(), move |conn| {
- Comment::update_deleted(conn, id, true)
- })
- .await??;
- Ok(())
- }
-}
-
-#[async_trait::async_trait(?Send)]
-impl DeletableApubObject for PostOrComment {
- async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> {
- match self {
- PostOrComment::Comment(c) => {
- blocking(context.pool(), move |conn| {
- Comment::update_deleted(conn, c.id, true)
- })
- .await??;
- }
- PostOrComment::Post(p) => {
- blocking(context.pool(), move |conn| {
- Post::update_deleted(conn, p.id, true)
- })
- .await??;
- }
- }
-
- Ok(())
- }
-}
-
-#[async_trait::async_trait(?Send)]
-impl DeletableApubObject for PrivateMessage {
- async fn delete(self, _context: &LemmyContext) -> Result<(), LemmyError> {
- // do nothing, because pm can't be fetched over http
- unimplemented!()
- }
-}
pub mod community;
-pub mod deletable_apub_object;
mod fetch;
pub mod object_id;
pub mod post_or_comment;
-use crate::{
- fetcher::{deletable_apub_object::DeletableApubObject, should_refetch_actor},
- objects::FromApub,
-};
+use crate::{fetcher::should_refetch_actor, objects::FromApub};
use anyhow::anyhow;
use diesel::{NotFound, PgConnection};
use lemmy_api_common::blocking;
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
pub struct ObjectId<Kind>(Url, #[serde(skip)] PhantomData<Kind>)
where
- Kind: FromApub + ApubObject<DataType = PgConnection> + DeletableApubObject + Send + 'static,
+ Kind: FromApub + ApubObject<DataType = PgConnection> + Send + 'static,
for<'de2> <Kind as FromApub>::ApubType: serde::Deserialize<'de2>;
impl<Kind> ObjectId<Kind>
where
- Kind: FromApub + ApubObject<DataType = PgConnection> + DeletableApubObject + Send + 'static,
+ Kind: FromApub + ApubObject<DataType = PgConnection> + Send + 'static,
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
{
pub fn new<T>(url: T) -> Self
if res.status() == StatusCode::GONE {
if let Some(db_object) = db_object {
- db_object.delete(context).await?;
+ blocking(context.pool(), move |conn| db_object.delete(conn)).await??;
}
return Err(anyhow!("Fetched remote object {} which was deleted", self).into());
}
impl<Kind> Display for ObjectId<Kind>
where
- Kind: FromApub + ApubObject<DataType = PgConnection> + DeletableApubObject + Send + 'static,
+ Kind: FromApub + ApubObject<DataType = PgConnection> + Send + 'static,
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
impl<Kind> From<ObjectId<Kind>> for Url
where
- Kind: FromApub + ApubObject<DataType = PgConnection> + DeletableApubObject + Send + 'static,
+ Kind: FromApub + ApubObject<DataType = PgConnection> + Send + 'static,
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
{
fn from(id: ObjectId<Kind>) -> Self {
impl<Kind> From<ObjectId<Kind>> for DbUrl
where
- Kind: FromApub + ApubObject<DataType = PgConnection> + DeletableApubObject + Send + 'static,
+ Kind: FromApub + ApubObject<DataType = PgConnection> + Send + 'static,
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
{
fn from(id: ObjectId<Kind>) -> Self {
None => Comment::read_from_apub_id(conn, object_id)?.map(PostOrComment::Comment),
})
}
+
+ fn delete(self, data: &Self::DataType) -> Result<(), LemmyError> {
+ match self {
+ PostOrComment::Post(p) => p.delete(data),
+ PostOrComment::Comment(c) => c.delete(data),
+ }
+ }
}
#[async_trait::async_trait(?Send)]
use crate::{
- fetcher::{deletable_apub_object::DeletableApubObject, object_id::ObjectId},
+ fetcher::object_id::ObjectId,
objects::{comment::Note, community::Group, person::Person as ApubPerson, post::Page, FromApub},
};
use activitystreams::chrono::NaiveDateTime;
}
Ok(None)
}
+
+ fn delete(self, conn: &Self::DataType) -> Result<(), LemmyError> {
+ match self {
+ SearchableObjects::Person(p) => p.delete(conn),
+ SearchableObjects::Community(c) => c.delete(conn),
+ SearchableObjects::Post(p) => p.delete(conn),
+ SearchableObjects::Comment(c) => c.delete(conn),
+ }
+ }
}
#[async_trait::async_trait(?Send)]
})
}
}
-
-#[async_trait::async_trait(?Send)]
-impl DeletableApubObject for SearchableObjects {
- async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> {
- match self {
- SearchableObjects::Person(p) => p.delete(context).await,
- SearchableObjects::Community(c) => c.delete(context).await,
- SearchableObjects::Post(p) => p.delete(context).await,
- SearchableObjects::Comment(c) => c.delete(context).await,
- }
- }
-}
fn read_from_apub_id(data: &Self::DataType, object_id: Url) -> Result<Option<Self>, LemmyError>
where
Self: Sized;
+ /// Marks the object as deleted in local db. Called when a tombstone is received.
+ fn delete(self, data: &Self::DataType) -> Result<(), LemmyError>;
}
/// Common methods provided by ActivityPub actors (community and person). Not all methods are
use crate::{
+ naive_now,
schema::{comment, comment_alias_1, comment_like, comment_saved},
source::post::Post,
CommentId,
let object_id: DbUrl = object_id.into();
Ok(comment.filter(ap_id.eq(object_id)).first::<Self>(conn).ok())
}
+
+ // TODO: duplicate code from Comment::update_deleted(), we should really move all impls to
+ // this crate so we can call that function from here
+ fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> {
+ use crate::schema::comment::dsl::*;
+ diesel::update(comment.find(self.id))
+ .set((deleted.eq(true), updated.eq(naive_now())))
+ .get_result::<Self>(conn)?;
+ Ok(())
+ }
}
use crate::{
+ naive_now,
schema::{community, community_follower, community_moderator, community_person_ban},
CommunityId,
DbUrl,
.ok(),
)
}
+
+ fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> {
+ use crate::schema::community::dsl::*;
+ diesel::update(community.find(self.id))
+ .set((deleted.eq(true), updated.eq(naive_now())))
+ .get_result::<Self>(conn)?;
+ Ok(())
+ }
}
impl ActorType for Community {
use crate::{
+ naive_now,
schema::{person, person_alias_1, person_alias_2},
DbUrl,
PersonId,
.ok(),
)
}
+
+ fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> {
+ use crate::schema::person::dsl::*;
+ diesel::update(person.find(self.id))
+ .set((deleted.eq(true), updated.eq(naive_now())))
+ .get_result::<Self>(conn)?;
+ Ok(())
+ }
}
impl ActorType for Person {
use crate::{
+ naive_now,
schema::{post, post_like, post_read, post_saved},
CommunityId,
DbUrl,
let object_id: DbUrl = object_id.into();
Ok(post.filter(ap_id.eq(object_id)).first::<Self>(conn).ok())
}
+
+ fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> {
+ use crate::schema::post::dsl::*;
+ diesel::update(post.find(self.id))
+ .set((deleted.eq(true), updated.eq(naive_now())))
+ .get_result::<Self>(conn)?;
+ Ok(())
+ }
}
.ok(),
)
}
+
+ fn delete(self, _conn: &PgConnection) -> Result<(), LemmyError> {
+ // do nothing, because pm can't be fetched over http
+ unimplemented!()
+ }
}