-use crate::{
- activities::generate_activity_id,
- activity_queue::{send_to_community, send_to_community_followers},
- check_is_apub_id_valid,
- extensions::context::lemmy_context,
- fetcher::get_or_fetch_and_upsert_actor,
- generate_moderators_url,
- insert_activity,
- objects::ToApub,
- ActorType,
- CommunityType,
-};
-use activitystreams::{
- activity::{
- kind::{AddType, AnnounceType, BlockType, RemoveType, UndoType, UpdateType},
- Add,
- Announce,
- Block,
- OptTargetRefExt,
- Remove,
- Undo,
- Update,
- },
- base::{AnyBase, BaseExt, ExtendsExt},
- object::ObjectExt,
- public,
-};
-use anyhow::Context;
+use crate::{check_is_apub_id_valid, ActorType, CommunityType};
use itertools::Itertools;
use lemmy_api_common::blocking;
use lemmy_db_queries::DbPool;
-use lemmy_db_schema::source::{community::Community, person::Person};
+use lemmy_db_schema::source::community::Community;
use lemmy_db_views_actor::community_follower_view::CommunityFollowerView;
-use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
-use lemmy_websocket::LemmyContext;
+use lemmy_utils::LemmyError;
use url::Url;
impl ActorType for Community {
self.followers_url.clone().into()
}
- /// If a remote community is updated by a local mod, send the updated info to the community's
- /// instance.
- async fn send_update(&self, mod_: Person, context: &LemmyContext) -> Result<(), LemmyError> {
- if self.local {
- // Do nothing, other instances will automatically refetch the community
- } else {
- let mut update = Update::new(
- mod_.actor_id(),
- AnyBase::from_arbitrary_json(self.to_apub(context.pool()).await?)?,
- );
- update
- .set_many_contexts(lemmy_context())
- .set_id(generate_activity_id(UpdateType::Update)?)
- .set_to(public())
- .set_many_ccs(vec![self.actor_id()]);
- send_to_community(update, &mod_, self, None, context).await?;
- }
- Ok(())
- }
-
- /// Wraps an activity sent to the community in an announce, and then sends the announce to all
- /// community followers.
- ///
- /// If we are announcing a local activity, it hasn't been stored in the database yet, and we need
- /// to do it here, so that it can be fetched by ID. Remote activities are inserted into DB in the
- /// inbox.
- ///
- /// If the `object` of the announced activity is an actor, the actor ID needs to be passed as
- /// `object_actor`, so that the announce can be delivered to that user.
- async fn send_announce(
- &self,
- activity: AnyBase,
- object_actor: Option<Url>,
- context: &LemmyContext,
- ) -> Result<(), LemmyError> {
- let inner_id = activity.id().context(location_info!())?;
- if inner_id.domain() == Some(&Settings::get().get_hostname_without_port()?) {
- insert_activity(inner_id, activity.clone(), true, false, context.pool()).await?;
- }
-
- let mut ccs = vec![self.followers_url()];
- let mut object_actor_inbox: Option<Url> = None;
- if let Some(actor_id) = object_actor {
- // Ignore errors, maybe its not actually an actor
- // TODO: should pass the actual request counter in, but that seems complicated
- let actor = get_or_fetch_and_upsert_actor(&actor_id, context, &mut 0)
- .await
- .ok();
- if let Some(actor) = actor {
- ccs.push(actor_id);
- object_actor_inbox = Some(actor.get_shared_inbox_or_inbox_url());
- }
- }
- let mut announce = Announce::new(self.actor_id(), activity);
- announce
- .set_many_contexts(lemmy_context())
- .set_id(generate_activity_id(AnnounceType::Announce)?)
- .set_to(public())
- .set_many_ccs(ccs);
-
- send_to_community_followers(announce, self, object_actor_inbox, context).await?;
-
- Ok(())
- }
-
/// For a given community, returns the inboxes of all followers.
async fn get_follower_inboxes(&self, pool: &DbPool) -> Result<Vec<Url>, LemmyError> {
let id = self.id;
Ok(inboxes)
}
-
- async fn send_add_mod(
- &self,
- actor: &Person,
- added_mod: Person,
- context: &LemmyContext,
- ) -> Result<(), LemmyError> {
- let mut add = Add::new(actor.actor_id(), added_mod.actor_id());
- add
- .set_many_contexts(lemmy_context())
- .set_id(generate_activity_id(AddType::Add)?)
- .set_to(public())
- .set_many_ccs(vec![self.actor_id()])
- .set_target(generate_moderators_url(&self.actor_id)?.into_inner());
-
- send_to_community(add, actor, self, Some(added_mod.actor_id()), context).await?;
- Ok(())
- }
-
- async fn send_remove_mod(
- &self,
- actor: &Person,
- removed_mod: Person,
- context: &LemmyContext,
- ) -> Result<(), LemmyError> {
- let mut remove = Remove::new(actor.actor_id(), removed_mod.actor_id());
- remove
- .set_many_contexts(lemmy_context())
- .set_id(generate_activity_id(RemoveType::Remove)?)
- .set_to(public())
- .set_many_ccs(vec![self.actor_id()])
- .set_target(generate_moderators_url(&self.actor_id)?.into_inner());
-
- send_to_community(remove, actor, self, Some(removed_mod.actor_id()), context).await?;
- Ok(())
- }
-
- async fn send_block_user(
- &self,
- actor: &Person,
- blocked_user: Person,
- context: &LemmyContext,
- ) -> Result<(), LemmyError> {
- let mut block = Block::new(actor.actor_id(), blocked_user.actor_id());
- block
- .set_many_contexts(lemmy_context())
- .set_id(generate_activity_id(BlockType::Block)?)
- .set_to(public())
- .set_many_ccs(vec![self.actor_id()]);
-
- send_to_community(block, actor, self, Some(blocked_user.actor_id()), context).await?;
- Ok(())
- }
-
- async fn send_undo_block_user(
- &self,
- actor: &Person,
- unblocked_user: Person,
- context: &LemmyContext,
- ) -> Result<(), LemmyError> {
- let mut block = Block::new(actor.actor_id(), unblocked_user.actor_id());
- block
- .set_many_contexts(lemmy_context())
- .set_id(generate_activity_id(BlockType::Block)?)
- .set_to(public())
- .set_many_ccs(vec![self.actor_id()]);
-
- // Undo that fake activity
- let mut undo = Undo::new(actor.actor_id(), block.into_any_base()?);
- undo
- .set_many_contexts(lemmy_context())
- .set_id(generate_activity_id(UndoType::Undo)?)
- .set_to(public())
- .set_many_ccs(vec![self.actor_id()]);
-
- send_to_community(undo, actor, self, Some(unblocked_user.actor_id()), context).await?;
- Ok(())
- }
}