summaryrefslogtreecommitdiffstats
path: root/server/src/apub/community.rs
diff options
context:
space:
mode:
authorFelix Ableitner <me@nutomic.com>2020-04-03 07:02:43 +0200
committerFelix Ableitner <me@nutomic.com>2020-04-03 07:02:43 +0200
commit96c3621a801d96a8d2bffc849d871c297683e387 (patch)
tree32487c48a63fa9d01ce4ae4d9bb09421815e77e0 /server/src/apub/community.rs
parent0d369e60197fd8a967200ee6c02a9f84beaf5dca (diff)
Share list of communities over apub, some refactoring
Diffstat (limited to 'server/src/apub/community.rs')
-rw-r--r--server/src/apub/community.rs159
1 files changed, 124 insertions, 35 deletions
diff --git a/server/src/apub/community.rs b/server/src/apub/community.rs
index 2f533b97..67cd99c4 100644
--- a/server/src/apub/community.rs
+++ b/server/src/apub/community.rs
@@ -1,15 +1,19 @@
-use crate::apub::{create_apub_response, make_apub_endpoint, EndpointType};
+use crate::api::community::ListCommunities;
+use crate::api::{Oper, Perform};
+use crate::apub::puller::{fetch_remote_object, format_community_name};
+use crate::apub::{
+ create_apub_response, get_apub_protocol_string, make_apub_endpoint, EndpointType, GroupExt,
+};
use crate::convert_datetime;
use crate::db::community::Community;
-use crate::db::community_view::CommunityFollowerView;
+use crate::db::community_view::{CommunityFollowerView, CommunityView};
use crate::db::establish_unpooled_connection;
use crate::db::post_view::{PostQueryBuilder, PostView};
+use crate::settings::Settings;
+use activitystreams::actor::properties::ApActorProperties;
use activitystreams::collection::OrderedCollection;
use activitystreams::{
- actor::{properties::ApActorProperties, Group},
- collection::UnorderedCollection,
- context,
- ext::Extensible,
+ actor::Group, collection::UnorderedCollection, context, ext::Extensible,
object::properties::ObjectProperties,
};
use actix_web::body::Body;
@@ -26,41 +30,126 @@ pub struct CommunityQuery {
community_name: String,
}
-pub async fn get_apub_community(
- info: Path<CommunityQuery>,
+pub async fn get_apub_community_list(
db: web::Data<Pool<ConnectionManager<PgConnection>>>,
) -> Result<HttpResponse<Body>, Error> {
- let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
- let base_url = make_apub_endpoint(EndpointType::Community, &community.name);
+ // TODO: implement pagination
+ let query = ListCommunities {
+ sort: "Hot".to_string(),
+ page: None,
+ limit: None,
+ auth: None,
+ local_only: Some(true),
+ };
+ let communities = Oper::new(query)
+ .perform(&db.get().unwrap())
+ .unwrap()
+ .communities
+ .iter()
+ .map(|c| c.as_group())
+ .collect::<Result<Vec<GroupExt>, failure::Error>>()?;
+ let mut collection = UnorderedCollection::default();
+ let oprops: &mut ObjectProperties = collection.as_mut();
+ oprops.set_context_xsd_any_uri(context())?.set_id(format!(
+ "{}://{}/federation/communities",
+ get_apub_protocol_string(),
+ Settings::get().hostname
+ ))?;
- let mut group = Group::default();
- let oprops: &mut ObjectProperties = group.as_mut();
+ collection
+ .collection_props
+ .set_total_items(communities.len() as u64)?
+ .set_many_items_base_boxes(communities)?;
+ Ok(create_apub_response(&collection))
+}
- oprops
- .set_context_xsd_any_uri(context())?
- .set_id(base_url.to_owned())?
- .set_name_xsd_string(community.title.to_owned())?
- .set_published(convert_datetime(community.published))?
- .set_attributed_to_xsd_any_uri(make_apub_endpoint(
- EndpointType::User,
- &community.creator_id.to_string(),
- ))?;
-
- if let Some(u) = community.updated.to_owned() {
- oprops.set_updated(convert_datetime(u))?;
- }
- if let Some(d) = community.description {
- oprops.set_summary_xsd_string(d)?;
- }
+impl CommunityView {
+ fn as_group(&self) -> Result<GroupExt, Error> {
+ let base_url = make_apub_endpoint(EndpointType::Community, &self.name);
+
+ let mut group = Group::default();
+ let oprops: &mut ObjectProperties = group.as_mut();
+
+ oprops
+ .set_context_xsd_any_uri(context())?
+ .set_id(base_url.to_owned())?
+ .set_name_xsd_string(self.name.to_owned())?
+ .set_published(convert_datetime(self.published))?
+ .set_attributed_to_xsd_any_uri(make_apub_endpoint(
+ EndpointType::User,
+ &self.creator_id.to_string(),
+ ))?;
+
+ if let Some(u) = self.updated.to_owned() {
+ oprops.set_updated(convert_datetime(u))?;
+ }
+ if let Some(d) = self.description.to_owned() {
+ oprops.set_summary_xsd_string(d)?;
+ }
- let mut actor_props = ApActorProperties::default();
+ let mut actor_props = ApActorProperties::default();
- actor_props
- .set_inbox(format!("{}/inbox", &base_url))?
- .set_outbox(format!("{}/outbox", &base_url))?
- .set_followers(format!("{}/followers", &base_url))?;
+ actor_props
+ .set_preferred_username(self.title.to_owned())?
+ .set_inbox(format!("{}/inbox", &base_url))?
+ .set_outbox(format!("{}/outbox", &base_url))?
+ .set_followers(format!("{}/followers", &base_url))?;
- Ok(create_apub_response(&group.extend(actor_props)))
+ Ok(group.extend(actor_props))
+ }
+
+ pub fn from_group(group: &GroupExt, domain: &str) -> Result<CommunityView, Error> {
+ let followers_uri = &group.extension.get_followers().unwrap().to_string();
+ let outbox_uri = &group.extension.get_outbox().to_string();
+ let outbox = fetch_remote_object::<OrderedCollection>(outbox_uri)?;
+ let followers = fetch_remote_object::<UnorderedCollection>(followers_uri)?;
+ let oprops = &group.base.object_props;
+ let aprops = &group.extension;
+ Ok(CommunityView {
+ // TODO: we need to merge id and name into a single thing (stuff like @user@instance.com)
+ id: 1337, //community.object_props.get_id()
+ name: format_community_name(&oprops.get_name_xsd_string().unwrap().to_string(), domain),
+ title: aprops.get_preferred_username().unwrap().to_string(),
+ description: oprops.get_summary_xsd_string().map(|s| s.to_string()),
+ category_id: -1,
+ creator_id: -1, //community.object_props.get_attributed_to_xsd_any_uri()
+ removed: false,
+ published: oprops
+ .get_published()
+ .unwrap()
+ .as_ref()
+ .naive_local()
+ .to_owned(),
+ updated: oprops
+ .get_updated()
+ .map(|u| u.as_ref().to_owned().naive_local()),
+ deleted: false,
+ nsfw: false,
+ creator_name: "".to_string(),
+ creator_avatar: None,
+ category_name: "".to_string(),
+ number_of_subscribers: *followers
+ .collection_props
+ .get_total_items()
+ .unwrap()
+ .as_ref() as i64,
+ number_of_posts: *outbox.collection_props.get_total_items().unwrap().as_ref() as i64,
+ number_of_comments: -1,
+ hot_rank: -1,
+ user_id: None,
+ subscribed: None,
+ })
+ }
+}
+
+pub async fn get_apub_community_http(
+ info: Path<CommunityQuery>,
+ db: web::Data<Pool<ConnectionManager<PgConnection>>>,
+) -> Result<HttpResponse<Body>, Error> {
+ let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
+ let community_view = CommunityView::read(&&db.get()?, community.id, None)?;
+ let c = community_view.as_group()?;
+ Ok(create_apub_response(&c))
}
pub async fn get_apub_community_followers(
@@ -107,7 +196,7 @@ pub async fn get_apub_community_outbox(
.set_id(base_url)?;
collection
.collection_props
- .set_many_items_object_boxs(
+ .set_many_items_base_boxes(
community_posts
.iter()
.map(|c| c.as_page().unwrap())