2 activities::community::announce::AnnounceActivity,
3 fetcher::{fetch::fetch_remote_object, object_id::ObjectId},
4 objects::community::Group,
6 use activitystreams::collection::{CollectionExt, OrderedCollection};
8 use lemmy_api_common::blocking;
9 use lemmy_apub_lib::ActivityHandler;
10 use lemmy_db_queries::Joinable;
11 use lemmy_db_schema::source::{
12 community::{Community, CommunityModerator, CommunityModeratorForm},
15 use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
16 use lemmy_utils::{location_info, LemmyError};
17 use lemmy_websocket::LemmyContext;
20 pub(crate) async fn update_community_mods(
22 community: &Community,
23 context: &LemmyContext,
24 request_counter: &mut i32,
25 ) -> Result<(), LemmyError> {
26 let new_moderators = fetch_community_mods(context, group, request_counter).await?;
27 let community_id = community.id;
28 let current_moderators = blocking(context.pool(), move |conn| {
29 CommunityModeratorView::for_community(conn, community_id)
32 // Remove old mods from database which arent in the moderators collection anymore
33 for mod_user in ¤t_moderators {
34 if !new_moderators.contains(&mod_user.moderator.actor_id.clone().into()) {
35 let community_moderator_form = CommunityModeratorForm {
36 community_id: mod_user.community.id,
37 person_id: mod_user.moderator.id,
39 blocking(context.pool(), move |conn| {
40 CommunityModerator::leave(conn, &community_moderator_form)
46 // Add new mods to database which have been added to moderators collection
47 for mod_id in new_moderators {
48 let mod_id = ObjectId::new(mod_id);
49 let mod_user: Person = mod_id.dereference(context, request_counter).await?;
51 if !current_moderators
54 .map(|c| c.moderator.actor_id.clone())
55 .any(|x| x == mod_user.actor_id)
57 let community_moderator_form = CommunityModeratorForm {
58 community_id: community.id,
59 person_id: mod_user.id,
61 blocking(context.pool(), move |conn| {
62 CommunityModerator::join(conn, &community_moderator_form)
71 pub(crate) async fn fetch_community_outbox(
72 context: &LemmyContext,
74 recursion_counter: &mut i32,
75 ) -> Result<(), LemmyError> {
76 let outbox = fetch_remote_object::<OrderedCollection>(
83 let outbox_activities = outbox.items().context(location_info!())?.clone();
84 let mut outbox_activities = outbox_activities.many().context(location_info!())?;
85 if outbox_activities.len() > 20 {
86 outbox_activities = outbox_activities[0..20].to_vec();
89 for announce in outbox_activities {
90 // TODO: instead of converting like this, we should create a struct CommunityOutbox with
91 // AnnounceActivity as inner type, but that gives me stackoverflow
92 let ser = serde_json::to_string(&announce)?;
93 let announce: AnnounceActivity = serde_json::from_str(&ser)?;
94 announce.receive(context, recursion_counter).await?;
100 async fn fetch_community_mods(
101 context: &LemmyContext,
103 recursion_counter: &mut i32,
104 ) -> Result<Vec<Url>, LemmyError> {
105 if let Some(mods_url) = &group.moderators {
106 let mods = fetch_remote_object::<OrderedCollection>(
115 .map(|i| i.as_many())
117 .context(location_info!())?
119 .filter_map(|i| i.as_xsd_any_uri())
120 .map(|u| u.to_owned())