diff --git a/upub/cli/src/nuke.rs b/upub/cli/src/nuke.rs index 15108ea..f01cf8e 100644 --- a/upub/cli/src/nuke.rs +++ b/upub/cli/src/nuke.rs @@ -52,13 +52,13 @@ pub async fn nuke(ctx: upub::Context, for_real: bool, delete_posts: bool) -> Res }; let (target, undone) = if matches!(activity.activity_type, apb::ActivityType::Follow) { - (oid.clone(), activity.clone().ap()) + (oid.clone(), ctx.ap(activity.clone())) } else { let follow_activity = upub::model::activity::Entity::find_by_ap_id(oid) .one(ctx.db()) .await? .ok_or(sea_orm::DbErr::RecordNotFound(oid.clone()))?; - (follow_activity.clone().object.unwrap_or_default(), follow_activity.ap()) + (follow_activity.clone().object.unwrap_or_default(), ctx.ap(follow_activity)) }; let aid = ctx.aid(&upub::Context::new_id()); diff --git a/upub/cli/src/relay.rs b/upub/cli/src/relay.rs index 67b4849..3ced83c 100644 --- a/upub/cli/src/relay.rs +++ b/upub/cli/src/relay.rs @@ -143,7 +143,7 @@ pub async fn relay(ctx: upub::Context, action: RelayCommand) -> Result<(), Reque .set_id(Some(aid.clone())) .set_activity_type(Some(apb::ActivityType::Undo)) .set_actor(apb::Node::link(ctx.base().to_string())) - .set_object(apb::Node::object(activity.ap())) + .set_object(apb::Node::object(ctx.ap(activity))) .set_to(apb::Node::links(vec![actor.clone()])) .set_cc(apb::Node::links(vec![apb::target::PUBLIC.to_string()])) .set_published(Some(chrono::Utc::now())); @@ -179,7 +179,7 @@ pub async fn relay(ctx: upub::Context, action: RelayCommand) -> Result<(), Reque .set_id(Some(aid.clone())) .set_activity_type(Some(apb::ActivityType::Undo)) .set_actor(apb::Node::link(ctx.base().to_string())) - .set_object(apb::Node::object(activity.ap())) + .set_object(apb::Node::object(ctx.ap(activity))) .set_to(apb::Node::links(vec![actor.clone()])) .set_cc(apb::Node::links(vec![apb::target::PUBLIC.to_string()])) .set_published(Some(chrono::Utc::now())); diff --git a/upub/core/src/context.rs b/upub/core/src/context.rs index 1e76f5a..db5214b 100644 --- a/upub/core/src/context.rs +++ b/upub/core/src/context.rs @@ -114,6 +114,10 @@ impl Context { &self.0.base_url } + pub fn ap(&self, x: T) -> serde_json::Value { + x.into_activity_pub_json(self) + } + pub fn new_id() -> String { uuid::Uuid::new_v4().to_string() } diff --git a/upub/core/src/ext.rs b/upub/core/src/ext.rs index f7e856e..ac9ed26 100644 --- a/upub/core/src/ext.rs +++ b/upub/core/src/ext.rs @@ -1,5 +1,9 @@ use sea_orm::{ConnectionTrait, PaginatorTrait}; +pub trait IntoActivityPub { + fn into_activity_pub_json(self, ctx: &crate::Context) -> serde_json::Value; +} + #[allow(async_fn_in_trait)] pub trait AnyQuery { async fn any(self, db: &impl ConnectionTrait) -> Result; diff --git a/upub/core/src/model/activity.rs b/upub/core/src/model/activity.rs index db51b34..ae5a330 100644 --- a/upub/core/src/model/activity.rs +++ b/upub/core/src/model/activity.rs @@ -87,8 +87,8 @@ impl Entity { } } -impl Model { - pub fn ap(self) -> serde_json::Value { +impl crate::ext::IntoActivityPub for Model { + fn into_activity_pub_json(self, _ctx: &crate::Context) -> serde_json::Value { apb::new() .set_id(Some(self.id)) .set_activity_type(Some(self.activity_type)) diff --git a/upub/core/src/model/actor.rs b/upub/core/src/model/actor.rs index 8ec5cf3..76a4a07 100644 --- a/upub/core/src/model/actor.rs +++ b/upub/core/src/model/actor.rs @@ -200,8 +200,8 @@ impl Entity { } } -impl Model { - pub fn ap(self) -> serde_json::Value { +impl crate::ext::IntoActivityPub for Model { + fn into_activity_pub_json(self, _ctx: &crate::Context) -> serde_json::Value { apb::new() .set_id(Some(self.id.clone())) .set_actor_type(Some(self.actor_type)) diff --git a/upub/core/src/model/attachment.rs b/upub/core/src/model/attachment.rs index 12082bf..37bd7ee 100644 --- a/upub/core/src/model/attachment.rs +++ b/upub/core/src/model/attachment.rs @@ -34,8 +34,8 @@ impl Related for Entity { impl ActiveModelBehavior for ActiveModel {} -impl Model { - pub fn ap(self) -> serde_json::Value { +impl crate::ext::IntoActivityPub for Model { + fn into_activity_pub_json(self, _ctx: &crate::Context) -> serde_json::Value { apb::new() .set_url(apb::Node::link(self.url)) .set_document_type(Some(self.document_type)) diff --git a/upub/core/src/model/object.rs b/upub/core/src/model/object.rs index d776735..3e2dc5a 100644 --- a/upub/core/src/model/object.rs +++ b/upub/core/src/model/object.rs @@ -160,8 +160,8 @@ impl Entity { } } -impl Model { - pub fn ap(self) -> serde_json::Value { +impl crate::ext::IntoActivityPub for Model { + fn into_activity_pub_json(self, _ctx: &crate::Context) -> serde_json::Value { apb::new() .set_id(Some(self.id)) .set_object_type(Some(self.object_type)) diff --git a/upub/core/src/selector/rich.rs b/upub/core/src/selector/rich.rs index 62b61d7..7661db4 100644 --- a/upub/core/src/selector/rich.rs +++ b/upub/core/src/selector/rich.rs @@ -1,14 +1,16 @@ use apb::ActivityMut; use sea_orm::{DbErr, EntityName, FromQueryResult, Iden, QueryResult}; +use crate::ext::IntoActivityPub; + pub struct RichMention { pub mention: crate::model::mention::Model, pub id: String, pub fqn: String, } -impl RichMention { - pub fn ap(self) -> serde_json::Value { +impl IntoActivityPub for RichMention { + fn into_activity_pub_json(self, _ctx: &crate::Context) -> serde_json::Value { use apb::LinkMut; apb::new() .set_link_type(Some(apb::LinkType::Mention)) @@ -21,8 +23,8 @@ pub struct RichHashtag { pub hash: crate::model::hashtag::Model, } -impl RichHashtag { - pub fn ap(self) -> serde_json::Value { +impl IntoActivityPub for RichHashtag { + fn into_activity_pub_json(self, _ctx: &crate::Context) -> serde_json::Value { use apb::LinkMut; apb::new() .set_name(Some(format!("#{}", self.hash.name))) @@ -55,32 +57,32 @@ impl FromQueryResult for RichActivity { } } -impl RichActivity { - pub fn ap(self) -> serde_json::Value { +impl IntoActivityPub for RichActivity { + fn into_activity_pub_json(self, ctx: &crate::Context) -> serde_json::Value { use apb::ObjectMut; match (self.activity, self.object) { (None, None) => serde_json::Value::Null, (Some(activity), None) => { let obj = apb::Node::maybe_link(activity.object.clone()); - activity.ap().set_object(obj) + activity.into_activity_pub_json(ctx).set_object(obj) }, (maybe_activity, Some(object)) => { let mut tags = Vec::new(); if let Some(mentions) = self.mentions { for mention in mentions { - tags.push(mention.ap()); + tags.push(mention.into_activity_pub_json(ctx)); } } if let Some(hashtags) = self.hashtags { for hash in hashtags { - tags.push(hash.ap()); + tags.push(hash.into_activity_pub_json(ctx)); } } let activity = match maybe_activity { - Some(activity) => activity.ap(), + Some(activity) => activity.into_activity_pub_json(ctx), None => apb::new() .set_activity_type(Some(apb::ActivityType::View)) .set_published(Some(self.discovered)) @@ -88,13 +90,13 @@ impl RichActivity { activity .set_object(apb::Node::object( - object.ap() + object.into_activity_pub_json(ctx) .set_liked_by_me(if self.liked.is_some() { Some(true) } else { None }) .set_tag(apb::Node::maybe_array(tags)) .set_attachment(match self.attachments { None => apb::Node::Empty, Some(vec) => apb::Node::array( - vec.into_iter().map(|x| x.ap()).collect() + vec.into_iter().map(|x| x.into_activity_pub_json(ctx)).collect() ), }) )) @@ -102,35 +104,35 @@ impl RichActivity { } } - // TODO ughhh cant make it a trait because there's this different one!!! - pub fn object_ap(self) -> serde_json::Value { - use apb::ObjectMut; - match self.object { - Some(object) => { - let mut tags = Vec::new(); - if let Some(mentions) = self.mentions { - for mention in mentions { - tags.push(mention.ap()); - } - } - if let Some(hashtags) = self.hashtags { - for hash in hashtags { - tags.push(hash.ap()); - } - } - object.ap() - .set_liked_by_me(if self.liked.is_some() { Some(true) } else { None }) - .set_tag(apb::Node::maybe_array(tags)) - .set_attachment(match self.attachments { - None => apb::Node::Empty, - Some(vec) => apb::Node::array( - vec.into_iter().map(|x| x.ap()).collect() - ), - }) - }, - None => serde_json::Value::Null, - } - } + // // TODO ughhh cant make it a trait because there's this different one!!! + // pub fn object_ap(self) -> serde_json::Value { + // use apb::ObjectMut; + // match self.object { + // Some(object) => { + // let mut tags = Vec::new(); + // if let Some(mentions) = self.mentions { + // for mention in mentions { + // tags.push(mention.ap()); + // } + // } + // if let Some(hashtags) = self.hashtags { + // for hash in hashtags { + // tags.push(hash.ap()); + // } + // } + // object.ap() + // .set_liked_by_me(if self.liked.is_some() { Some(true) } else { None }) + // .set_tag(apb::Node::maybe_array(tags)) + // .set_attachment(match self.attachments { + // None => apb::Node::Empty, + // Some(vec) => apb::Node::array( + // vec.into_iter().map(|x| x.ap()).collect() + // ), + // }) + // }, + // None => serde_json::Value::Null, + // } + // } } pub struct RichNotification { @@ -150,10 +152,10 @@ impl FromQueryResult for RichNotification { } } -impl RichNotification { - pub fn ap(self) -> serde_json::Value { +impl IntoActivityPub for RichNotification { + fn into_activity_pub_json(self, ctx: &crate::Context) -> serde_json::Value { let seen = self.seen; - self.activity.ap() + self.activity.into_activity_pub_json(ctx) .set_seen(Some(seen)) } } diff --git a/upub/routes/src/activitypub/activity.rs b/upub/routes/src/activitypub/activity.rs index a428e1e..7f371c0 100644 --- a/upub/routes/src/activitypub/activity.rs +++ b/upub/routes/src/activitypub/activity.rs @@ -37,6 +37,6 @@ pub async fn view( .with_batched::(ctx.db()) .await?; - Ok(JsonLD(row.ap().ld_context())) + Ok(JsonLD(ctx.ap(row).ld_context())) } diff --git a/upub/routes/src/activitypub/actor/inbox.rs b/upub/routes/src/activitypub/actor/inbox.rs index ec5f707..5f70961 100644 --- a/upub/routes/src/activitypub/actor/inbox.rs +++ b/upub/routes/src/activitypub/actor/inbox.rs @@ -41,7 +41,7 @@ pub async fn page( .add(upub::model::addressing::Column::Actor.eq(*internal)) .add(upub::model::activity::Column::Actor.eq(uid)) .add(upub::model::object::Column::AttributedTo.eq(uid)), - ctx.db(), + &ctx, page, auth.my_id(), false, diff --git a/upub/routes/src/activitypub/actor/mod.rs b/upub/routes/src/activitypub/actor/mod.rs index 1be689b..a71c46b 100644 --- a/upub/routes/src/activitypub/actor/mod.rs +++ b/upub/routes/src/activitypub/actor/mod.rs @@ -55,7 +55,7 @@ pub async fn view( { // local user Some((user_model, Some(cfg))) => { - let mut user = user_model.ap() + let mut user = ctx.ap(user_model) .set_inbox(Node::link(upub::url!(ctx, "/actors/{id}/inbox"))) .set_outbox(Node::link(upub::url!(ctx, "/actors/{id}/outbox"))) .set_following(Node::link(upub::url!(ctx, "/actors/{id}/following"))) @@ -89,7 +89,7 @@ pub async fn view( }, // remote user Some((user_model, None)) => Ok(JsonLD( - user_model.ap() + ctx.ap(user_model) .set_following_me(following_me) .set_followed_by_me(followed_by_me) .ld_context() diff --git a/upub/routes/src/activitypub/actor/notifications.rs b/upub/routes/src/activitypub/actor/notifications.rs index 5a5e8bd..4a52c0e 100644 --- a/upub/routes/src/activitypub/actor/notifications.rs +++ b/upub/routes/src/activitypub/actor/notifications.rs @@ -49,7 +49,7 @@ pub async fn page( .all(ctx.db()) .await? .into_iter() - .map(|x| x.ap()) + .map(|x| ctx.ap(x)) .collect(); crate::builders::collection_page(&upub::url!(ctx, "/actors/{id}/notifications/page"), offset, limit, activities) diff --git a/upub/routes/src/activitypub/actor/outbox.rs b/upub/routes/src/activitypub/actor/outbox.rs index 959789e..f7e4c51 100644 --- a/upub/routes/src/activitypub/actor/outbox.rs +++ b/upub/routes/src/activitypub/actor/outbox.rs @@ -31,7 +31,7 @@ pub async fn page( crate::builders::paginate_feed( upub::url!(ctx, "/actors/{id}/outbox/page"), filter, - ctx.db(), + &ctx, page, auth.my_id(), false, diff --git a/upub/routes/src/activitypub/application.rs b/upub/routes/src/activitypub/application.rs index c7a01e1..76e0f59 100644 --- a/upub/routes/src/activitypub/application.rs +++ b/upub/routes/src/activitypub/application.rs @@ -66,7 +66,7 @@ pub async fn search( crate::builders::paginate_feed( upub::url!(ctx, "/search"), filter, - ctx.db(), + &ctx, page, auth.my_id(), false, diff --git a/upub/routes/src/activitypub/inbox.rs b/upub/routes/src/activitypub/inbox.rs index 27280b9..24a4c28 100644 --- a/upub/routes/src/activitypub/inbox.rs +++ b/upub/routes/src/activitypub/inbox.rs @@ -22,7 +22,7 @@ pub async fn page( crate::builders::paginate_feed( upub::url!(ctx, "/inbox/page"), upub::model::addressing::Column::Actor.is_null().into_condition(), - ctx.db(), + &ctx, page, auth.my_id(), false, diff --git a/upub/routes/src/activitypub/object/context.rs b/upub/routes/src/activitypub/object/context.rs index c9464d9..de4a875 100644 --- a/upub/routes/src/activitypub/object/context.rs +++ b/upub/routes/src/activitypub/object/context.rs @@ -49,7 +49,7 @@ pub async fn page( let items : Vec = items .into_iter() - .map(|item| item.ap()) + .map(|item| ctx.ap(item)) .collect(); crate::builders::collection_page(&upub::url!(ctx, "/objects/{id}/context/page"), offset, limit, items) diff --git a/upub/routes/src/activitypub/outbox.rs b/upub/routes/src/activitypub/outbox.rs index 1b4e1e2..cb7213f 100644 --- a/upub/routes/src/activitypub/outbox.rs +++ b/upub/routes/src/activitypub/outbox.rs @@ -18,7 +18,7 @@ pub async fn page( Condition::all() .add(upub::model::addressing::Column::Actor.is_null()) .add(upub::model::actor::Column::Domain.eq(ctx.domain().to_string())), - ctx.db(), + &ctx, page, auth.my_id(), true, diff --git a/upub/routes/src/activitypub/tags.rs b/upub/routes/src/activitypub/tags.rs index 5fd2228..7974dde 100644 --- a/upub/routes/src/activitypub/tags.rs +++ b/upub/routes/src/activitypub/tags.rs @@ -39,7 +39,7 @@ pub async fn page( .with_batched::(ctx.db()) .await? .into_iter() - .map(|x| x.ap()) + .map(|x| ctx.ap(x)) .collect(); crate::builders::collection_page( diff --git a/upub/routes/src/builders.rs b/upub/routes/src/builders.rs index 8c9a756..022f8d0 100644 --- a/upub/routes/src/builders.rs +++ b/upub/routes/src/builders.rs @@ -1,5 +1,5 @@ use apb::{BaseMut, CollectionMut, CollectionPageMut, LD}; -use sea_orm::{Condition, ConnectionTrait, QueryFilter, QuerySelect, RelationTrait, ColumnTrait}; +use sea_orm::{Condition, QueryFilter, QuerySelect, RelationTrait, ColumnTrait}; use axum::response::{IntoResponse, Response}; use upub::selector::{BatchFillable, RichActivity}; @@ -9,7 +9,7 @@ use crate::activitypub::Pagination; pub async fn paginate_feed( id: String, filter: Condition, - db: &impl ConnectionTrait, + ctx: &upub::Context, page: Pagination, my_id: Option, with_users: bool, // TODO ewww too many arguments for this weird function... @@ -32,6 +32,7 @@ pub async fn paginate_feed( .join(sea_orm::JoinType::InnerJoin, upub::model::activity::Relation::Actors.def()); } + let db = ctx.db(); let items = select .filter(conditions) // TODO also limit to only local activities @@ -49,7 +50,7 @@ pub async fn paginate_feed( let items : Vec = items .into_iter() - .map(|item| item.ap()) + .map(|item| ctx.ap(item)) .collect(); collection_page(&id, offset, limit, items) diff --git a/upub/worker/src/delivery.rs b/upub/worker/src/delivery.rs index a636177..3fa4b4e 100644 --- a/upub/worker/src/delivery.rs +++ b/upub/worker/src/delivery.rs @@ -21,17 +21,17 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult< model::object::Entity::find_by_ap_id(oid) .one(ctx.db()) .await? - .map(|x| x.ap()), + .map(|x| ctx.ap(x)), apb::ActivityType::Accept(_) | apb::ActivityType::Reject(_) | apb::ActivityType::Undo => model::activity::Entity::find_by_ap_id(oid) .one(ctx.db()) .await? - .map(|x| x.ap()), + .map(|x| ctx.ap(x)), apb::ActivityType::Update => { if let Some(o) = model::object::Entity::find_by_ap_id(oid).one(ctx.db()).await? { - Some(o.ap()) + Some(ctx.ap(o)) } else if let Some(a) = model::actor::Entity::find_by_ap_id(oid).one(ctx.db()).await? { - Some(a.ap()) + Some(ctx.ap(a)) } else { None } @@ -40,7 +40,7 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult< } } else { None }; - let mut payload = activity.ap(); + let mut payload = ctx.ap(activity); if let Some(object) = object { payload = payload.set_object(apb::Node::object(object)); } diff --git a/upub/worker/src/outbound.rs b/upub/worker/src/outbound.rs index 295aaad..470b62f 100644 --- a/upub/worker/src/outbound.rs +++ b/upub/worker/src/outbound.rs @@ -101,7 +101,7 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult< .into(); } - updated = prev.ap(); + updated = ctx.ap(prev); }, apb::ObjectType::Note => { let mut prev = model::object::Entity::find_by_ap_id(&updated.id()?) @@ -122,7 +122,7 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult< prev.sensitive = sensitive; } - updated = prev.ap(); + updated = ctx.ap(prev); }, t => return Err(crate::JobError::ProcessorError(ProcessorError::Unprocessable(format!("{t}")))), }