diff options
author | Felix Ableitner <me@nutomic.com> | 2020-04-03 07:02:43 +0200 |
---|---|---|
committer | Felix Ableitner <me@nutomic.com> | 2020-04-03 07:02:43 +0200 |
commit | 96c3621a801d96a8d2bffc849d871c297683e387 (patch) | |
tree | 32487c48a63fa9d01ce4ae4d9bb09421815e77e0 /server/src/apub/community.rs | |
parent | 0d369e60197fd8a967200ee6c02a9f84beaf5dca (diff) |
Share list of communities over apub, some refactoring
Diffstat (limited to 'server/src/apub/community.rs')
-rw-r--r-- | server/src/apub/community.rs | 159 |
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()) |