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 actix_web::web::Data;
use activitypub_federation::config::Data;
use actix_web::web::Json;
use lemmy_api_common::{
community::{CommunityResponse, FollowCommunity},
context::LemmyContext,
send_activity::{ActivityChannel, SendActivityData},
utils::{check_community_ban, check_community_deleted_or_removed, local_user_view_from_jwt},
};
use lemmy_db_schema::{
@ -15,54 +16,56 @@ use lemmy_db_schema::{
use lemmy_db_views_actor::structs::CommunityView;
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
#[async_trait::async_trait(?Send)]
impl Perform for FollowCommunity {
type Response = CommunityResponse;
#[tracing::instrument(skip(context))]
pub async fn follow_community(
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))]
async fn perform(&self, context: &Data<LemmyContext>) -> Result<CommunityResponse, LemmyError> {
let data: &FollowCommunity = self;
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
let community = Community::read(&mut context.pool(), data.community_id).await?;
let mut community_follower_form = CommunityFollowerForm {
community_id: community.id,
person_id: local_user_view.person.id,
pending: false,
};
let community_id = data.community_id;
let community = Community::read(&mut context.pool(), community_id).await?;
let mut community_follower_form = CommunityFollowerForm {
community_id: data.community_id,
person_id: local_user_view.person.id,
pending: false,
};
if data.follow {
if community.local {
check_community_ban(local_user_view.person.id, community.id, &mut context.pool()).await?;
check_community_deleted_or_removed(community.id, &mut context.pool()).await?;
if data.follow {
if community.local {
check_community_ban(local_user_view.person.id, community_id, &mut context.pool()).await?;
check_community_deleted_or_removed(community_id, &mut context.pool()).await?;
CommunityFollower::follow(&mut context.pool(), &community_follower_form)
.await
.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)
CommunityFollower::follow(&mut context.pool(), &community_follower_form)
.await
.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)?;
}
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 ban;
mod block;
mod follow;
pub mod follow;
mod hide;
mod transfer;

View file

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

View file

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

View file

@ -1,3 +1,4 @@
use self::following::send_follow_community;
use crate::{
activities::{
deletion::{send_apub_delete_in_community, DeletableObjects},
@ -250,6 +251,9 @@ pub async fn match_outgoing_activities(
LikePostOrComment(object_id, person, community, score) => {
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 {

View file

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