From 437908f7d5b7adc4d574fe92b49595592c58454a Mon Sep 17 00:00:00 2001 From: alemi Date: Thu, 26 Dec 2024 17:19:35 +0100 Subject: [PATCH] feat: add likes collection for actor --- upub/routes/src/activitypub/actor/likes.rs | 65 ++++++++++++++++++++++ upub/routes/src/activitypub/actor/mod.rs | 1 + upub/routes/src/activitypub/mod.rs | 2 + 3 files changed, 68 insertions(+) create mode 100644 upub/routes/src/activitypub/actor/likes.rs diff --git a/upub/routes/src/activitypub/actor/likes.rs b/upub/routes/src/activitypub/actor/likes.rs new file mode 100644 index 0000000..a20eb52 --- /dev/null +++ b/upub/routes/src/activitypub/actor/likes.rs @@ -0,0 +1,65 @@ +use axum::extract::{Path, Query, State}; +use sea_orm::{ColumnTrait, QueryFilter, QueryOrder, QuerySelect, RelationTrait}; + +use upub::{model, selector::{RichObject, BatchFillable}, Context}; + +use crate::{activitypub::Pagination, builders::JsonLD, ApiError, AuthIdentity}; + +pub async fn get( + State(ctx): State, + Path(id): Path, +) -> crate::ApiResult> { + crate::builders::collection(upub::url!(ctx, "/actors/{id}/liked"), None) +} + +pub async fn page( + State(ctx): State, + Path(id): Path, + Query(page): Query, + AuthIdentity(auth): AuthIdentity, +) -> crate::ApiResult> { + let uid = ctx.uid(&id); + let (user, config) = model::actor::Entity::find_by_ap_id(&uid) + .find_also_related(model::config::Entity) + .one(ctx.db()) + .await? + .ok_or_else(ApiError::not_found)?; + + if !auth.is(&uid) && !config.map_or(false, |x| x.show_liked_objects) { + return Err(ApiError::forbidden()); + } + + let (limit, offset) = page.pagination(); + + let mut select = upub::Query::objects(auth.my_id()) + .join(sea_orm::JoinType::InnerJoin, upub::model::object::Relation::Likes.def()) + .filter(auth.filter_objects()) + .filter(upub::model::like::Column::Actor.eq(user.internal)) + .order_by_desc(upub::model::like::Column::Published) + .limit(limit) + .offset(offset); + + let items : Vec = select + .into_model::() + .all(ctx.db()) + .await? + .with_batched::(ctx.db()) + .await? + .with_batched::(ctx.db()) + .await? + .with_batched::(ctx.db()) + .await? + .into_iter() + .map(|x| ctx.ap(x)) + .collect(); + + crate::builders::paginate_feed( + upub::url!(ctx, "/actors/{id}/outbox/page"), + auth.filter_objects(), + &ctx, + page, + auth.my_id(), + false, + ) + .await +} diff --git a/upub/routes/src/activitypub/actor/mod.rs b/upub/routes/src/activitypub/actor/mod.rs index a71c46b..b6285c8 100644 --- a/upub/routes/src/activitypub/actor/mod.rs +++ b/upub/routes/src/activitypub/actor/mod.rs @@ -1,5 +1,6 @@ pub mod inbox; pub mod outbox; +pub mod likes; pub mod following; pub mod notifications; // pub mod audience; diff --git a/upub/routes/src/activitypub/mod.rs b/upub/routes/src/activitypub/mod.rs index d50e0c0..53c03ba 100644 --- a/upub/routes/src/activitypub/mod.rs +++ b/upub/routes/src/activitypub/mod.rs @@ -57,6 +57,8 @@ impl ActivityPubRouter for Router { .route("/actors/:id/followers/page", get(ap::actor::following::page::)) .route("/actors/:id/following", get(ap::actor::following::get::)) .route("/actors/:id/following/page", get(ap::actor::following::page::)) + .route("/actors/:id/likes", get(ap::actor::likes::get)) + .route("/actors/:id/likes/page", get(ap::actor::likes::page)) // .route("/actors/:id/audience", get(ap::actor::audience::get)) // .route("/actors/:id/audience/page", get(ap::actor::audience::page)) // activities