mirror of https://github.com/LemmyNet/lemmy.git
handle deletion in new fetcher
parent
13eca1b106
commit
64619d7eb1
|
@ -0,0 +1,85 @@
|
|||
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};
|
||||
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(())
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
pub mod community;
|
||||
pub mod deletable_apub_object;
|
||||
mod fetch;
|
||||
pub mod object_id;
|
||||
pub mod post_or_comment;
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use crate::{fetcher::should_refetch_actor, objects::FromApub, APUB_JSON_CONTENT_TYPE};
|
||||
use crate::{
|
||||
fetcher::{deletable_apub_object::DeletableApubObject, should_refetch_actor},
|
||||
objects::FromApub,
|
||||
APUB_JSON_CONTENT_TYPE,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use diesel::NotFound;
|
||||
use lemmy_api_common::blocking;
|
||||
|
@ -23,18 +27,18 @@ static REQUEST_LIMIT: i32 = 25;
|
|||
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
|
||||
pub struct ObjectId<Kind>(Url, #[serde(skip)] PhantomData<Kind>)
|
||||
where
|
||||
Kind: FromApub + ApubObject + Send + 'static,
|
||||
Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static,
|
||||
for<'de2> <Kind as FromApub>::ApubType: serde::Deserialize<'de2>;
|
||||
|
||||
impl<Kind> ObjectId<Kind>
|
||||
where
|
||||
Kind: FromApub + ApubObject + Send + 'static,
|
||||
Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static,
|
||||
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
|
||||
{
|
||||
pub fn new<K, T>(url: T) -> ObjectId<K>
|
||||
where
|
||||
T: Into<Url>,
|
||||
K: FromApub + ApubObject + Send + 'static,
|
||||
K: FromApub + ApubObject + DeletableApubObject + Send + 'static,
|
||||
for<'de> <K as FromApub>::ApubType: serde::Deserialize<'de>,
|
||||
{
|
||||
ObjectId(url.into(), PhantomData::<K>)
|
||||
|
@ -64,13 +68,17 @@ where
|
|||
// TODO: rename to should_refetch_object()
|
||||
if should_refetch_actor(last_refreshed_at) {
|
||||
debug!("Refetching remote object {}", self.0.as_str());
|
||||
return self.dereference_remotely(context, request_counter).await;
|
||||
return self
|
||||
.dereference_remotely(context, request_counter, Some(object))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
Ok(object)
|
||||
} else {
|
||||
debug!("Fetching remote object {}", self.0.as_str());
|
||||
self.dereference_remotely(context, request_counter).await
|
||||
self
|
||||
.dereference_remotely(context, request_counter, None)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,6 +97,7 @@ where
|
|||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
db_object: Option<Kind>,
|
||||
) -> Result<Kind, LemmyError> {
|
||||
// dont fetch local objects this way
|
||||
debug_assert!(self.0.domain() != Some(&Settings::get().hostname));
|
||||
|
@ -109,31 +118,21 @@ where
|
|||
.await?;
|
||||
|
||||
if res.status() == StatusCode::GONE {
|
||||
self.mark_object_deleted(context).await?;
|
||||
return Err(
|
||||
anyhow!(
|
||||
"Fetched remote object {} which was deleted",
|
||||
self.0.as_str()
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
if let Some(db_object) = db_object {
|
||||
db_object.delete(context).await?;
|
||||
}
|
||||
return Err(anyhow!("Fetched remote object {} which was deleted", self).into());
|
||||
}
|
||||
|
||||
let res2: Kind::ApubType = res.json().await?;
|
||||
|
||||
Ok(Kind::from_apub(&res2, context, self.inner(), request_counter).await?)
|
||||
}
|
||||
|
||||
async fn mark_object_deleted(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
// TODO: need to move methods update_deleted, update_removed etc into a trait to use them here.
|
||||
// also, how do we know if the object was deleted vs removed?
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Kind> Display for ObjectId<Kind>
|
||||
where
|
||||
Kind: FromApub + ApubObject + Send + 'static,
|
||||
Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static,
|
||||
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
|
||||
{
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
|
@ -143,7 +142,7 @@ where
|
|||
|
||||
impl<Kind> From<ObjectId<Kind>> for Url
|
||||
where
|
||||
Kind: FromApub + ApubObject + Send + 'static,
|
||||
Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static,
|
||||
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
|
||||
{
|
||||
fn from(id: ObjectId<Kind>) -> Self {
|
||||
|
@ -153,7 +152,7 @@ where
|
|||
|
||||
impl<Kind> From<ObjectId<Kind>> for DbUrl
|
||||
where
|
||||
Kind: FromApub + ApubObject + Send + 'static,
|
||||
Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static,
|
||||
for<'de> <Kind as FromApub>::ApubType: serde::Deserialize<'de>,
|
||||
{
|
||||
fn from(id: ObjectId<Kind>) -> Self {
|
||||
|
|
Loading…
Reference in New Issue