]> Untitled Git - lemmy.git/blob - server/src/apub/community.rs
Merge remote-tracking branch 'upstream/master'
[lemmy.git] / server / src / apub / community.rs
1 use crate::apub::make_apub_endpoint;
2 use crate::db::community::Community;
3 use crate::db::community_view::CommunityFollowerView;
4 use crate::db::establish_unpooled_connection;
5 use crate::to_datetime_utc;
6 use activitypub::{actor::Group, collection::UnorderedCollection, context};
7 use actix_web::body::Body;
8 use actix_web::web::Path;
9 use actix_web::HttpResponse;
10 use serde::Deserialize;
11
12 impl Community {
13   pub fn as_group(&self) -> Group {
14     let base_url = make_apub_endpoint("c", &self.name);
15
16     let mut group = Group::default();
17
18     group.object_props.set_context_object(context()).ok();
19     group.object_props.set_id_string(base_url.to_string()).ok();
20     group
21       .object_props
22       .set_name_string(self.name.to_owned())
23       .ok();
24     group
25       .object_props
26       .set_published_utctime(to_datetime_utc(self.published))
27       .ok();
28     if let Some(updated) = self.updated {
29       group
30         .object_props
31         .set_updated_utctime(to_datetime_utc(updated))
32         .ok();
33     }
34
35     if let Some(description) = &self.description {
36       group
37         .object_props
38         .set_summary_string(description.to_string())
39         .ok();
40     }
41
42     group
43       .ap_actor_props
44       .set_inbox_string(format!("{}/inbox", &base_url))
45       .ok();
46     group
47       .ap_actor_props
48       .set_outbox_string(format!("{}/outbox", &base_url))
49       .ok();
50     group
51       .ap_actor_props
52       .set_followers_string(format!("{}/followers", &base_url))
53       .ok();
54
55     group
56   }
57
58   pub fn followers_as_collection(&self) -> UnorderedCollection {
59     let base_url = make_apub_endpoint("c", &self.name);
60
61     let mut collection = UnorderedCollection::default();
62     collection.object_props.set_context_object(context()).ok();
63     collection.object_props.set_id_string(base_url).ok();
64
65     let connection = establish_unpooled_connection();
66     //As we are an object, we validated that the community id was valid
67     let community_followers = CommunityFollowerView::for_community(&connection, self.id).unwrap();
68
69     let ap_followers = community_followers
70       .iter()
71       .map(|follower| make_apub_endpoint("u", &follower.user_name))
72       .collect();
73
74     collection
75       .collection_props
76       .set_items_string_vec(ap_followers)
77       .unwrap();
78     collection
79   }
80 }
81
82 #[derive(Deserialize)]
83 pub struct CommunityQuery {
84   community_name: String,
85 }
86
87 pub async fn get_apub_community(info: Path<CommunityQuery>) -> HttpResponse<Body> {
88   let connection = establish_unpooled_connection();
89
90   if let Ok(community) = Community::read_from_name(&connection, info.community_name.to_owned()) {
91     HttpResponse::Ok()
92       .content_type("application/activity+json")
93       .body(serde_json::to_string(&community.as_group()).unwrap())
94   } else {
95     HttpResponse::NotFound().finish()
96   }
97 }
98
99 pub async fn get_apub_community_followers(info: Path<CommunityQuery>) -> HttpResponse<Body> {
100   let connection = establish_unpooled_connection();
101
102   if let Ok(community) = Community::read_from_name(&connection, info.community_name.to_owned()) {
103     HttpResponse::Ok()
104       .content_type("application/activity+json")
105       .body(serde_json::to_string(&community.followers_as_collection()).unwrap())
106   } else {
107     HttpResponse::NotFound().finish()
108   }
109 }