feat: show users following/followers

use audience for followers, generator for following and replies for
total statuses count. restored followers, following and outbox as bare
links. silly AP!!!
This commit is contained in:
əlemi 2024-04-30 00:53:07 +02:00
parent 5bdf139ef5
commit 97ed5d60b1
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 38 additions and 18 deletions

View file

@ -1,6 +1,6 @@
use sea_orm::entity::prelude::*; 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; use crate::routes::activitypub::jsonld::LD;
@ -59,9 +59,9 @@ impl Model {
following: object.following().id(), following: object.following().id(),
created: object.published().unwrap_or(chrono::Utc::now()), created: object.published().unwrap_or(chrono::Utc::now()),
updated: 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, 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.followers().get().map(|f| f.total_items().unwrap_or(0)).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.outbox().get().map(|o| o.total_items().unwrap_or(0)).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(), 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 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_discoverable(Some(true))
.set_endpoints(apb::Node::Empty) .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))
))
} }
} }

View file

@ -7,7 +7,7 @@ pub mod following;
use axum::extract::{Path, Query, State}; use axum::extract::{Path, Query, State};
use sea_orm::EntityTrait; 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 crate::{errors::UpubError, model::{self, user}, server::{auth::AuthIdentity, fetcher::Fetcher, Context}, url};
use super::{jsonld::LD, JsonLD, TryFetch}; use super::{jsonld::LD, JsonLD, TryFetch};
@ -32,20 +32,22 @@ pub async fn view(
.one(ctx.db()).await? .one(ctx.db()).await?
{ {
// local user // local user
Some((user, Some(_cfg))) => { Some((user, Some(cfg))) => {
Ok(JsonLD(user.clone().ap() // ew ugly clone TODO let mut user = user.ap()
.set_inbox(Node::link(url!(ctx, "/users/{id}/inbox"))) // TODO unread activities as count .set_inbox(Node::link(url!(ctx, "/users/{id}/inbox")))
.set_outbox(Node::object( .set_outbox(Node::link(url!(ctx, "/users/{id}/outbox")))
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))
))
.set_following(Node::link(url!(ctx, "/users/{id}/following"))) .set_following(Node::link(url!(ctx, "/users/{id}/following")))
.set_followers(Node::link(url!(ctx, "/users/{id}/followers"))) .set_followers(Node::link(url!(ctx, "/users/{id}/followers")));
.ld_context()
)) 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? // remote user TODDO doesn't work?
Some((user, None)) => Ok(JsonLD(user.ap().ld_context())), Some((user, None)) => Ok(JsonLD(user.ap().ld_context())),