Remove follow community traits (#3737)

* chore(FollowCommunity): remove Perform and Send Activity traits

* chore(FollowCommunity): avoid fetching community and person from db
This commit is contained in:
Louis GERARD 2023-08-02 11:32:16 +02:00 committed by GitHub
parent 91834d0d21
commit 7bc64ab91a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 71 additions and 77 deletions

View file

@ -1,8 +1,9 @@
use crate::Perform; use activitypub_federation::config::Data;
use actix_web::web::Data; use actix_web::web::Json;
use lemmy_api_common::{ use lemmy_api_common::{
community::{CommunityResponse, FollowCommunity}, community::{CommunityResponse, FollowCommunity},
context::LemmyContext, context::LemmyContext,
send_activity::{ActivityChannel, SendActivityData},
utils::{check_community_ban, check_community_deleted_or_removed, local_user_view_from_jwt}, utils::{check_community_ban, check_community_deleted_or_removed, local_user_view_from_jwt},
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
@ -15,54 +16,56 @@ use lemmy_db_schema::{
use lemmy_db_views_actor::structs::CommunityView; use lemmy_db_views_actor::structs::CommunityView;
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType}; use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
#[async_trait::async_trait(?Send)] #[tracing::instrument(skip(context))]
impl Perform for FollowCommunity { pub async fn follow_community(
type Response = CommunityResponse; data: Json<FollowCommunity>,
context: Data<LemmyContext>,
) -> Result<Json<CommunityResponse>, LemmyError> {
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
#[tracing::instrument(skip(context))] let community = Community::read(&mut context.pool(), data.community_id).await?;
async fn perform(&self, context: &Data<LemmyContext>) -> Result<CommunityResponse, LemmyError> { let mut community_follower_form = CommunityFollowerForm {
let data: &FollowCommunity = self; community_id: community.id,
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?; person_id: local_user_view.person.id,
pending: false,
};
let community_id = data.community_id; if data.follow {
let community = Community::read(&mut context.pool(), community_id).await?; if community.local {
let mut community_follower_form = CommunityFollowerForm { check_community_ban(local_user_view.person.id, community.id, &mut context.pool()).await?;
community_id: data.community_id, check_community_deleted_or_removed(community.id, &mut context.pool()).await?;
person_id: local_user_view.person.id,
pending: false,
};
if data.follow { CommunityFollower::follow(&mut context.pool(), &community_follower_form)
if community.local { .await
check_community_ban(local_user_view.person.id, community_id, &mut context.pool()).await?; .with_lemmy_type(LemmyErrorType::CommunityFollowerAlreadyExists)?;
check_community_deleted_or_removed(community_id, &mut context.pool()).await?; } else {
// Mark as pending, the actual federation activity is sent via `SendActivity` handler
CommunityFollower::follow(&mut context.pool(), &community_follower_form) community_follower_form.pending = true;
.await CommunityFollower::follow(&mut context.pool(), &community_follower_form)
.with_lemmy_type(LemmyErrorType::CommunityFollowerAlreadyExists)?;
} else {
// Mark as pending, the actual federation activity is sent via `SendActivity` handler
community_follower_form.pending = true;
CommunityFollower::follow(&mut context.pool(), &community_follower_form)
.await
.with_lemmy_type(LemmyErrorType::CommunityFollowerAlreadyExists)?;
}
}
if !data.follow {
CommunityFollower::unfollow(&mut context.pool(), &community_follower_form)
.await .await
.with_lemmy_type(LemmyErrorType::CommunityFollowerAlreadyExists)?; .with_lemmy_type(LemmyErrorType::CommunityFollowerAlreadyExists)?;
} }
let community_id = data.community_id;
let person_id = local_user_view.person.id;
let community_view =
CommunityView::read(&mut context.pool(), community_id, Some(person_id), None).await?;
let discussion_languages = CommunityLanguage::read(&mut context.pool(), community_id).await?;
Ok(Self::Response {
community_view,
discussion_languages,
})
} }
if !data.follow {
CommunityFollower::unfollow(&mut context.pool(), &community_follower_form)
.await
.with_lemmy_type(LemmyErrorType::CommunityFollowerAlreadyExists)?;
}
ActivityChannel::submit_activity(
SendActivityData::FollowCommunity(community, local_user_view.person.clone(), data.follow),
&context,
)
.await?;
let community_id = data.community_id;
let person_id = local_user_view.person.id;
let community_view =
CommunityView::read(&mut context.pool(), community_id, Some(person_id), None).await?;
let discussion_languages = CommunityLanguage::read(&mut context.pool(), community_id).await?;
Ok(Json(CommunityResponse {
community_view,
discussion_languages,
}))
} }

View file

@ -1,6 +1,6 @@
mod add_mod; mod add_mod;
mod ban; mod ban;
mod block; mod block;
mod follow; pub mod follow;
mod hide; mod hide;
mod transfer; mod transfer;

View file

@ -31,6 +31,7 @@ pub enum SendActivityData {
RemoveComment(Comment, Person, Community, Option<String>), RemoveComment(Comment, Person, Community, Option<String>),
UpdateComment(Comment), UpdateComment(Comment),
LikePostOrComment(DbUrl, Person, Community, i16), LikePostOrComment(DbUrl, Person, Community, i16),
FollowCommunity(Community, Person, bool),
} }
// TODO: instead of static, move this into LemmyContext. make sure that stopping the process with // TODO: instead of static, move this into LemmyContext. make sure that stopping the process with

View file

@ -1,41 +1,27 @@
use crate::{ use crate::{
objects::community::ApubCommunity, objects::{community::ApubCommunity, person::ApubPerson},
protocol::activities::following::{follow::Follow, undo_follow::UndoFollow}, protocol::activities::following::{follow::Follow, undo_follow::UndoFollow},
SendActivity,
}; };
use activitypub_federation::config::Data; use activitypub_federation::config::Data;
use lemmy_api_common::{ use lemmy_api_common::context::LemmyContext;
community::{CommunityResponse, FollowCommunity}, use lemmy_db_schema::source::{community::Community, person::Person};
context::LemmyContext,
utils::local_user_view_from_jwt,
};
use lemmy_db_schema::{source::community::Community, traits::Crud};
use lemmy_utils::error::LemmyError; use lemmy_utils::error::LemmyError;
pub mod accept; pub mod accept;
pub mod follow; pub mod follow;
pub mod undo_follow; pub mod undo_follow;
#[async_trait::async_trait] pub async fn send_follow_community(
impl SendActivity for FollowCommunity { community: Community,
type Response = CommunityResponse; person: Person,
follow: bool,
async fn send_activity( context: &Data<LemmyContext>,
request: &Self, ) -> Result<(), LemmyError> {
_response: &Self::Response, let community: ApubCommunity = community.into();
context: &Data<LemmyContext>, let actor: ApubPerson = person.into();
) -> Result<(), LemmyError> { if follow {
let local_user_view = local_user_view_from_jwt(&request.auth, context).await?; Follow::send(&actor, &community, context).await
let person = local_user_view.person.clone().into(); } else {
let community: ApubCommunity = Community::read(&mut context.pool(), request.community_id) UndoFollow::send(&actor, &community, context).await
.await?
.into();
if community.local {
Ok(())
} else if request.follow {
Follow::send(&person, &community, context).await
} else {
UndoFollow::send(&person, &community, context).await
}
} }
} }

View file

@ -1,3 +1,4 @@
use self::following::send_follow_community;
use crate::{ use crate::{
activities::{ activities::{
deletion::{send_apub_delete_in_community, DeletableObjects}, deletion::{send_apub_delete_in_community, DeletableObjects},
@ -250,6 +251,9 @@ pub async fn match_outgoing_activities(
LikePostOrComment(object_id, person, community, score) => { LikePostOrComment(object_id, person, community, score) => {
send_like_activity(object_id, person, community, score, context).await send_like_activity(object_id, person, community, score, context).await
} }
SendActivityData::FollowCommunity(community, person, follow) => {
send_follow_community(community, person, follow, &context).await
}
} }
}; };
if *SYNCHRONOUS_FEDERATION { if *SYNCHRONOUS_FEDERATION {

View file

@ -2,6 +2,7 @@ use actix_web::{guard, web, Error, HttpResponse, Result};
use lemmy_api::{ use lemmy_api::{
comment::{distinguish::distinguish_comment, like::like_comment, save::save_comment}, comment::{distinguish::distinguish_comment, like::like_comment, save::save_comment},
comment_report::{list::list_comment_reports, resolve::resolve_comment_report}, comment_report::{list::list_comment_reports, resolve::resolve_comment_report},
community::follow::follow_community,
local_user::notifications::mark_reply_read::mark_reply_as_read, local_user::notifications::mark_reply_read::mark_reply_as_read,
post::like::like_post, post::like::like_post,
Perform, Perform,
@ -15,7 +16,6 @@ use lemmy_api_common::{
CreateCommunity, CreateCommunity,
DeleteCommunity, DeleteCommunity,
EditCommunity, EditCommunity,
FollowCommunity,
HideCommunity, HideCommunity,
RemoveCommunity, RemoveCommunity,
TransferCommunity, TransferCommunity,
@ -146,7 +146,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
.route("", web::put().to(route_post_crud::<EditCommunity>)) .route("", web::put().to(route_post_crud::<EditCommunity>))
.route("/hide", web::put().to(route_post::<HideCommunity>)) .route("/hide", web::put().to(route_post::<HideCommunity>))
.route("/list", web::get().to(list_communities)) .route("/list", web::get().to(list_communities))
.route("/follow", web::post().to(route_post::<FollowCommunity>)) .route("/follow", web::post().to(follow_community))
.route("/block", web::post().to(route_post::<BlockCommunity>)) .route("/block", web::post().to(route_post::<BlockCommunity>))
.route( .route(
"/delete", "/delete",