diff --git a/src/routes/activitypub/context.rs b/src/routes/activitypub/context.rs new file mode 100644 index 0000000..4820a5d --- /dev/null +++ b/src/routes/activitypub/context.rs @@ -0,0 +1,62 @@ +use axum::extract::{Path, Query, State}; +use sea_orm::{ColumnTrait, Order, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect}; + +use crate::{model::{self, addressing::EmbeddedActivity}, routes::activitypub::{jsonld::LD, JsonLD, Pagination}, server::{auth::AuthIdentity, Context}, url}; + +pub async fn get( + State(ctx): State, + Path(id): Path, + AuthIdentity(auth): AuthIdentity, +) -> crate::Result> { + let context = if id.starts_with('+') { + format!("https://{}", id.replacen('+', "", 1).replace('@', "/")) + } else { + url!(ctx, "/context/{id}") + }; + + let count = model::addressing::Entity::find_objects() + .filter(auth.filter_condition()) + .filter(model::object::Column::Context.eq(context)) + .count(ctx.db()) + .await?; + + Ok(JsonLD(ctx.ap_collection(&url!(ctx, "/context/{id}"), Some(count)).ld_context())) +} + +pub async fn page( + State(ctx): State, + Path(id): Path, + Query(page): Query, + AuthIdentity(auth): AuthIdentity, +) -> crate::Result> { + let limit = page.batch.unwrap_or(20).min(50); + let offset = page.offset.unwrap_or(0); + + let context = if id.starts_with('+') { + format!("https://{}", id.replacen('+', "", 1).replace('@', "/")) + } else { + url!(ctx, "/context/{id}") + }; + + let items = model::addressing::Entity::find_objects() + .filter(auth.filter_condition()) + .filter(model::object::Column::Context.eq(context)) + // TODO also limit to only local activities + .order_by(model::addressing::Column::Published, Order::Desc) + .limit(limit) + .offset(offset) + .into_model::() + .all(ctx.db()) + .await?; + + Ok(JsonLD( + ctx.ap_collection_page( + &url!(ctx, "/context/{id}"), + offset, limit, + items + .into_iter() + .filter_map(|x| Some(x.object?.ap())) + .collect() + ).ld_context() + )) +} diff --git a/src/routes/activitypub/mod.rs b/src/routes/activitypub/mod.rs index 1bc1f3b..57ed8f7 100644 --- a/src/routes/activitypub/mod.rs +++ b/src/routes/activitypub/mod.rs @@ -2,6 +2,7 @@ pub mod user; pub mod inbox; pub mod outbox; pub mod object; +pub mod context; pub mod activity; pub mod application; pub mod auth; @@ -53,8 +54,8 @@ impl ActivityPubRouter for Router { // activities .route("/activities/:id", get(ap::activity::view)) // context - //.route("/context/:id", get(ap::context::get)) - //.route("/context/:id/page", get(ap::context::page)) + .route("/context/:id", get(ap::context::get)) + .route("/context/:id/page", get(ap::context::page)) // specific object routes .route("/objects/:id", get(ap::object::view)) //.route("/objects/:id/likes", get(ap::object::likes::get))