diff --git a/src/model/user.rs b/src/model/user.rs index 068a00b..c0de334 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -1,6 +1,6 @@ use sea_orm::entity::prelude::*; -use apb::{Actor, ActorMut, ActorType, BaseMut, Collection, DocumentMut, Object, ObjectMut, PublicKey, PublicKeyMut}; +use apb::{Actor, ActorMut, ActorType, BaseMut, Collection, CollectionMut, DocumentMut, Object, ObjectMut, PublicKey, PublicKeyMut}; use crate::routes::activitypub::jsonld::LD; @@ -59,9 +59,9 @@ impl Model { following: object.following().id(), created: object.published().unwrap_or(chrono::Utc::now()), updated: chrono::Utc::now(), - following_count: object.following().get().map(|f| f.total_items().unwrap_or(0)).unwrap_or(0) as i64, - followers_count: object.followers().get().map(|f| f.total_items().unwrap_or(0)).unwrap_or(0) as i64, - statuses_count: object.outbox().get().map(|o| o.total_items().unwrap_or(0)).unwrap_or(0) as i64, + following_count: object.generator().get().map_or(0, |f| f.as_collection().map_or(0, |f| f.total_items().unwrap_or(0))) as i64, + followers_count: object.audience().get().map_or(0, |f| f.as_collection().map_or(0, |f| f.total_items().unwrap_or(0))) as i64, + statuses_count: object.replies().get().map_or(0, |o| o.total_items().unwrap_or(0)) as i64, public_key: object.public_key().get().ok_or(super::FieldError("publicKey"))?.public_key_pem().to_string(), private_key: None, // there's no way to transport privkey over AP json, must come from DB }) @@ -97,6 +97,24 @@ impl Model { )) .set_discoverable(Some(true)) .set_endpoints(apb::Node::Empty) + .set_replies(apb::Node::object( + serde_json::Value::new_object() + .set_id(self.outbox.as_deref()) + .set_collection_type(Some(apb::CollectionType::OrderedCollection)) + .set_total_items(Some(self.statuses_count as u64)) + )) + .set_audience(apb::Node::object( + serde_json::Value::new_object() + .set_id(self.followers.as_deref()) + .set_collection_type(Some(apb::CollectionType::OrderedCollection)) + .set_total_items(Some(self.followers_count as u64)) + )) + .set_generator(apb::Node::object( + serde_json::Value::new_object() + .set_id(self.following.as_deref()) + .set_collection_type(Some(apb::CollectionType::OrderedCollection)) + .set_total_items(Some(self.following_count as u64)) + )) } } diff --git a/src/routes/activitypub/user/mod.rs b/src/routes/activitypub/user/mod.rs index bda67a0..c24f7e2 100644 --- a/src/routes/activitypub/user/mod.rs +++ b/src/routes/activitypub/user/mod.rs @@ -7,7 +7,7 @@ pub mod following; use axum::extract::{Path, Query, State}; use sea_orm::EntityTrait; -use apb::{ActorMut, BaseMut, CollectionMut, Node}; +use apb::{ActorMut, BaseMut, CollectionMut, Node, ObjectMut}; use crate::{errors::UpubError, model::{self, user}, server::{auth::AuthIdentity, fetcher::Fetcher, Context}, url}; use super::{jsonld::LD, JsonLD, TryFetch}; @@ -32,20 +32,22 @@ pub async fn view( .one(ctx.db()).await? { // local user - Some((user, Some(_cfg))) => { - Ok(JsonLD(user.clone().ap() // ew ugly clone TODO - .set_inbox(Node::link(url!(ctx, "/users/{id}/inbox"))) // TODO unread activities as count - .set_outbox(Node::object( - serde_json::Value::new_object() - .set_id(Some(&url!(ctx, "/users/{id}/outbox"))) - .set_collection_type(Some(apb::CollectionType::OrderedCollection)) - .set_first(Node::link(url!(ctx, "/users/{id}/outbox/page"))) - .set_total_items(Some(user.statuses_count as u64)) - )) + Some((user, Some(cfg))) => { + let mut user = user.ap() + .set_inbox(Node::link(url!(ctx, "/users/{id}/inbox"))) + .set_outbox(Node::link(url!(ctx, "/users/{id}/outbox"))) .set_following(Node::link(url!(ctx, "/users/{id}/following"))) - .set_followers(Node::link(url!(ctx, "/users/{id}/followers"))) - .ld_context() - )) + .set_followers(Node::link(url!(ctx, "/users/{id}/followers"))); + + if !cfg.show_followers_count { + user = user.set_audience(apb::Node::Empty); + } + + if !cfg.show_following_count { + user = user.set_generator(apb::Node::Empty); + } + + Ok(JsonLD(user.ld_context())) }, // remote user TODDO doesn't work? Some((user, None)) => Ok(JsonLD(user.ap().ld_context())),