From 97d798eeed68d2b3c3dd2233f85b6ae689e664b7 Mon Sep 17 00:00:00 2001 From: silverpill Date: Fri, 31 Dec 2021 16:43:14 +0000 Subject: [PATCH] Create helper functions for getting recipients of Create, Like and Announce activities --- src/mastodon_api/statuses/helpers.rs | 71 +++++++++++++++++++ src/mastodon_api/statuses/mod.rs | 1 + src/mastodon_api/statuses/views.rs | 102 ++++++--------------------- 3 files changed, 94 insertions(+), 80 deletions(-) create mode 100644 src/mastodon_api/statuses/helpers.rs diff --git a/src/mastodon_api/statuses/helpers.rs b/src/mastodon_api/statuses/helpers.rs new file mode 100644 index 0000000..6d97b8e --- /dev/null +++ b/src/mastodon_api/statuses/helpers.rs @@ -0,0 +1,71 @@ +use tokio_postgres::GenericClient; + +use crate::activitypub::actor::Actor; +use crate::errors::DatabaseError; +use crate::models::profiles::queries::get_followers; +use crate::models::posts::queries::get_post_author; +use crate::models::posts::types::Post; +use crate::models::users::types::User; + +pub async fn get_note_audience( + db_client: &impl GenericClient, + current_user: &User, + post: &Post, +) -> Result, DatabaseError> { + let mut audience = get_followers(db_client, ¤t_user.id).await?; + if let Some(in_reply_to_id) = post.in_reply_to_id { + // TODO: use post.in_reply_to ? + let in_reply_to_author = get_post_author(db_client, &in_reply_to_id).await?; + audience.push(in_reply_to_author); + }; + audience.extend(post.mentions.clone()); + let mut recipients: Vec = Vec::new(); + for profile in audience { + let maybe_remote_actor = profile.remote_actor()?; + if let Some(remote_actor) = maybe_remote_actor { + recipients.push(remote_actor); + }; + }; + Ok(recipients) +} + +pub struct Audience { + pub recipients: Vec, + pub primary_recipient: Option, +} + +pub async fn get_like_audience( + _db_client: &impl GenericClient, + post: &Post, +) -> Result { + let mut recipients: Vec = Vec::new(); + let mut primary_recipient = None; + let maybe_remote_author = post.author.remote_actor()?; + if let Some(remote_actor) = maybe_remote_author { + primary_recipient = Some(remote_actor.id.clone()); + recipients.push(remote_actor); + }; + Ok(Audience { recipients, primary_recipient }) +} + +pub async fn get_announce_audience( + db_client: &impl GenericClient, + current_user: &User, + post: &Post, +) -> Result { + let followers = get_followers(db_client, ¤t_user.id).await?; + let mut recipients: Vec = Vec::new(); + for profile in followers { + let maybe_remote_actor = profile.remote_actor()?; + if let Some(remote_actor) = maybe_remote_actor { + recipients.push(remote_actor); + }; + }; + let mut primary_recipient = None; + let maybe_remote_author = post.author.remote_actor()?; + if let Some(remote_actor) = maybe_remote_author { + primary_recipient = Some(remote_actor.id.clone()); + recipients.push(remote_actor); + }; + Ok(Audience { recipients, primary_recipient }) +} diff --git a/src/mastodon_api/statuses/mod.rs b/src/mastodon_api/statuses/mod.rs index a964b01..328cdc2 100644 --- a/src/mastodon_api/statuses/mod.rs +++ b/src/mastodon_api/statuses/mod.rs @@ -1,2 +1,3 @@ +mod helpers; pub mod types; pub mod views; diff --git a/src/mastodon_api/statuses/views.rs b/src/mastodon_api/statuses/views.rs index 56c8a83..658db08 100644 --- a/src/mastodon_api/statuses/views.rs +++ b/src/mastodon_api/statuses/views.rs @@ -12,7 +12,6 @@ use crate::activitypub::activity::{ create_activity_undo_announce, create_activity_delete_note, }; -use crate::activitypub::actor::Actor; use crate::activitypub::deliverer::deliver_activity; use crate::activitypub::views::get_object_url; use crate::config::Config; @@ -26,7 +25,6 @@ use crate::models::attachments::queries::set_attachment_ipfs_cid; use crate::models::posts::helpers::can_view_post; use crate::models::posts::mentions::{find_mentioned_profiles, replace_mentions}; use crate::models::posts::tags::{find_tags, replace_tags}; -use crate::models::profiles::queries::get_followers; use crate::models::posts::helpers::{ get_actions_for_posts, get_reposted_posts, @@ -35,7 +33,6 @@ use crate::models::posts::queries::{ create_post, get_post_by_id, get_thread, - get_post_author, find_reposts_by_user, update_post, delete_post, @@ -45,6 +42,12 @@ use crate::models::reactions::queries::{ create_reaction, delete_reaction, }; +use super::helpers::{ + get_announce_audience, + get_like_audience, + get_note_audience, + Audience, +}; use super::types::{Status, StatusData, TransactionData}; #[post("")] @@ -93,29 +96,7 @@ async fn create_status( &instance.url(), &post, ); - let followers = get_followers(db_client, ¤t_user.id).await?; - let mut recipients: Vec = Vec::new(); - for follower in followers { - let maybe_remote_actor = follower.remote_actor() - .map_err(|_| HttpError::InternalError)?; - if let Some(remote_actor) = maybe_remote_actor { - recipients.push(remote_actor); - }; - }; - if let Some(ref in_reply_to) = post.in_reply_to { - let maybe_remote_actor = in_reply_to.author.remote_actor() - .map_err(|_| HttpError::InternalError)?; - if let Some(remote_actor) = maybe_remote_actor { - recipients.push(remote_actor); - } - } - for profile in post.mentions.iter() { - let maybe_remote_actor = profile.remote_actor() - .map_err(|_| HttpError::InternalError)?; - if let Some(remote_actor) = maybe_remote_actor { - recipients.push(remote_actor); - }; - }; + let recipients = get_note_audience(db_client, ¤t_user, &post).await?; deliver_activity(&config, ¤t_user, activity, recipients); let status = Status::from_post(post, &instance.url()); Ok(HttpResponse::Created().json(status)) @@ -169,20 +150,7 @@ async fn delete_status( ¤t_user.profile, &post, ); - let mut audience = get_followers(db_client, ¤t_user.id).await?; - if let Some(in_reply_to_id) = post.in_reply_to_id { - let in_reply_to_author = get_post_author(db_client, &in_reply_to_id).await?; - audience.push(in_reply_to_author); - }; - audience.extend(post.mentions); - let mut recipients: Vec = Vec::new(); - for profile in audience { - let maybe_remote_actor = profile.remote_actor() - .map_err(|_| HttpError::InternalError)?; - if let Some(remote_actor) = maybe_remote_actor { - recipients.push(remote_actor); - }; - }; + let recipients = get_note_audience(db_client, ¤t_user, &post).await?; deliver_activity(&config, ¤t_user, activity, recipients); Ok(HttpResponse::NoContent().finish()) @@ -247,9 +215,9 @@ async fn favourite( get_actions_for_posts(db_client, ¤t_user.id, vec![&mut post]).await?; if let Some(reaction) = maybe_reaction_created { - let maybe_remote_actor = post.author.remote_actor() - .map_err(|_| HttpError::InternalError)?; - if let Some(remote_actor) = maybe_remote_actor { + let Audience { recipients, primary_recipient } = + get_like_audience(db_client, &post).await?; + if let Some(remote_actor_id) = primary_recipient { // Federate let object_id = post.object_id.as_ref().ok_or(HttpError::InternalError)?; let activity = create_activity_like( @@ -257,9 +225,9 @@ async fn favourite( ¤t_user.profile, object_id, &reaction.id, - &remote_actor.id, + &remote_actor_id, ); - deliver_activity(&config, ¤t_user, activity, vec![remote_actor]); + deliver_activity(&config, ¤t_user, activity, recipients); } } @@ -294,17 +262,17 @@ async fn unfavourite( get_actions_for_posts(db_client, ¤t_user.id, vec![&mut post]).await?; if let Some(reaction_id) = maybe_reaction_deleted { - let maybe_remote_actor = post.author.remote_actor() - .map_err(|_| HttpError::InternalError)?; - if let Some(remote_actor) = maybe_remote_actor { + let Audience { recipients, primary_recipient } = + get_like_audience(db_client, &post).await?; + if let Some(remote_actor_id) = primary_recipient { // Federate let activity = create_activity_undo_like( &config.instance_url(), ¤t_user.profile, &reaction_id, - &remote_actor.id, + &remote_actor_id, ); - deliver_activity(&config, ¤t_user, activity, vec![remote_actor]); + deliver_activity(&config, ¤t_user, activity, recipients); }; }; @@ -331,26 +299,14 @@ async fn reblog( get_actions_for_posts(db_client, ¤t_user.id, vec![&mut post]).await?; // Federate + let Audience { recipients, .. } = + get_announce_audience(db_client, ¤t_user, &post).await?; let activity = create_activity_announce( &config.instance_url(), ¤t_user.profile, &post, &repost.id, ); - let mut recipients: Vec = Vec::new(); - let followers = get_followers(db_client, ¤t_user.id).await?; - for follower in followers { - let maybe_remote_follower = follower.remote_actor() - .map_err(|_| HttpError::InternalError)?; - if let Some(remote_actor) = maybe_remote_follower { - recipients.push(remote_actor); - }; - }; - let maybe_remote_author = post.author.remote_actor() - .map_err(|_| HttpError::InternalError)?; - if let Some(remote_actor) = maybe_remote_author { - recipients.push(remote_actor); - }; deliver_activity(&config, ¤t_user, activity, recipients); let status = Status::from_post(post, &config.instance_url()); @@ -375,22 +331,8 @@ async fn unreblog( get_actions_for_posts(db_client, ¤t_user.id, vec![&mut post]).await?; // Federate - let mut primary_recipient = None; - let mut recipients: Vec = Vec::new(); - let followers = get_followers(db_client, ¤t_user.id).await?; - for follower in followers { - let maybe_remote_follower = follower.remote_actor() - .map_err(|_| HttpError::InternalError)?; - if let Some(remote_actor) = maybe_remote_follower { - recipients.push(remote_actor); - }; - }; - let maybe_remote_author = post.author.remote_actor() - .map_err(|_| HttpError::InternalError)?; - if let Some(remote_actor) = maybe_remote_author { - primary_recipient = Some(remote_actor.id.clone()); - recipients.push(remote_actor); - }; + let Audience { recipients, primary_recipient } = + get_announce_audience(db_client, ¤t_user, &post).await?; let activity = create_activity_undo_announce( &config.instance_url(), ¤t_user.profile,