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> {
77 fetch_remote_object::<OrderedCollection>(context.client(), outbox, recursion_counter).await?;
78 let outbox_activities = outbox.items().context(location_info!())?.clone();
79 let mut outbox_activities = outbox_activities.many().context(location_info!())?;
80 if outbox_activities.len() > 20 {
81 outbox_activities = outbox_activities[0..20].to_vec();
84 for announce in outbox_activities {
85 // TODO: instead of converting like this, we should create a struct CommunityOutbox with
86 // AnnounceActivity as inner type, but that gives me stackoverflow
87 let ser = serde_json::to_string(&announce)?;
88 let announce: AnnounceActivity = serde_json::from_str(&ser)?;
89 announce.receive(context, recursion_counter).await?;
95 async fn fetch_community_mods(
96 context: &LemmyContext,
98 recursion_counter: &mut i32,
99 ) -> Result<Vec<Url>, LemmyError> {
100 if let Some(mods_url) = &group.moderators {
102 fetch_remote_object::<OrderedCollection>(context.client(), mods_url, recursion_counter)
106 .map(|i| i.as_many())
108 .context(location_info!())?
110 .filter_map(|i| i.as_xsd_any_uri())
111 .map(|u| u.to_owned())