mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-05 20:15:01 +00:00
convert post receiver
This commit is contained in:
parent
26f4694b98
commit
6abfa92a60
17 changed files with 428 additions and 470 deletions
|
@ -14,7 +14,6 @@ use url::Url;
|
|||
|
||||
pub(crate) mod comment_undo;
|
||||
pub(crate) mod community;
|
||||
pub(crate) mod post;
|
||||
pub(crate) mod post_undo;
|
||||
pub(crate) mod private_message;
|
||||
|
||||
|
|
|
@ -1,242 +0,0 @@
|
|||
use crate::{
|
||||
activities::receive::get_actor_as_person,
|
||||
inbox::receive_for_community::verify_mod_activity,
|
||||
};
|
||||
use activitystreams::{
|
||||
activity::{Announce, Create, Dislike, Like, Update},
|
||||
prelude::*,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use lemmy_api_common::{blocking, post::PostResponse};
|
||||
use lemmy_apub::{objects::FromApub, ActorType, PageExt};
|
||||
use lemmy_db_queries::{source::post::Post_, ApubObject, Crud, Likeable};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
community::Community,
|
||||
post::{Post, PostLike, PostLikeForm},
|
||||
},
|
||||
DbUrl,
|
||||
};
|
||||
use lemmy_db_views::post_view::PostView;
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation, UserOperationCrud};
|
||||
|
||||
pub(crate) async fn receive_create_post(
|
||||
create: Create,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person = get_actor_as_person(&create, context, request_counter).await?;
|
||||
let page = PageExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
|
||||
.context(location_info!())?;
|
||||
|
||||
let post = Post::from_apub(&page, context, person.actor_id(), request_counter, false).await?;
|
||||
|
||||
// Refetch the view
|
||||
let post_id = post.id;
|
||||
let post_view = blocking(context.pool(), move |conn| {
|
||||
PostView::read(conn, post_id, None)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = PostResponse { post_view };
|
||||
|
||||
context.chat_server().do_send(SendPost {
|
||||
op: UserOperationCrud::CreatePost,
|
||||
post: res,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn receive_update_post(
|
||||
update: Update,
|
||||
announce: Option<Announce>,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person = get_actor_as_person(&update, context, request_counter).await?;
|
||||
let page = PageExt::from_any_base(update.object().to_owned().one().context(location_info!())?)?
|
||||
.context(location_info!())?;
|
||||
|
||||
let post_id: DbUrl = page
|
||||
.id_unchecked()
|
||||
.context(location_info!())?
|
||||
.to_owned()
|
||||
.into();
|
||||
let old_post = blocking(context.pool(), move |conn| {
|
||||
Post::read_from_apub_id(conn, &post_id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// If sticked or locked state was changed, make sure the actor is a mod
|
||||
let stickied = page.ext_one.stickied.context(location_info!())?;
|
||||
let locked = !page.ext_one.comments_enabled.context(location_info!())?;
|
||||
let mut mod_action_allowed = false;
|
||||
if (stickied != old_post.stickied) || (locked != old_post.locked) {
|
||||
let community = blocking(context.pool(), move |conn| {
|
||||
Community::read(conn, old_post.community_id)
|
||||
})
|
||||
.await??;
|
||||
// Only check mod status if the community is local, otherwise we trust that it was sent correctly.
|
||||
if community.local {
|
||||
verify_mod_activity(&update, announce, &community, context).await?;
|
||||
}
|
||||
mod_action_allowed = true;
|
||||
}
|
||||
|
||||
let post = Post::from_apub(
|
||||
&page,
|
||||
context,
|
||||
person.actor_id(),
|
||||
request_counter,
|
||||
mod_action_allowed,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let post_id = post.id;
|
||||
// Refetch the view
|
||||
let post_view = blocking(context.pool(), move |conn| {
|
||||
PostView::read(conn, post_id, None)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = PostResponse { post_view };
|
||||
|
||||
context.chat_server().do_send(SendPost {
|
||||
op: UserOperationCrud::EditPost,
|
||||
post: res,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn receive_like_post(
|
||||
like: Like,
|
||||
post: Post,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person = get_actor_as_person(&like, context, request_counter).await?;
|
||||
|
||||
let post_id = post.id;
|
||||
let like_form = PostLikeForm {
|
||||
post_id,
|
||||
person_id: person.id,
|
||||
score: 1,
|
||||
};
|
||||
let person_id = person.id;
|
||||
blocking(context.pool(), move |conn| {
|
||||
PostLike::remove(conn, person_id, post_id)?;
|
||||
PostLike::like(conn, &like_form)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// Refetch the view
|
||||
let post_view = blocking(context.pool(), move |conn| {
|
||||
PostView::read(conn, post_id, None)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = PostResponse { post_view };
|
||||
|
||||
context.chat_server().do_send(SendPost {
|
||||
op: UserOperation::CreatePostLike,
|
||||
post: res,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn receive_dislike_post(
|
||||
dislike: Dislike,
|
||||
post: Post,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person = get_actor_as_person(&dislike, context, request_counter).await?;
|
||||
|
||||
let post_id = post.id;
|
||||
let like_form = PostLikeForm {
|
||||
post_id,
|
||||
person_id: person.id,
|
||||
score: -1,
|
||||
};
|
||||
let person_id = person.id;
|
||||
blocking(context.pool(), move |conn| {
|
||||
PostLike::remove(conn, person_id, post_id)?;
|
||||
PostLike::like(conn, &like_form)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// Refetch the view
|
||||
let post_view = blocking(context.pool(), move |conn| {
|
||||
PostView::read(conn, post_id, None)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = PostResponse { post_view };
|
||||
|
||||
context.chat_server().do_send(SendPost {
|
||||
op: UserOperation::CreatePostLike,
|
||||
post: res,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn receive_delete_post(
|
||||
context: &LemmyContext,
|
||||
post: Post,
|
||||
) -> Result<(), LemmyError> {
|
||||
let deleted_post = blocking(context.pool(), move |conn| {
|
||||
Post::update_deleted(conn, post.id, true)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// Refetch the view
|
||||
let post_id = deleted_post.id;
|
||||
let post_view = blocking(context.pool(), move |conn| {
|
||||
PostView::read(conn, post_id, None)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = PostResponse { post_view };
|
||||
context.chat_server().do_send(SendPost {
|
||||
op: UserOperationCrud::EditPost,
|
||||
post: res,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn receive_remove_post(
|
||||
context: &LemmyContext,
|
||||
post: Post,
|
||||
) -> Result<(), LemmyError> {
|
||||
let removed_post = blocking(context.pool(), move |conn| {
|
||||
Post::update_removed(conn, post.id, true)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// Refetch the view
|
||||
let post_id = removed_post.id;
|
||||
let post_view = blocking(context.pool(), move |conn| {
|
||||
PostView::read(conn, post_id, None)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = PostResponse { post_view };
|
||||
context.chat_server().do_send(SendPost {
|
||||
op: UserOperationCrud::EditPost,
|
||||
post: res,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,15 +1,8 @@
|
|||
use crate::{activities_new::comment::send_websocket_message, inbox::new_inbox_routing::Activity};
|
||||
use crate::{activities_new::comment::like_or_dislike_comment, inbox::new_inbox_routing::Activity};
|
||||
use activitystreams::activity::kind::DislikeType;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::fetcher::{
|
||||
objects::get_or_fetch_and_insert_comment,
|
||||
person::get_or_fetch_and_upsert_person,
|
||||
};
|
||||
use lemmy_apub_lib::{PublicUrl, ReceiveActivity};
|
||||
use lemmy_db_queries::Likeable;
|
||||
use lemmy_db_schema::source::comment::{CommentLike, CommentLikeForm};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::{LemmyContext, UserOperation};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
|
@ -30,31 +23,12 @@ impl ReceiveActivity for Activity<DislikeComment> {
|
|||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person =
|
||||
get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?;
|
||||
let comment =
|
||||
get_or_fetch_and_insert_comment(&self.inner.object, context, request_counter).await?;
|
||||
|
||||
let comment_id = comment.id;
|
||||
let like_form = CommentLikeForm {
|
||||
comment_id,
|
||||
post_id: comment.post_id,
|
||||
person_id: person.id,
|
||||
score: -1,
|
||||
};
|
||||
let person_id = person.id;
|
||||
blocking(context.pool(), move |conn| {
|
||||
CommentLike::remove(conn, person_id, comment_id)?;
|
||||
CommentLike::like(conn, &like_form)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// TODO get those recipient actor ids from somewhere
|
||||
send_websocket_message(
|
||||
comment_id,
|
||||
vec![],
|
||||
UserOperation::CreateCommentLike,
|
||||
like_or_dislike_comment(
|
||||
-1,
|
||||
&self.inner.actor,
|
||||
&self.inner.object,
|
||||
context,
|
||||
request_counter,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
use crate::{activities_new::comment::send_websocket_message, inbox::new_inbox_routing::Activity};
|
||||
use crate::{activities_new::comment::like_or_dislike_comment, inbox::new_inbox_routing::Activity};
|
||||
use activitystreams::activity::kind::LikeType;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::fetcher::{
|
||||
objects::get_or_fetch_and_insert_comment,
|
||||
person::get_or_fetch_and_upsert_person,
|
||||
};
|
||||
use lemmy_apub_lib::{PublicUrl, ReceiveActivity};
|
||||
use lemmy_db_queries::Likeable;
|
||||
use lemmy_db_schema::source::comment::{CommentLike, CommentLikeForm};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::{LemmyContext, UserOperation};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
|
@ -30,31 +23,12 @@ impl ReceiveActivity for Activity<LikeComment> {
|
|||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person =
|
||||
get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?;
|
||||
let comment =
|
||||
get_or_fetch_and_insert_comment(&self.inner.object, context, request_counter).await?;
|
||||
|
||||
let comment_id = comment.id;
|
||||
let like_form = CommentLikeForm {
|
||||
comment_id,
|
||||
post_id: comment.post_id,
|
||||
person_id: person.id,
|
||||
score: 1,
|
||||
};
|
||||
let person_id = person.id;
|
||||
blocking(context.pool(), move |conn| {
|
||||
CommentLike::remove(conn, person_id, comment_id)?;
|
||||
CommentLike::like(conn, &like_form)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// TODO get those recipient actor ids from somewhere
|
||||
send_websocket_message(
|
||||
comment_id,
|
||||
vec![],
|
||||
UserOperation::CreateCommentLike,
|
||||
like_or_dislike_comment(
|
||||
-1,
|
||||
&self.inner.actor,
|
||||
&self.inner.object,
|
||||
context,
|
||||
request_counter,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
use lemmy_api_common::{blocking, comment::CommentResponse, send_local_notifs};
|
||||
use lemmy_apub::fetcher::person::get_or_fetch_and_upsert_person;
|
||||
use lemmy_db_queries::Crud;
|
||||
use lemmy_apub::fetcher::{
|
||||
objects::get_or_fetch_and_insert_comment,
|
||||
person::get_or_fetch_and_upsert_person,
|
||||
};
|
||||
use lemmy_db_queries::{Crud, Likeable};
|
||||
use lemmy_db_schema::{
|
||||
source::{comment::Comment, post::Post},
|
||||
source::{
|
||||
comment::{Comment, CommentLike, CommentLikeForm},
|
||||
post::Post,
|
||||
},
|
||||
CommentId,
|
||||
LocalUserId,
|
||||
};
|
||||
use lemmy_db_views::comment_view::CommentView;
|
||||
use lemmy_utils::{utils::scrape_text_for_mentions, LemmyError};
|
||||
use lemmy_websocket::{messages::SendComment, LemmyContext};
|
||||
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
|
||||
use url::Url;
|
||||
|
||||
pub mod create;
|
||||
|
@ -62,3 +68,37 @@ async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::Operation
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn like_or_dislike_comment(
|
||||
score: i16,
|
||||
actor: &Url,
|
||||
object: &Url,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
|
||||
let comment = get_or_fetch_and_insert_comment(object, context, request_counter).await?;
|
||||
|
||||
let comment_id = comment.id;
|
||||
let like_form = CommentLikeForm {
|
||||
comment_id,
|
||||
post_id: comment.post_id,
|
||||
person_id: person.id,
|
||||
score,
|
||||
};
|
||||
let person_id = person.id;
|
||||
blocking(context.pool(), move |conn| {
|
||||
CommentLike::remove(conn, person_id, comment_id)?;
|
||||
CommentLike::like(conn, &like_form)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// TODO get those recipient actor ids from somewhere
|
||||
send_websocket_message(
|
||||
comment_id,
|
||||
vec![],
|
||||
UserOperation::CreateCommentLike,
|
||||
context,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
pub mod comment;
|
||||
pub mod follow;
|
||||
pub mod post;
|
||||
pub mod private_message;
|
||||
|
|
46
crates/apub_receive/src/activities_new/post/create.rs
Normal file
46
crates/apub_receive/src/activities_new/post/create.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use crate::{activities_new::post::send_websocket_message, inbox::new_inbox_routing::Activity};
|
||||
use activitystreams::activity::kind::CreateType;
|
||||
use lemmy_apub::{
|
||||
fetcher::person::get_or_fetch_and_upsert_person,
|
||||
objects::FromApub,
|
||||
ActorType,
|
||||
PageExt,
|
||||
};
|
||||
use lemmy_apub_lib::{PublicUrl, ReceiveActivity};
|
||||
use lemmy_db_schema::source::post::Post;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreatePost {
|
||||
actor: Url,
|
||||
to: PublicUrl,
|
||||
object: PageExt,
|
||||
#[serde(rename = "type")]
|
||||
kind: CreateType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<CreatePost> {
|
||||
async fn receive(
|
||||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person =
|
||||
get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?;
|
||||
|
||||
let post = Post::from_apub(
|
||||
&self.inner.object,
|
||||
context,
|
||||
person.actor_id(),
|
||||
request_counter,
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
|
||||
send_websocket_message(post.id, UserOperationCrud::CreatePost, context).await
|
||||
}
|
||||
}
|
39
crates/apub_receive/src/activities_new/post/delete.rs
Normal file
39
crates/apub_receive/src/activities_new/post/delete.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
use crate::{activities_new::post::send_websocket_message, inbox::new_inbox_routing::Activity};
|
||||
use activitystreams::activity::kind::DeleteType;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::fetcher::objects::get_or_fetch_and_insert_post;
|
||||
use lemmy_apub_lib::{PublicUrl, ReceiveActivity};
|
||||
use lemmy_db_queries::source::post::Post_;
|
||||
use lemmy_db_schema::source::post::Post;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DeletePost {
|
||||
actor: Url,
|
||||
to: PublicUrl,
|
||||
object: Url,
|
||||
#[serde(rename = "type")]
|
||||
kind: DeleteType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<DeletePost> {
|
||||
async fn receive(
|
||||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
// TODO: check that actor is from same instance as post (same for DeleteComment)
|
||||
let post = get_or_fetch_and_insert_post(&self.inner.object, context, request_counter).await?;
|
||||
|
||||
let deleted_post = blocking(context.pool(), move |conn| {
|
||||
Post::update_deleted(conn, post.id, true)
|
||||
})
|
||||
.await??;
|
||||
|
||||
send_websocket_message(deleted_post.id, UserOperationCrud::EditPost, context).await
|
||||
}
|
||||
}
|
34
crates/apub_receive/src/activities_new/post/dislike.rs
Normal file
34
crates/apub_receive/src/activities_new/post/dislike.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use crate::{activities_new::post::like_or_dislike_post, inbox::new_inbox_routing::Activity};
|
||||
use activitystreams::activity::kind::DislikeType;
|
||||
use lemmy_apub_lib::{PublicUrl, ReceiveActivity};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DislikePost {
|
||||
actor: Url,
|
||||
to: PublicUrl,
|
||||
object: Url,
|
||||
#[serde(rename = "type")]
|
||||
kind: DislikeType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<DislikePost> {
|
||||
async fn receive(
|
||||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
like_or_dislike_post(
|
||||
-1,
|
||||
&self.inner.actor,
|
||||
&self.inner.object,
|
||||
context,
|
||||
request_counter,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
34
crates/apub_receive/src/activities_new/post/like.rs
Normal file
34
crates/apub_receive/src/activities_new/post/like.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use crate::{activities_new::post::like_or_dislike_post, inbox::new_inbox_routing::Activity};
|
||||
use activitystreams::activity::kind::LikeType;
|
||||
use lemmy_apub_lib::{PublicUrl, ReceiveActivity};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct LikePost {
|
||||
actor: Url,
|
||||
to: PublicUrl,
|
||||
object: Url,
|
||||
#[serde(rename = "type")]
|
||||
kind: LikeType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<LikePost> {
|
||||
async fn receive(
|
||||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
like_or_dislike_post(
|
||||
1,
|
||||
&self.inner.actor,
|
||||
&self.inner.object,
|
||||
context,
|
||||
request_counter,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
68
crates/apub_receive/src/activities_new/post/mod.rs
Normal file
68
crates/apub_receive/src/activities_new/post/mod.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use lemmy_api_common::{blocking, post::PostResponse};
|
||||
use lemmy_apub::fetcher::{
|
||||
objects::get_or_fetch_and_insert_post,
|
||||
person::get_or_fetch_and_upsert_person,
|
||||
};
|
||||
use lemmy_db_queries::Likeable;
|
||||
use lemmy_db_schema::{
|
||||
source::post::{PostLike, PostLikeForm},
|
||||
PostId,
|
||||
};
|
||||
use lemmy_db_views::post_view::PostView;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
|
||||
use url::Url;
|
||||
|
||||
pub mod create;
|
||||
pub mod delete;
|
||||
pub mod dislike;
|
||||
pub mod like;
|
||||
pub mod remove;
|
||||
pub mod update;
|
||||
|
||||
async fn send_websocket_message<OP: ToString + Send + lemmy_websocket::OperationType + 'static>(
|
||||
post_id: PostId,
|
||||
op: OP,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError> {
|
||||
let post_view = blocking(context.pool(), move |conn| {
|
||||
PostView::read(conn, post_id, None)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = PostResponse { post_view };
|
||||
|
||||
context.chat_server().do_send(SendPost {
|
||||
op,
|
||||
post: res,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn like_or_dislike_post(
|
||||
score: i16,
|
||||
actor: &Url,
|
||||
object: &Url,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
|
||||
let post = get_or_fetch_and_insert_post(object, context, request_counter).await?;
|
||||
|
||||
let post_id = post.id;
|
||||
let like_form = PostLikeForm {
|
||||
post_id: post.id,
|
||||
person_id: person.id,
|
||||
score,
|
||||
};
|
||||
let person_id = person.id;
|
||||
blocking(context.pool(), move |conn| {
|
||||
PostLike::remove(conn, person_id, post_id)?;
|
||||
PostLike::like(conn, &like_form)
|
||||
})
|
||||
.await??;
|
||||
|
||||
send_websocket_message(post.id, UserOperation::CreatePostLike, context).await
|
||||
}
|
39
crates/apub_receive/src/activities_new/post/remove.rs
Normal file
39
crates/apub_receive/src/activities_new/post/remove.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
use crate::{activities_new::post::send_websocket_message, inbox::new_inbox_routing::Activity};
|
||||
use activitystreams::activity::kind::RemoveType;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::fetcher::objects::get_or_fetch_and_insert_post;
|
||||
use lemmy_apub_lib::{PublicUrl, ReceiveActivity};
|
||||
use lemmy_db_queries::source::post::Post_;
|
||||
use lemmy_db_schema::source::post::Post;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RemovePost {
|
||||
actor: Url,
|
||||
to: PublicUrl,
|
||||
object: Url,
|
||||
#[serde(rename = "type")]
|
||||
kind: RemoveType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<RemovePost> {
|
||||
async fn receive(
|
||||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
// TODO: check that actor is instance mod if community is local (same for DeleteComment)
|
||||
let post = get_or_fetch_and_insert_post(&self.inner.object, context, request_counter).await?;
|
||||
|
||||
let removed_post = blocking(context.pool(), move |conn| {
|
||||
Post::update_removed(conn, post.id, true)
|
||||
})
|
||||
.await??;
|
||||
|
||||
send_websocket_message(removed_post.id, UserOperationCrud::EditPost, context).await
|
||||
}
|
||||
}
|
86
crates/apub_receive/src/activities_new/post/update.rs
Normal file
86
crates/apub_receive/src/activities_new/post/update.rs
Normal file
|
@ -0,0 +1,86 @@
|
|||
use crate::{activities_new::post::send_websocket_message, inbox::new_inbox_routing::Activity};
|
||||
use activitystreams::activity::kind::UpdateType;
|
||||
use anyhow::Context;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::{
|
||||
fetcher::person::get_or_fetch_and_upsert_person,
|
||||
objects::{FromApub, FromApubToForm},
|
||||
ActorType,
|
||||
PageExt,
|
||||
};
|
||||
use lemmy_apub_lib::{PublicUrl, ReceiveActivity};
|
||||
use lemmy_db_queries::{ApubObject, Crud};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
community::Community,
|
||||
post::{Post, PostForm},
|
||||
},
|
||||
DbUrl,
|
||||
};
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UpdatePost {
|
||||
actor: Url,
|
||||
to: PublicUrl,
|
||||
object: PageExt,
|
||||
#[serde(rename = "type")]
|
||||
kind: UpdateType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<UpdatePost> {
|
||||
async fn receive(
|
||||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person =
|
||||
get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?;
|
||||
let temp_post = PostForm::from_apub(
|
||||
&self.inner.object,
|
||||
context,
|
||||
person.actor_id(),
|
||||
request_counter,
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let post_id: DbUrl = temp_post.ap_id.context(location_info!())?;
|
||||
let old_post = blocking(context.pool(), move |conn| {
|
||||
Post::read_from_apub_id(conn, &post_id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
// If sticked or locked state was changed, make sure the actor is a mod
|
||||
let stickied = temp_post.stickied.context(location_info!())?;
|
||||
let locked = temp_post.locked.context(location_info!())?;
|
||||
let mut mod_action_allowed = false;
|
||||
if (stickied != old_post.stickied) || (locked != old_post.locked) {
|
||||
let community = blocking(context.pool(), move |conn| {
|
||||
Community::read(conn, old_post.community_id)
|
||||
})
|
||||
.await??;
|
||||
// Only check mod status if the community is local, otherwise we trust that it was sent correctly.
|
||||
if community.local {
|
||||
// TODO
|
||||
//verify_mod_activity(&update, announce, &community, context).await?;
|
||||
}
|
||||
mod_action_allowed = true;
|
||||
}
|
||||
|
||||
let post = Post::from_apub(
|
||||
&self.inner.object,
|
||||
context,
|
||||
person.actor_id(),
|
||||
request_counter,
|
||||
mod_action_allowed,
|
||||
)
|
||||
.await?;
|
||||
|
||||
send_websocket_message(post.id, UserOperationCrud::EditPost, context).await
|
||||
}
|
||||
}
|
|
@ -8,10 +8,7 @@ use crate::{
|
|||
receive_for_community::{
|
||||
receive_add_for_community,
|
||||
receive_block_user_for_community,
|
||||
receive_create_for_community,
|
||||
receive_delete_for_community,
|
||||
receive_dislike_for_community,
|
||||
receive_like_for_community,
|
||||
receive_remove_for_community,
|
||||
receive_undo_for_community,
|
||||
receive_update_for_community,
|
||||
|
@ -157,16 +154,7 @@ pub(crate) async fn community_receive_message(
|
|||
))
|
||||
.await?
|
||||
}
|
||||
CommunityValidTypes::Create => {
|
||||
Box::pin(receive_create_for_community(
|
||||
context,
|
||||
any_base.clone(),
|
||||
&actor_url,
|
||||
request_counter,
|
||||
))
|
||||
.await?;
|
||||
true
|
||||
}
|
||||
CommunityValidTypes::Create => todo!(),
|
||||
CommunityValidTypes::Update => {
|
||||
Box::pin(receive_update_for_community(
|
||||
context,
|
||||
|
@ -178,26 +166,8 @@ pub(crate) async fn community_receive_message(
|
|||
.await?;
|
||||
true
|
||||
}
|
||||
CommunityValidTypes::Like => {
|
||||
Box::pin(receive_like_for_community(
|
||||
context,
|
||||
any_base.clone(),
|
||||
&actor_url,
|
||||
request_counter,
|
||||
))
|
||||
.await?;
|
||||
true
|
||||
}
|
||||
CommunityValidTypes::Dislike => {
|
||||
Box::pin(receive_dislike_for_community(
|
||||
context,
|
||||
any_base.clone(),
|
||||
&actor_url,
|
||||
request_counter,
|
||||
))
|
||||
.await?;
|
||||
true
|
||||
}
|
||||
CommunityValidTypes::Like => todo!(),
|
||||
CommunityValidTypes::Dislike => todo!(),
|
||||
CommunityValidTypes::Delete => {
|
||||
Box::pin(receive_delete_for_community(
|
||||
context,
|
||||
|
|
|
@ -8,6 +8,14 @@ use crate::activities_new::{
|
|||
update::UpdateComment,
|
||||
},
|
||||
follow::AcceptFollowCommunity,
|
||||
post::{
|
||||
create::CreatePost,
|
||||
delete::DeletePost,
|
||||
dislike::DislikePost,
|
||||
like::LikePost,
|
||||
remove::RemovePost,
|
||||
update::UpdatePost,
|
||||
},
|
||||
private_message::{
|
||||
create::CreatePrivateMessage,
|
||||
delete::DeletePrivateMessage,
|
||||
|
@ -61,6 +69,12 @@ pub enum PersonAcceptedActivitiesNew {
|
|||
DislikeComment(DislikeComment),
|
||||
DeleteComment(DeleteComment),
|
||||
RemoveComment(RemoveComment),
|
||||
CreatePost(CreatePost),
|
||||
UpdatePost(UpdatePost),
|
||||
LikePost(LikePost),
|
||||
DislikePost(DislikePost),
|
||||
DeletePost(DeletePost),
|
||||
RemovePost(RemovePost),
|
||||
}
|
||||
|
||||
// todo: can probably get rid of this?
|
||||
|
|
|
@ -17,10 +17,7 @@ use crate::{
|
|||
receive_for_community::{
|
||||
receive_add_for_community,
|
||||
receive_block_user_for_community,
|
||||
receive_create_for_community,
|
||||
receive_delete_for_community,
|
||||
receive_dislike_for_community,
|
||||
receive_like_for_community,
|
||||
receive_remove_for_community,
|
||||
receive_undo_for_community,
|
||||
receive_update_for_community,
|
||||
|
@ -242,9 +239,7 @@ pub async fn receive_announce(
|
|||
|
||||
use AnnouncableActivities::*;
|
||||
match kind {
|
||||
Some(Create) => {
|
||||
receive_create_for_community(context, inner_activity, &inner_id, request_counter).await
|
||||
}
|
||||
Some(Create) => todo!(),
|
||||
Some(Update) => {
|
||||
receive_update_for_community(
|
||||
context,
|
||||
|
@ -255,12 +250,8 @@ pub async fn receive_announce(
|
|||
)
|
||||
.await
|
||||
}
|
||||
Some(Like) => {
|
||||
receive_like_for_community(context, inner_activity, &inner_id, request_counter).await
|
||||
}
|
||||
Some(Dislike) => {
|
||||
receive_dislike_for_community(context, inner_activity, &inner_id, request_counter).await
|
||||
}
|
||||
Some(Like) => todo!(),
|
||||
Some(Dislike) => todo!(),
|
||||
Some(Delete) => {
|
||||
receive_delete_for_community(
|
||||
context,
|
||||
|
|
|
@ -11,14 +11,6 @@ use crate::{
|
|||
receive_remote_mod_undo_delete_community,
|
||||
receive_remote_mod_update_community,
|
||||
},
|
||||
post::{
|
||||
receive_create_post,
|
||||
receive_delete_post,
|
||||
receive_dislike_post,
|
||||
receive_like_post,
|
||||
receive_remove_post,
|
||||
receive_update_post,
|
||||
},
|
||||
post_undo::{
|
||||
receive_undo_delete_post,
|
||||
receive_undo_dislike_post,
|
||||
|
@ -36,7 +28,6 @@ use activitystreams::{
|
|||
Add,
|
||||
Announce,
|
||||
Block,
|
||||
Create,
|
||||
Delete,
|
||||
Dislike,
|
||||
Like,
|
||||
|
@ -69,7 +60,6 @@ use lemmy_db_queries::{
|
|||
source::community::CommunityModerator_,
|
||||
ApubObject,
|
||||
Bannable,
|
||||
Crud,
|
||||
Followable,
|
||||
Joinable,
|
||||
};
|
||||
|
@ -85,7 +75,6 @@ use lemmy_db_schema::{
|
|||
CommunityPersonBanForm,
|
||||
},
|
||||
person::Person,
|
||||
site::Site,
|
||||
},
|
||||
DbUrl,
|
||||
};
|
||||
|
@ -112,28 +101,6 @@ enum ObjectTypes {
|
|||
/// This file is for post/comment activities received by the community, and for post/comment
|
||||
/// activities announced by the community and received by the person.
|
||||
|
||||
/// A post or comment being created
|
||||
pub(in crate::inbox) async fn receive_create_for_community(
|
||||
context: &LemmyContext,
|
||||
activity: AnyBase,
|
||||
expected_domain: &Url,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let create = Create::from_any_base(activity)?.context(location_info!())?;
|
||||
verify_activity_domains_valid(&create, &expected_domain, true)?;
|
||||
verify_is_addressed_to_public(&create)?;
|
||||
|
||||
let kind = create
|
||||
.object()
|
||||
.as_single_kind_str()
|
||||
.and_then(|s| s.parse().ok());
|
||||
match kind {
|
||||
Some(ObjectTypes::Page) => receive_create_post(create, context, request_counter).await,
|
||||
Some(ObjectTypes::Note) => todo!(),
|
||||
_ => receive_unhandled_activity(create),
|
||||
}
|
||||
}
|
||||
|
||||
/// A post or comment being edited
|
||||
pub(in crate::inbox) async fn receive_update_for_community(
|
||||
context: &LemmyContext,
|
||||
|
@ -152,9 +119,7 @@ pub(in crate::inbox) async fn receive_update_for_community(
|
|||
.as_single_kind_str()
|
||||
.and_then(|s| s.parse().ok());
|
||||
match kind {
|
||||
Some(ObjectTypes::Page) => {
|
||||
receive_update_post(update, announce, context, request_counter).await
|
||||
}
|
||||
Some(ObjectTypes::Page) => todo!(),
|
||||
Some(ObjectTypes::Note) => todo!(),
|
||||
Some(ObjectTypes::Group) => {
|
||||
receive_remote_mod_update_community(update, context, request_counter).await
|
||||
|
@ -163,62 +128,6 @@ pub(in crate::inbox) async fn receive_update_for_community(
|
|||
}
|
||||
}
|
||||
|
||||
/// A post or comment being upvoted
|
||||
pub(in crate::inbox) async fn receive_like_for_community(
|
||||
context: &LemmyContext,
|
||||
activity: AnyBase,
|
||||
expected_domain: &Url,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let like = Like::from_any_base(activity)?.context(location_info!())?;
|
||||
verify_activity_domains_valid(&like, &expected_domain, false)?;
|
||||
verify_is_addressed_to_public(&like)?;
|
||||
|
||||
let object_id = like
|
||||
.object()
|
||||
.as_single_xsd_any_uri()
|
||||
.context(location_info!())?;
|
||||
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
||||
PostOrComment::Post(post) => receive_like_post(like, *post, context, request_counter).await,
|
||||
PostOrComment::Comment(_) => {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A post or comment being downvoted
|
||||
pub(in crate::inbox) async fn receive_dislike_for_community(
|
||||
context: &LemmyContext,
|
||||
activity: AnyBase,
|
||||
expected_domain: &Url,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let enable_downvotes = blocking(context.pool(), move |conn| {
|
||||
Site::read(conn, 1).map(|s| s.enable_downvotes)
|
||||
})
|
||||
.await??;
|
||||
if !enable_downvotes {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let dislike = Dislike::from_any_base(activity)?.context(location_info!())?;
|
||||
verify_activity_domains_valid(&dislike, &expected_domain, false)?;
|
||||
verify_is_addressed_to_public(&dislike)?;
|
||||
|
||||
let object_id = dislike
|
||||
.object()
|
||||
.as_single_xsd_any_uri()
|
||||
.context(location_info!())?;
|
||||
match fetch_post_or_comment_by_id(&object_id, context, request_counter).await? {
|
||||
PostOrComment::Post(post) => {
|
||||
receive_dislike_post(dislike, *post, context, request_counter).await
|
||||
}
|
||||
PostOrComment::Comment(_) => {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A post or comment being deleted by its creator
|
||||
pub(in crate::inbox) async fn receive_delete_for_community(
|
||||
context: &LemmyContext,
|
||||
|
@ -239,10 +148,7 @@ pub(in crate::inbox) async fn receive_delete_for_community(
|
|||
.context(location_info!())?;
|
||||
|
||||
match find_object_by_id(context, object).await {
|
||||
Ok(Object::Post(p)) => {
|
||||
verify_activity_domains_valid(&delete, &expected_domain, true)?;
|
||||
receive_delete_post(context, *p).await
|
||||
}
|
||||
Ok(Object::Post(_)) => todo!(),
|
||||
Ok(Object::Comment(_)) => {
|
||||
verify_activity_domains_valid(&delete, &expected_domain, true)?;
|
||||
todo!()
|
||||
|
@ -290,23 +196,8 @@ pub(in crate::inbox) async fn receive_remove_for_community(
|
|||
)
|
||||
.await?;
|
||||
// TODO: send websocket notification about removed mod
|
||||
Ok(())
|
||||
}
|
||||
// Remove a post or comment
|
||||
else {
|
||||
let object = remove
|
||||
.object()
|
||||
.to_owned()
|
||||
.single_xsd_any_uri()
|
||||
.context(location_info!())?;
|
||||
|
||||
match find_post_or_comment_by_id(context, object).await {
|
||||
Ok(PostOrComment::Post(p)) => receive_remove_post(context, *p).await,
|
||||
Ok(PostOrComment::Comment(_)) => todo!(),
|
||||
// if we dont have the object, no need to do anything
|
||||
Err(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(EnumString)]
|
||||
|
|
Loading…
Reference in a new issue