diff --git a/upub/cli/src/fetch.rs b/upub/cli/src/fetch.rs
index 3c63623..8be3b60 100644
--- a/upub/cli/src/fetch.rs
+++ b/upub/cli/src/fetch.rs
@@ -25,7 +25,7 @@ pub async fn fetch(ctx: upub::Context, uri: String, save: bool, actor: Option()
.await?
diff --git a/upub/cli/src/nuke.rs b/upub/cli/src/nuke.rs
index b01ff13..15108ea 100644
--- a/upub/cli/src/nuke.rs
+++ b/upub/cli/src/nuke.rs
@@ -63,7 +63,7 @@ pub async fn nuke(ctx: upub::Context, for_real: bool, delete_posts: bool) -> Res
let aid = ctx.aid(&upub::Context::new_id());
let undo_activity = apb::new()
- .set_id(Some(&aid))
+ .set_id(Some(aid.clone()))
.set_activity_type(Some(apb::ActivityType::Undo))
.set_actor(apb::Node::link(activity.actor.clone()))
.set_object(apb::Node::object(undone))
@@ -73,7 +73,7 @@ pub async fn nuke(ctx: upub::Context, for_real: bool, delete_posts: bool) -> Res
let job = upub::model::job::ActiveModel {
internal: NotSet,
- activity: Set(aid.clone()),
+ activity: Set(aid),
job_type: Set(upub::model::job::JobType::Outbound),
actor: Set(activity.actor),
target: Set(None),
@@ -101,7 +101,7 @@ pub async fn nuke(ctx: upub::Context, for_real: bool, delete_posts: bool) -> Res
let aid = ctx.aid(&upub::Context::new_id());
let actor = object.attributed_to.unwrap_or_else(|| ctx.domain().to_string());
let undo_activity = apb::new()
- .set_id(Some(&aid))
+ .set_id(Some(aid.clone()))
.set_activity_type(Some(apb::ActivityType::Delete))
.set_actor(apb::Node::link(actor.clone()))
.set_object(apb::Node::link(object.id.clone()))
@@ -114,7 +114,7 @@ pub async fn nuke(ctx: upub::Context, for_real: bool, delete_posts: bool) -> Res
let job = upub::model::job::ActiveModel {
internal: NotSet,
- activity: Set(aid.clone()),
+ activity: Set(aid),
job_type: Set(upub::model::job::JobType::Outbound),
actor: Set(actor),
target: Set(None),
diff --git a/upub/cli/src/relay.rs b/upub/cli/src/relay.rs
index 40bfc62..67b4849 100644
--- a/upub/cli/src/relay.rs
+++ b/upub/cli/src/relay.rs
@@ -67,7 +67,7 @@ pub async fn relay(ctx: upub::Context, action: RelayCommand) -> Result<(), Reque
RelayCommand::Follow { actor } => {
let aid = ctx.aid(&upub::Context::new_id());
let payload = apb::new()
- .set_id(Some(&aid))
+ .set_id(Some(aid.clone()))
.set_activity_type(Some(apb::ActivityType::Follow))
.set_actor(apb::Node::link(ctx.base().to_string()))
.set_object(apb::Node::link(actor.clone()))
@@ -76,7 +76,7 @@ pub async fn relay(ctx: upub::Context, action: RelayCommand) -> Result<(), Reque
.set_published(Some(chrono::Utc::now()));
let job = upub::model::job::ActiveModel {
internal: NotSet,
- activity: Set(aid.clone()),
+ activity: Set(aid),
job_type: Set(upub::model::job::JobType::Outbound),
actor: Set(ctx.base().to_string()),
target: Set(None),
@@ -103,7 +103,7 @@ pub async fn relay(ctx: upub::Context, action: RelayCommand) -> Result<(), Reque
.ok_or_else(|| DbErr::RecordNotFound(format!("activity#{}", relation.activity)))?;
let aid = ctx.aid(&upub::Context::new_id());
let payload = apb::new()
- .set_id(Some(&aid))
+ .set_id(Some(aid.clone()))
.set_activity_type(Some(apb::ActivityType::Accept(apb::AcceptType::Accept)))
.set_actor(apb::Node::link(ctx.base().to_string()))
.set_object(apb::Node::link(activity.id))
@@ -112,7 +112,7 @@ pub async fn relay(ctx: upub::Context, action: RelayCommand) -> Result<(), Reque
.set_published(Some(chrono::Utc::now()));
let job = upub::model::job::ActiveModel {
internal: NotSet,
- activity: Set(aid.clone()),
+ activity: Set(aid),
job_type: Set(upub::model::job::JobType::Outbound),
actor: Set(ctx.base().to_string()),
target: Set(None),
@@ -140,7 +140,7 @@ pub async fn relay(ctx: upub::Context, action: RelayCommand) -> Result<(), Reque
.ok_or_else(|| DbErr::RecordNotFound(format!("activity#{}", accept_activity_id)))?;
let aid = ctx.aid(&upub::Context::new_id());
let payload = apb::new()
- .set_id(Some(&aid))
+ .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()))
@@ -149,7 +149,7 @@ pub async fn relay(ctx: upub::Context, action: RelayCommand) -> Result<(), Reque
.set_published(Some(chrono::Utc::now()));
let job = upub::model::job::ActiveModel {
internal: NotSet,
- activity: Set(aid.clone()),
+ activity: Set(aid),
job_type: Set(upub::model::job::JobType::Outbound),
actor: Set(ctx.base().to_string()),
target: Set(None),
@@ -176,7 +176,7 @@ pub async fn relay(ctx: upub::Context, action: RelayCommand) -> Result<(), Reque
.ok_or_else(|| DbErr::RecordNotFound(format!("activity#{}", relation.activity)))?;
let aid = ctx.aid(&upub::Context::new_id());
let payload = apb::new()
- .set_id(Some(&aid))
+ .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()))
@@ -185,7 +185,7 @@ pub async fn relay(ctx: upub::Context, action: RelayCommand) -> Result<(), Reque
.set_published(Some(chrono::Utc::now()));
let job = upub::model::job::ActiveModel {
internal: NotSet,
- activity: Set(aid.clone()),
+ activity: Set(aid),
job_type: Set(upub::model::job::JobType::Outbound),
actor: Set(ctx.base().to_string()),
target: Set(None),
diff --git a/upub/core/src/model/activity.rs b/upub/core/src/model/activity.rs
index 21946e2..db51b34 100644
--- a/upub/core/src/model/activity.rs
+++ b/upub/core/src/model/activity.rs
@@ -90,7 +90,7 @@ impl Entity {
impl Model {
pub fn ap(self) -> serde_json::Value {
apb::new()
- .set_id(Some(&self.id))
+ .set_id(Some(self.id))
.set_activity_type(Some(self.activity_type))
.set_actor(apb::Node::link(self.actor))
.set_object(apb::Node::maybe_link(self.object))
diff --git a/upub/core/src/model/actor.rs b/upub/core/src/model/actor.rs
index e62a339..8ec5cf3 100644
--- a/upub/core/src/model/actor.rs
+++ b/upub/core/src/model/actor.rs
@@ -1,6 +1,6 @@
use sea_orm::{entity::prelude::*, QuerySelect, SelectColumns};
-use apb::{field::OptionalString, ActorMut, ActorType, BaseMut, DocumentMut, EndpointsMut, ObjectMut, PublicKeyMut};
+use apb::{ActorMut, ActorType, BaseMut, DocumentMut, EndpointsMut, ObjectMut, PublicKeyMut};
use crate::ext::{JsonVec, TypeName};
@@ -25,8 +25,8 @@ impl TypeName for Field {
impl From for Field {
fn from(value: T) -> Self {
Field {
- name: value.name().str().unwrap_or_default(),
- value: mdhtml::safe_html(value.value().unwrap_or_default()),
+ name: value.name().unwrap_or_default().to_string(),
+ value: mdhtml::safe_html(&value.value().unwrap_or_default()),
field_type: "PropertyValue".to_string(), // TODO can we try parsing this instead??
verified_at: None, // TODO where does verified_at come from? extend apb maybe
}
@@ -203,10 +203,10 @@ impl Entity {
impl Model {
pub fn ap(self) -> serde_json::Value {
apb::new()
- .set_id(Some(&self.id))
+ .set_id(Some(self.id.clone()))
.set_actor_type(Some(self.actor_type))
- .set_name(self.name.as_deref())
- .set_summary(self.summary.as_deref())
+ .set_name(self.name)
+ .set_summary(self.summary)
.set_icon(apb::Node::maybe_object(self.icon.map(|i|
apb::new()
.set_document_type(Some(apb::DocumentType::Image))
@@ -225,7 +225,7 @@ impl Model {
))
.set_published(Some(self.published))
.set_updated(if self.updated != self.published { Some(self.updated) } else { None })
- .set_preferred_username(Some(&self.preferred_username))
+ .set_preferred_username(Some(self.preferred_username))
.set_statuses_count(Some(self.statuses_count as u64))
.set_followers_count(Some(self.followers_count as u64))
.set_following_count(Some(self.following_count as u64))
@@ -235,13 +235,13 @@ impl Model {
.set_followers(apb::Node::maybe_link(self.followers))
.set_public_key(apb::Node::object(
apb::new()
- .set_id(Some(&format!("{}#main-key", self.id)))
- .set_owner(Some(&self.id))
- .set_public_key_pem(&self.public_key)
+ .set_id(Some(format!("{}#main-key", self.id)))
+ .set_owner(Some(self.id))
+ .set_public_key_pem(self.public_key)
))
.set_endpoints(apb::Node::object(
apb::new()
- .set_shared_inbox(self.shared_inbox.as_deref())
+ .set_shared_inbox(self.shared_inbox)
))
.set_also_known_as(apb::Node::links(self.also_known_as.0))
.set_moved_to(apb::Node::maybe_link(self.moved_to))
diff --git a/upub/core/src/model/attachment.rs b/upub/core/src/model/attachment.rs
index 97851f5..12082bf 100644
--- a/upub/core/src/model/attachment.rs
+++ b/upub/core/src/model/attachment.rs
@@ -39,7 +39,7 @@ impl Model {
apb::new()
.set_url(apb::Node::link(self.url))
.set_document_type(Some(self.document_type))
- .set_media_type(Some(&self.media_type))
- .set_name(self.name.as_deref())
+ .set_media_type(Some(self.media_type))
+ .set_name(self.name)
}
}
diff --git a/upub/core/src/model/object.rs b/upub/core/src/model/object.rs
index bf5e045..d776735 100644
--- a/upub/core/src/model/object.rs
+++ b/upub/core/src/model/object.rs
@@ -163,12 +163,12 @@ impl Entity {
impl Model {
pub fn ap(self) -> serde_json::Value {
apb::new()
- .set_id(Some(&self.id))
+ .set_id(Some(self.id))
.set_object_type(Some(self.object_type))
.set_attributed_to(apb::Node::maybe_link(self.attributed_to))
- .set_name(self.name.as_deref())
- .set_summary(self.summary.as_deref())
- .set_content(self.content.as_deref())
+ .set_name(self.name)
+ .set_summary(self.summary)
+ .set_content(self.content)
.set_image(apb::Node::maybe_object(self.image.map(|x|
apb::new()
.set_document_type(Some(apb::DocumentType::Image))
diff --git a/upub/core/src/selector/rich.rs b/upub/core/src/selector/rich.rs
index 625fb04..62b61d7 100644
--- a/upub/core/src/selector/rich.rs
+++ b/upub/core/src/selector/rich.rs
@@ -12,8 +12,8 @@ impl RichMention {
use apb::LinkMut;
apb::new()
.set_link_type(Some(apb::LinkType::Mention))
- .set_href(Some(&self.id))
- .set_name(Some(&self.fqn))
+ .set_href(Some(self.id))
+ .set_name(Some(self.fqn))
}
}
@@ -25,7 +25,7 @@ impl RichHashtag {
pub fn ap(self) -> serde_json::Value {
use apb::LinkMut;
apb::new()
- .set_name(Some(&format!("#{}", self.hash.name)))
+ .set_name(Some(format!("#{}", self.hash.name)))
.set_link_type(Some(apb::LinkType::Hashtag))
}
}
diff --git a/upub/core/src/traits/fetch.rs b/upub/core/src/traits/fetch.rs
index 5fe1085..7c822f8 100644
--- a/upub/core/src/traits/fetch.rs
+++ b/upub/core/src/traits/fetch.rs
@@ -1,14 +1,14 @@
use std::collections::BTreeMap;
-use apb::{Activity, Actor, ActorMut, Base, Collection, CollectionPage, Object};
+use apb::{Shortcuts, Activity, Actor, ActorMut, Base, Collection, CollectionPage, Object};
use reqwest::{header::{ACCEPT, CONTENT_TYPE, USER_AGENT}, Method, Response};
use sea_orm::{ActiveValue::Set, ColumnTrait, ConnectionTrait, DbErr, EntityTrait, IntoActiveModel, NotSet, QueryFilter, ActiveModelTrait};
-use crate::{ext::Shortcuts, traits::normalize::AP};
-
use super::{Addresser, Cloaker, Normalizer};
use httpsign::HttpSignature;
+use crate::AP;
+
#[derive(Debug, Clone)]
pub enum Pull {
Actor(T),
@@ -184,7 +184,7 @@ impl Fetcher for crate::Context {
if depth >= self.cfg().security.max_id_redirects {
return Err(RequestError::TooManyRedirects);
}
- return self.pull(doc_id).await;
+ return self.pull(&doc_id).await;
}
match document.object_type()? {
@@ -299,7 +299,7 @@ impl Fetcher for crate::Context {
// TODO try fetching these numbers from audience/generator fields to avoid making 2 more GETs every time
if let Ok(followers_url) = document.followers().id() {
let req = Self::request(
- Method::GET, followers_url, None,
+ Method::GET, &followers_url, None,
self.base(), self.pkey(), self.domain(),
).await;
if let Ok(res) = req {
@@ -313,7 +313,7 @@ impl Fetcher for crate::Context {
if let Ok(following_url) = document.following().id() {
let req = Self::request(
- Method::GET, following_url, None,
+ Method::GET, &following_url, None,
self.base(), self.pkey(), self.domain(),
).await;
if let Ok(res) = req {
@@ -362,7 +362,7 @@ impl Fetcher for crate::Context {
let document = self.pull(id).await?.actor()?;
if document.id()? != id {
- if let Some(x) = crate::model::actor::Entity::find_by_ap_id(document.id()?).one(tx).await? {
+ if let Some(x) = crate::model::actor::Entity::find_by_ap_id(&document.id()?).one(tx).await? {
return Ok(x); // already in db but we had to follow the "pretty" url, mehh
}
}
@@ -381,16 +381,16 @@ impl Fetcher for crate::Context {
}
async fn resolve_activity(&self, activity: serde_json::Value, tx: &impl ConnectionTrait) -> Result {
- let _domain = self.fetch_domain(&crate::Context::server(activity.id()?), tx).await?;
+ let _domain = self.fetch_domain(&crate::Context::server(&activity.id()?), tx).await?;
if let Ok(activity_actor) = activity.actor().id() {
- if let Err(e) = self.fetch_user(activity_actor, tx).await {
+ if let Err(e) = self.fetch_user(&activity_actor, tx).await {
tracing::warn!("could not get actor of fetched activity: {e}");
}
}
if let Ok(activity_object) = activity.object().id() {
- if let Err(e) = self.fetch_object(activity_object, tx).await {
+ if let Err(e) = self.fetch_object(&activity_object, tx).await {
tracing::warn!("could not get object of fetched activity: {e}");
}
}
@@ -441,13 +441,13 @@ impl Fetcher for crate::Context {
}
for obj in page.items().flat() {
- if let Err(e) = self.fetch_object(obj.id()?, tx).await {
+ if let Err(e) = self.fetch_object(&obj.id()?, tx).await {
tracing::warn!("error fetching reply: {e}");
}
}
for obj in page.ordered_items().flat() {
- if let Err(e) = self.fetch_object(obj.id()?, tx).await {
+ if let Err(e) = self.fetch_object(&obj.id()?, tx).await {
tracing::warn!("error fetching reply: {e}");
}
}
@@ -477,7 +477,7 @@ async fn fetch_object_r(ctx: &crate::Context, id: &str, depth: u32, tx: &impl Co
let object = ctx.pull(id).await?.object()?;
if object.id()? != id {
- if let Some(x) = crate::model::object::Entity::find_by_ap_id(object.id()?).one(tx).await? {
+ if let Some(x) = crate::model::object::Entity::find_by_ap_id(&object.id()?).one(tx).await? {
return Ok(x); // already in db but we had to follow the "pretty" url, mehh
}
}
@@ -490,21 +490,21 @@ async fn resolve_object_r(ctx: &crate::Context, object: serde_json::Value, depth
if let Ok(oid) = object.id() {
if oid != id {
- if let Some(x) = crate::model::object::Entity::find_by_ap_id(oid).one(tx).await? {
+ if let Some(x) = crate::model::object::Entity::find_by_ap_id(&oid).one(tx).await? {
return Ok(x); // already in db, but with id different that given url
}
}
}
if let Ok(attributed_to) = object.attributed_to().id() {
- if let Err(e) = ctx.fetch_user(attributed_to, tx).await {
+ if let Err(e) = ctx.fetch_user(&attributed_to, tx).await {
tracing::warn!("could not get actor of fetched object: {e}");
}
}
if let Ok(reply) = object.in_reply_to().id() {
if depth <= ctx.cfg().security.thread_crawl_depth {
- fetch_object_r(ctx, reply, depth + 1, tx).await?;
+ fetch_object_r(ctx, &reply, depth + 1, tx).await?;
} else {
tracing::warn!("thread deeper than {}, giving up fetching more replies", ctx.cfg().security.thread_crawl_depth);
}
@@ -527,7 +527,7 @@ impl Dereferenceable for apb::Node {
apb::Node::Link(uri) => {
let href = uri.href()?;
tracing::info!("dereferencing {href}");
- let res = crate::Context::request(Method::GET, href, None, ctx.base(), ctx.pkey(), ctx.domain())
+ let res = crate::Context::request(Method::GET, &href, None, ctx.base(), ctx.pkey(), ctx.domain())
.await?
.json::()
.await?;
diff --git a/upub/core/src/traits/normalize.rs b/upub/core/src/traits/normalize.rs
index f66c253..5637615 100644
--- a/upub/core/src/traits/normalize.rs
+++ b/upub/core/src/traits/normalize.rs
@@ -1,6 +1,5 @@
-use apb::{field::OptionalString, Document, Endpoints, Node, Object, PublicKey};
+use apb::{Document, Endpoints, Node, Object, PublicKey, Shortcuts};
use sea_orm::{sea_query::Expr, ActiveModelTrait, ActiveValue::{Unchanged, NotSet, Set}, ColumnTrait, ConnectionTrait, DbErr, EntityTrait, IntoActiveModel, QueryFilter};
-use crate::ext::Shortcuts;
use super::{Cloaker, Fetcher};
@@ -40,7 +39,7 @@ impl Normalizer for crate::Context {
// > kind of dumb. there should be a job system so this can be done in waves. or maybe there's
// > some whole other way to do this?? im thinking but misskey aaaa!! TODO
if let Ok(reply) = object.in_reply_to().id() {
- if let Some(o) = crate::model::object::Entity::find_by_ap_id(reply).one(tx).await? {
+ if let Some(o) = crate::model::object::Entity::find_by_ap_id(&reply).one(tx).await? {
object_model.context = o.context;
} else {
object_model.context = None; // TODO to be filled by some other task
@@ -104,7 +103,7 @@ impl Normalizer for crate::Context {
Node::Link(l) => {
let url = l.href().unwrap_or_default();
if url == obj_image { continue };
- let mut media_type = l.media_type().unwrap_or("link").to_string();
+ let mut media_type = l.media_type().unwrap_or("link".to_string());
let mut document_type = apb::DocumentType::Page;
if self.cfg().compat.fix_attachment_images_media_type
&& [".jpg", ".jpeg", ".png", ".webp", ".bmp"] // TODO more image types???
@@ -117,10 +116,10 @@ impl Normalizer for crate::Context {
}
crate::model::attachment::ActiveModel {
internal: sea_orm::ActiveValue::NotSet,
- url: Set(self.cloaked(url)),
+ url: Set(self.cloaked(&url)),
object: Set(object_model.internal),
document_type: Set(document_type),
- name: Set(l.name().str()),
+ name: Set(l.name().ok()),
media_type: Set(media_type),
}
},
@@ -142,7 +141,7 @@ impl Normalizer for crate::Context {
// we should try to resolve remote users mentioned, otherwise most mentions will
// be lost. also we shouldn't fail inserting the whole post if the mention fails
// resolving.
- if let Ok(user) = self.fetch_user(href, tx).await {
+ if let Ok(user) = self.fetch_user(&href, tx).await {
let model = crate::model::mention::ActiveModel {
internal: NotSet,
object: Set(object_model.internal),
@@ -156,7 +155,7 @@ impl Normalizer for crate::Context {
},
Ok(apb::LinkType::Hashtag) => {
let hashtag = l.name()
- .unwrap_or_else(|_| l.href().unwrap_or_default().split('/').last().unwrap_or_default()) // TODO maybe just fail?
+ .unwrap_or_else(|_| l.href().unwrap_or_default().split('/').last().unwrap_or_default().to_string()) // TODO maybe just fail?
.replace('#', "");
// TODO lemmy added a "fix" to make its communities kind of work with mastodon:
// basically they include the community name as hashtag. ughhhh, since we handle
@@ -238,8 +237,8 @@ impl AP {
id: activity.id()?.to_string(),
activity_type: activity.activity_type()?,
actor: activity.actor().id()?.to_string(),
- object: activity.object().id().str(),
- target: activity.target().id().str(),
+ object: activity.object().id().ok(),
+ target: activity.target().id().ok(),
published: activity.published().unwrap_or(chrono::Utc::now()),
to: activity.to().all_ids().into(),
bto: activity.bto().all_ids().into(),
@@ -268,11 +267,11 @@ impl AP {
}
Ok(crate::model::attachment::Model {
internal: 0,
- url: document.url().id().str().unwrap_or_default(),
+ url: document.url().id().unwrap_or_default(),
object: parent,
document_type: document.as_document().map_or(apb::DocumentType::Document, |x| x.document_type().unwrap_or(apb::DocumentType::Page)),
- name: document.name().str(),
- media_type: document.media_type().unwrap_or("link").to_string(),
+ name: document.name().ok(),
+ media_type: document.media_type().unwrap_or("link".to_string()),
})
}
@@ -307,21 +306,21 @@ impl AP {
internal: 0,
id: object.id()?.to_string(),
object_type: object.object_type()?,
- attributed_to: object.attributed_to().id().str(),
- name: object.name().str(),
- summary: object.summary().str(),
- content: object.content().str(),
+ attributed_to: object.attributed_to().id().ok(),
+ name: object.name().ok(),
+ summary: object.summary().ok(),
+ content: object.content().ok(),
image: object.image_url().ok(),
- context: object.context().id().str(),
- in_reply_to: object.in_reply_to().id().str(),
- quote: object.quote_url().id().str(),
+ context: object.context().id().ok(),
+ in_reply_to: object.in_reply_to().id().ok(),
+ quote: object.quote_url().id().ok(),
published: object.published().unwrap_or_else(|_| chrono::Utc::now()),
updated: object.updated().unwrap_or_else(|_| chrono::Utc::now()),
- url: object.url().id().str(),
+ url: object.url().id().ok(),
replies: object.replies_count().unwrap_or_default(),
likes: object.likes_count().unwrap_or_default(),
announces: object.shares_count().unwrap_or_default(),
- audience: object.audience().id().str(),
+ audience: object.audience().id().ok(),
to: object.to().all_ids().into(),
bto: object.bto().all_ids().into(),
cc: object.cc().all_ids().into(),
@@ -362,19 +361,19 @@ impl AP {
internal: 0,
domain,
id: ap_id,
- preferred_username: actor.preferred_username().unwrap_or(&fallback_preferred_username).to_string(),
+ preferred_username: actor.preferred_username().unwrap_or(fallback_preferred_username).to_string(),
actor_type: actor.actor_type()?,
- name: actor.name().str(),
- summary: actor.summary().str(),
+ name: actor.name().ok(),
+ summary: actor.summary().ok(),
icon: actor.icon_url().ok(),
image: actor.image_url().ok(),
- inbox: actor.inbox().id().str(),
- outbox: actor.outbox().id().str(),
+ inbox: actor.inbox().id().ok(),
+ outbox: actor.outbox().id().ok(),
shared_inbox: actor.endpoints().inner().and_then(|x| x.shared_inbox()).map(|x| x.to_string()).ok(),
- followers: actor.followers().id().str(),
- following: actor.following().id().str(),
- also_known_as: actor.also_known_as().flat().into_iter().filter_map(|x| x.id().str()).collect::>().into(),
- moved_to: actor.moved_to().id().str(),
+ followers: actor.followers().id().ok(),
+ following: actor.following().id().ok(),
+ also_known_as: actor.also_known_as().flat().into_iter().filter_map(|x| x.id().ok()).collect::>().into(),
+ moved_to: actor.moved_to().id().ok(),
published: actor.published().unwrap_or(chrono::Utc::now()),
updated: chrono::Utc::now(),
following_count: actor.following_count().unwrap_or(0) as i32,
diff --git a/upub/core/src/traits/process.rs b/upub/core/src/traits/process.rs
index cdd6964..06e641d 100644
--- a/upub/core/src/traits/process.rs
+++ b/upub/core/src/traits/process.rs
@@ -60,14 +60,14 @@ pub async fn create(ctx: &crate::Context, activity: impl apb::Activity, tx: &Dat
tracing::error!("refusing to process activity without embedded object");
return Err(ProcessorError::Unprocessable(activity.id()?.to_string()));
};
- if model::object::Entity::ap_to_internal(object_node.id()?, tx).await?.is_some() {
+ if model::object::Entity::ap_to_internal(&object_node.id()?, tx).await?.is_some() {
return Err(ProcessorError::AlreadyProcessed);
}
if object_node.attributed_to().id()? != activity.actor().id()? {
return Err(ProcessorError::Unauthorized);
}
if let Ok(reply) = object_node.in_reply_to().id() {
- if let Err(e) = ctx.fetch_object(reply, tx).await {
+ if let Err(e) = ctx.fetch_object(&reply, tx).await {
tracing::warn!("failed fetching replies for received object: {e}");
}
}
@@ -96,8 +96,8 @@ pub async fn create(ctx: &crate::Context, activity: impl apb::Activity, tx: &Dat
}
pub async fn like(ctx: &crate::Context, activity: impl apb::Activity, tx: &DatabaseTransaction) -> Result<(), ProcessorError> {
- let actor = ctx.fetch_user(activity.actor().id()?, tx).await?;
- let obj = ctx.fetch_object(activity.object().id()?, tx).await?;
+ let actor = ctx.fetch_user(&activity.actor().id()?, tx).await?;
+ let obj = ctx.fetch_object(&activity.object().id()?, tx).await?;
let likes_local_object = obj.attributed_to.as_ref().map(|x| ctx.is_local(x)).unwrap_or_default();
if crate::model::like::Entity::find_by_uid_oid(actor.internal, obj.internal)
.any(tx)
@@ -146,8 +146,8 @@ pub async fn like(ctx: &crate::Context, activity: impl apb::Activity, tx: &Datab
// TODO basically same as like, can we make one function, maybe with const generic???
pub async fn dislike(ctx: &crate::Context, activity: impl apb::Activity, tx: &DatabaseTransaction) -> Result<(), ProcessorError> {
- let actor = ctx.fetch_user(activity.actor().id()?, tx).await?;
- let obj = ctx.fetch_object(activity.object().id()?, tx).await?;
+ let actor = ctx.fetch_user(&activity.actor().id()?, tx).await?;
+ let obj = ctx.fetch_object(&activity.object().id()?, tx).await?;
if crate::model::dislike::Entity::find_by_uid_oid(actor.internal, obj.internal)
.any(tx)
.await?
@@ -186,11 +186,11 @@ pub async fn dislike(ctx: &crate::Context, activity: impl apb::Activity, tx: &Da
}
pub async fn follow(ctx: &crate::Context, activity: impl apb::Activity, tx: &DatabaseTransaction) -> Result<(), ProcessorError> {
- let source_actor = crate::model::actor::Entity::find_by_ap_id(activity.actor().id()?)
+ let source_actor = crate::model::actor::Entity::find_by_ap_id(&activity.actor().id()?)
.one(tx)
.await?
.ok_or(ProcessorError::Incomplete)?;
- let target_actor = ctx.fetch_user(activity.object().id()?, tx).await?;
+ let target_actor = ctx.fetch_user(&activity.object().id()?, tx).await?;
let activity_model = ctx.insert_activity(activity, tx).await?;
ctx.address(Some(&activity_model), None, tx).await?;
@@ -246,7 +246,7 @@ pub async fn follow(ctx: &crate::Context, activity: impl apb::Activity, tx: &Dat
pub async fn accept(ctx: &crate::Context, activity: impl apb::Activity, tx: &DatabaseTransaction) -> Result<(), ProcessorError> {
// TODO what about TentativeAccept
- let follow_activity = crate::model::activity::Entity::find_by_ap_id(activity.object().id()?)
+ let follow_activity = crate::model::activity::Entity::find_by_ap_id(&activity.object().id()?)
.one(tx)
.await?
.ok_or(ProcessorError::Incomplete)?;
@@ -305,7 +305,7 @@ pub async fn accept(ctx: &crate::Context, activity: impl apb::Activity, tx: &Dat
pub async fn reject(ctx: &crate::Context, activity: impl apb::Activity, tx: &DatabaseTransaction) -> Result<(), ProcessorError> {
// TODO what about TentativeReject?
- let follow_activity = crate::model::activity::Entity::find_by_ap_id(activity.object().id()?)
+ let follow_activity = crate::model::activity::Entity::find_by_ap_id(&activity.object().id()?)
.one(tx)
.await?
.ok_or(ProcessorError::Incomplete)?;
@@ -429,7 +429,7 @@ pub async fn undo(ctx: &crate::Context, activity: impl apb::Activity, tx: &Datab
match undone_activity.as_activity()?.activity_type()? {
apb::ActivityType::Like => {
let internal_oid = crate::model::object::Entity::ap_to_internal(
- undone_activity.as_activity()?.object().id()?,
+ &undone_activity.as_activity()?.object().id()?,
tx
)
.await?
@@ -450,7 +450,7 @@ pub async fn undo(ctx: &crate::Context, activity: impl apb::Activity, tx: &Datab
},
apb::ActivityType::Follow => {
let internal_uid_following = crate::model::actor::Entity::ap_to_internal(
- undone_activity.as_activity()?.object().id()?,
+ &undone_activity.as_activity()?.object().id()?,
tx,
)
.await?
@@ -494,7 +494,7 @@ pub async fn undo(ctx: &crate::Context, activity: impl apb::Activity, tx: &Datab
ctx.address(Some(&activity_model), None, tx).await?;
}
- if let Some(internal) = crate::model::activity::Entity::ap_to_internal(undone_activity.id()?, tx).await? {
+ if let Some(internal) = crate::model::activity::Entity::ap_to_internal(&undone_activity.id()?, tx).await? {
crate::model::notification::Entity::delete_many()
.filter(crate::model::notification::Column::Activity.eq(internal))
.exec(tx)
@@ -532,7 +532,7 @@ pub async fn announce(ctx: &crate::Context, activity: impl apb::Activity, tx: &D
}
};
- let actor = ctx.fetch_user(activity.actor().id()?, tx).await?;
+ let actor = ctx.fetch_user(&activity.actor().id()?, tx).await?;
// we only care about announces produced by "Person" actors, because there's intention
// anything shared by groups, services or applications is automated: fetch it and be done
diff --git a/upub/routes/src/activitypub/actor/following.rs b/upub/routes/src/activitypub/actor/following.rs
index 3f1deea..794f330 100644
--- a/upub/routes/src/activitypub/actor/following.rs
+++ b/upub/routes/src/activitypub/actor/following.rs
@@ -47,7 +47,7 @@ pub async fn get(
};
- crate::builders::collection(&upub::url!(ctx, "/actors/{id}/{follow___}"), Some(count as u64))
+ crate::builders::collection(upub::url!(ctx, "/actors/{id}/{follow___}"), Some(count as u64))
}
pub async fn page(
diff --git a/upub/routes/src/activitypub/actor/inbox.rs b/upub/routes/src/activitypub/actor/inbox.rs
index 620b4ce..ec5f707 100644
--- a/upub/routes/src/activitypub/actor/inbox.rs
+++ b/upub/routes/src/activitypub/actor/inbox.rs
@@ -14,7 +14,7 @@ pub async fn get(
Identity::Anonymous => Err(crate::ApiError::forbidden()),
Identity::Remote { .. } => Err(crate::ApiError::forbidden()),
Identity::Local { id: user, .. } => if ctx.uid(&id) == user {
- crate::builders::collection(&upub::url!(ctx, "/actors/{id}/inbox"), None)
+ crate::builders::collection(upub::url!(ctx, "/actors/{id}/inbox"), None)
} else {
Err(crate::ApiError::forbidden())
},
diff --git a/upub/routes/src/activitypub/actor/mod.rs b/upub/routes/src/activitypub/actor/mod.rs
index 4b76771..1be689b 100644
--- a/upub/routes/src/activitypub/actor/mod.rs
+++ b/upub/routes/src/activitypub/actor/mod.rs
@@ -65,8 +65,8 @@ pub async fn view(
.set_manually_approves_followers(Some(!cfg.accept_follow_requests))
.set_endpoints(Node::object(
apb::new()
- .set_shared_inbox(Some(&upub::url!(ctx, "/inbox")))
- .set_proxy_url(Some(&upub::url!(ctx, "/fetch")))
+ .set_shared_inbox(Some(upub::url!(ctx, "/inbox")))
+ .set_proxy_url(Some(upub::url!(ctx, "/fetch")))
));
if auth.is(&uid) {
diff --git a/upub/routes/src/activitypub/actor/notifications.rs b/upub/routes/src/activitypub/actor/notifications.rs
index 8d0d215..5a5e8bd 100644
--- a/upub/routes/src/activitypub/actor/notifications.rs
+++ b/upub/routes/src/activitypub/actor/notifications.rs
@@ -22,7 +22,7 @@ pub async fn get(
.count(ctx.db())
.await?;
- crate::builders::collection(&upub::url!(ctx, "/actors/{id}/notifications"), Some(count))
+ crate::builders::collection(upub::url!(ctx, "/actors/{id}/notifications"), Some(count))
}
pub async fn page(
diff --git a/upub/routes/src/activitypub/actor/outbox.rs b/upub/routes/src/activitypub/actor/outbox.rs
index 7a0cfac..5e7f1bf 100644
--- a/upub/routes/src/activitypub/actor/outbox.rs
+++ b/upub/routes/src/activitypub/actor/outbox.rs
@@ -9,7 +9,7 @@ pub async fn get(
State(ctx): State,
Path(id): Path,
) -> crate::ApiResult> {
- crate::builders::collection(&upub::url!(ctx, "/actors/{id}/outbox"), None)
+ crate::builders::collection(upub::url!(ctx, "/actors/{id}/outbox"), None)
}
pub async fn page(
diff --git a/upub/routes/src/activitypub/application.rs b/upub/routes/src/activitypub/application.rs
index 9d5eb99..219220e 100644
--- a/upub/routes/src/activitypub/application.rs
+++ b/upub/routes/src/activitypub/application.rs
@@ -22,21 +22,21 @@ pub async fn view(
}
Ok(JsonLD(
apb::new()
- .set_id(Some(&upub::url!(ctx, "")))
+ .set_id(Some(upub::url!(ctx, "")))
.set_actor_type(Some(apb::ActorType::Application))
- .set_name(Some(&ctx.cfg().instance.name))
- .set_summary(Some(&ctx.cfg().instance.description))
+ .set_name(Some(ctx.cfg().instance.name.clone()))
+ .set_summary(Some(ctx.cfg().instance.description.clone()))
.set_inbox(apb::Node::link(upub::url!(ctx, "/inbox")))
.set_outbox(apb::Node::link(upub::url!(ctx, "/outbox")))
.set_published(Some(ctx.actor().published))
.set_endpoints(apb::Node::Empty)
- .set_preferred_username(Some(ctx.domain()))
+ .set_preferred_username(Some(ctx.domain().to_string()))
.set_url(apb::Node::link(upub::url!(ctx, "/")))
.set_public_key(apb::Node::object(
apb::new()
- .set_id(Some(&upub::url!(ctx, "#main-key")))
- .set_owner(Some(&upub::url!(ctx, "")))
- .set_public_key_pem(&ctx.actor().public_key)
+ .set_id(Some(upub::url!(ctx, "#main-key")))
+ .set_owner(Some(upub::url!(ctx, "")))
+ .set_public_key_pem(ctx.actor().public_key.clone())
))
.ld_context()
).into_response())
diff --git a/upub/routes/src/activitypub/inbox.rs b/upub/routes/src/activitypub/inbox.rs
index 5db3b63..27280b9 100644
--- a/upub/routes/src/activitypub/inbox.rs
+++ b/upub/routes/src/activitypub/inbox.rs
@@ -11,7 +11,7 @@ use super::Pagination;
pub async fn get(
State(ctx): State,
) -> crate::ApiResult> {
- crate::builders::collection(&upub::url!(ctx, "/inbox"), None)
+ crate::builders::collection(upub::url!(ctx, "/inbox"), None)
}
pub async fn page(
diff --git a/upub/routes/src/activitypub/object/context.rs b/upub/routes/src/activitypub/object/context.rs
index 3cc1751..377f70f 100644
--- a/upub/routes/src/activitypub/object/context.rs
+++ b/upub/routes/src/activitypub/object/context.rs
@@ -17,7 +17,7 @@ pub async fn get(
.count(ctx.db())
.await?;
- crate::builders::collection(&upub::url!(ctx, "/objects/{id}/context"), Some(count))
+ crate::builders::collection(upub::url!(ctx, "/objects/{id}/context"), Some(count))
}
pub async fn page(
diff --git a/upub/routes/src/activitypub/object/mod.rs b/upub/routes/src/activitypub/object/mod.rs
index de4613d..5b046c8 100644
--- a/upub/routes/src/activitypub/object/mod.rs
+++ b/upub/routes/src/activitypub/object/mod.rs
@@ -55,7 +55,7 @@ pub async fn view(
replies = apb::Node::object(
apb::new()
- .set_id(Some(&upub::url!(ctx, "/objects/{id}/replies")))
+ .set_id(Some(upub::url!(ctx, "/objects/{id}/replies")))
.set_first(apb::Node::link(upub::url!(ctx, "/objects/{id}/replies/page")))
.set_collection_type(Some(apb::CollectionType::Collection))
.set_total_items(item.object.as_ref().map(|x| x.replies as u64))
diff --git a/upub/routes/src/activitypub/object/replies.rs b/upub/routes/src/activitypub/object/replies.rs
index 425df01..caaa968 100644
--- a/upub/routes/src/activitypub/object/replies.rs
+++ b/upub/routes/src/activitypub/object/replies.rs
@@ -32,7 +32,7 @@ pub async fn get(
Ok(JsonLD(
apb::new()
- .set_id(Some(&upub::url!(ctx, "/objects/{id}/replies")))
+ .set_id(Some(upub::url!(ctx, "/objects/{id}/replies")))
.set_collection_type(Some(apb::CollectionType::Collection))
.set_first(apb::Node::link(upub::url!(ctx, "/objects/{id}/replies/page")))
.set_total_items(Some(replies_ids.len() as u64))
diff --git a/upub/routes/src/activitypub/outbox.rs b/upub/routes/src/activitypub/outbox.rs
index edec93f..1b4e1e2 100644
--- a/upub/routes/src/activitypub/outbox.rs
+++ b/upub/routes/src/activitypub/outbox.rs
@@ -5,7 +5,7 @@ use upub::Context;
use crate::{activitypub::{CreationResult, Pagination}, AuthIdentity, builders::JsonLD};
pub async fn get(State(ctx): State) -> crate::ApiResult> {
- crate::builders::collection(&upub::url!(ctx, "/outbox"), None)
+ crate::builders::collection(upub::url!(ctx, "/outbox"), None)
}
pub async fn page(
diff --git a/upub/routes/src/activitypub/tags.rs b/upub/routes/src/activitypub/tags.rs
index 415bf04..52f7925 100644
--- a/upub/routes/src/activitypub/tags.rs
+++ b/upub/routes/src/activitypub/tags.rs
@@ -10,7 +10,7 @@ pub async fn get(
Path(id): Path,
) -> crate::ApiResult> {
crate::builders::collection(
- &upub::url!(ctx, "/tags/{id}"),
+ upub::url!(ctx, "/tags/{id}"),
None,
)
}
diff --git a/upub/routes/src/builders.rs b/upub/routes/src/builders.rs
index 51be453..8c9a756 100644
--- a/upub/routes/src/builders.rs
+++ b/upub/routes/src/builders.rs
@@ -63,7 +63,7 @@ pub fn collection_page(id: &str, offset: u64, limit: u64, items: Vec) -> crate::ApiResult> {
+pub fn collection(id: String, total_items: Option) -> crate::ApiResult> {
Ok(JsonLD(
apb::new()
- .set_id(Some(id))
.set_collection_type(Some(apb::CollectionType::OrderedCollection))
.set_first(apb::Node::link(format!("{id}/page")))
.set_total_items(total_items)
+ .set_id(Some(id))
.ld_context()
))
}
diff --git a/upub/worker/src/outbound.rs b/upub/worker/src/outbound.rs
index ef4b76a..295aaad 100644
--- a/upub/worker/src/outbound.rs
+++ b/upub/worker/src/outbound.rs
@@ -1,4 +1,4 @@
-use apb::{field::OptionalString, target::Addressed, Activity, ActivityMut, Base, BaseMut, Object, ObjectMut};
+use apb::{target::Addressed, Activity, ActivityMut, Base, BaseMut, Object, ObjectMut, Shortcuts};
use sea_orm::{prelude::Expr, ColumnTrait, DbErr, EntityTrait, QueryFilter, QueryOrder, QuerySelect, SelectColumns, TransactionTrait};
use upub::{model::{self, actor::Field}, traits::{process::ProcessorError, Addresser, Processor}, Context};
@@ -17,7 +17,7 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
let actor = upub::model::actor::Entity::ap_to_internal(&job.actor, &tx)
.await?
.ok_or_else(|| DbErr::RecordNotFound(job.actor.clone()))?;
- let activity = upub::model::activity::Entity::ap_to_internal(activity.object().id()?, &tx)
+ let activity = upub::model::activity::Entity::ap_to_internal(&activity.object().id()?, &tx)
.await?
.ok_or_else(|| DbErr::RecordNotFound(activity.object().id().unwrap_or_default().to_string()))?;
upub::model::notification::Entity::update_many()
@@ -41,14 +41,14 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
}
activity = activity
- .set_id(Some(&job.activity))
+ .set_id(Some(job.activity.clone()))
.set_actor(apb::Node::link(job.actor.clone()))
.set_published(Some(now));
if matches!(t, apb::ObjectType::Activity(apb::ActivityType::Undo)) {
let mut undone = activity.object().into_inner()?;
if undone.id().is_err() {
- let undone_target = undone.object().id().str().ok_or(crate::JobError::MissingPayload)?;
+ let undone_target = undone.object().id()?;
let undone_type = undone.activity_type().map_err(|_| crate::JobError::MissingPayload)?;
let undone_model = model::activity::Entity::find()
.filter(model::activity::Column::Object.eq(&undone_target))
@@ -59,7 +59,7 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
.await?
.ok_or_else(|| sea_orm::DbErr::RecordNotFound(format!("actor={},type={},object={}",job.actor, undone_type, undone_target)))?;
undone = undone
- .set_id(Some(&undone_model.id))
+ .set_id(Some(undone_model.id))
.set_actor(apb::Node::link(job.actor.clone()));
}
activity = activity.set_object(apb::Node::object(undone));
@@ -67,7 +67,7 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
macro_rules! update {
($prev:ident, $field:ident, $getter:expr) => {
- if let Some($field) = $getter {
+ if let Ok($field) = $getter {
$prev.$field = Some($field.to_string());
}
};
@@ -77,7 +77,7 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
let mut updated = activity.object().into_inner()?;
match updated.object_type()? {
apb::ObjectType::Actor(_) => {
- let mut prev = model::actor::Entity::find_by_ap_id(updated.id()?)
+ let mut prev = model::actor::Entity::find_by_ap_id(&updated.id()?)
.one(&tx)
.await?
.ok_or_else(|| crate::JobError::MissingPayload)?;
@@ -86,10 +86,10 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
return Err(crate::JobError::Forbidden);
}
- update!(prev, name, updated.name().ok());
- update!(prev, summary, updated.summary().ok());
- update!(prev, icon, updated.icon().get().and_then(|x| x.url().id().str()));
- update!(prev, image, updated.image().get().and_then(|x| x.url().id().str()));
+ update!(prev, name, updated.name());
+ update!(prev, summary, updated.summary());
+ update!(prev, icon, updated.icon_url());
+ update!(prev, image, updated.image_url());
if !updated.attachment().is_empty() {
prev.fields = updated.attachment()
@@ -104,7 +104,7 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
updated = prev.ap();
},
apb::ObjectType::Note => {
- let mut prev = model::object::Entity::find_by_ap_id(updated.id()?)
+ let mut prev = model::object::Entity::find_by_ap_id(&updated.id()?)
.one(&tx)
.await?
.ok_or_else(|| crate::JobError::MissingPayload)?;
@@ -113,10 +113,10 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
return Err(crate::JobError::Forbidden);
}
- update!(prev, name, updated.name().ok());
- update!(prev, summary, updated.summary().ok());
- update!(prev, content, updated.content().ok());
- update!(prev, image, updated.image().get().and_then(|x| x.url().id().str()));
+ update!(prev, name, updated.name());
+ update!(prev, summary, updated.summary());
+ update!(prev, content, updated.content());
+ update!(prev, image, updated.image_url());
if let Ok(sensitive) = updated.sensitive() {
prev.sensitive = sensitive;
@@ -158,8 +158,8 @@ pub async fn process(ctx: Context, job: &model::job::Model) -> crate::JobResult<
activity = activity
.set_object(apb::Node::object(
object
- .set_id(Some(&oid))
- .set_content(content.as_deref())
+ .set_id(Some(oid))
+ .set_content(content)
.set_attributed_to(apb::Node::link(job.actor.clone()))
.set_published(Some(now))
.set_updated(Some(now))
diff --git a/web/src/activities/item.rs b/web/src/activities/item.rs
index 14e6c59..fa7aeec 100644
--- a/web/src/activities/item.rs
+++ b/web/src/activities/item.rs
@@ -1,16 +1,16 @@
use leptos::*;
use crate::prelude::*;
-use apb::{field::OptionalString, target::Addressed, Activity, ActivityMut, Base, Object};
+use apb::{target::Addressed, Activity, ActivityMut, Base, Object};
#[component]
pub fn ActivityLine(activity: crate::Object, children: Children) -> impl IntoView {
- let object_id = activity.object().id().str().unwrap_or_default();
+ let object_id = activity.object().id().unwrap_or_default();
let activity_url = activity.id().map(|x| view! {
"↗"
});
- let actor_id = activity.actor().id().str().unwrap_or_default();
+ let actor_id = activity.actor().id().unwrap_or_default();
let actor = cache::OBJECTS.get_or(&actor_id, serde_json::Value::String(actor_id.clone()).into());
let kind = activity.activity_type().unwrap_or(apb::ActivityType::Activity);
let href = match kind {
@@ -60,7 +60,7 @@ pub fn Item(
Some(view! { {sep.clone()} }.into_view()),
// everything else
apb::ObjectType::Activity(t) => {
- let object_id = item.object().id().str().unwrap_or_default();
+ let object_id = item.object().id().unwrap_or_default();
let object = match t {
apb::ActivityType::Create | apb::ActivityType::Announce =>
cache::OBJECTS.get(&object_id).map(|obj| {
diff --git a/web/src/actors/header.rs b/web/src/actors/header.rs
index 4036aae..3a985cb 100644
--- a/web/src/actors/header.rs
+++ b/web/src/actors/header.rs
@@ -2,7 +2,7 @@ use leptos::*;
use leptos_router::*;
use crate::{getters::Getter, prelude::*, FALLBACK_IMAGE_URL};
-use apb::{field::OptionalString, ActivityMut, Actor, Base, Object, ObjectMut};
+use apb::{ActivityMut, Actor, Base, Object, ObjectMut, Shortcuts};
#[component]
pub fn ActorHeader() -> impl IntoView {
@@ -16,7 +16,7 @@ pub fn ActorHeader() -> impl IntoView {
Some(x) => Some(x.clone()),
None => {
let user = cache::OBJECTS.resolve(&id, U::Actor, auth).await?;
- if let Some(url) = user.url().id().str() {
+ if let Ok(url) = user.url().id() {
cache::WEBFINGER.store(&url, user.id().unwrap_or_default().to_string());
}
Some(user)
@@ -29,10 +29,10 @@ pub fn ActorHeader() -> impl IntoView {
None => view! { }.into_view(),
Some(None) => view! { "could not resolve user"
}.into_view(),
Some(Some(actor)) => {
- let avatar_url = actor.icon().get().map(|x| x.url().id().str().unwrap_or(FALLBACK_IMAGE_URL.into())).unwrap_or(FALLBACK_IMAGE_URL.into());
- let background_url = actor.image().get().map(|x| x.url().id().str().unwrap_or(FALLBACK_IMAGE_URL.into())).unwrap_or(FALLBACK_IMAGE_URL.into());
+ let avatar_url = actor.icon_url().unwrap_or(FALLBACK_IMAGE_URL.into());
+ let background_url = actor.image_url().unwrap_or(FALLBACK_IMAGE_URL.into());
let username = actor.preferred_username().unwrap_or_default().to_string();
- let name = actor.name().str().unwrap_or(username.clone());
+ let name = actor.name().unwrap_or(username.clone());
let created = actor.published().ok();
let following_me = actor.following_me().unwrap_or(false);
let followed_by_me = actor.followed_by_me().unwrap_or(false);
@@ -44,11 +44,11 @@ pub fn ActorHeader() -> impl IntoView {
let fields = actor.attachment()
.flat()
.into_iter()
- .filter_map(|x| x.extract())
+ .filter_map(|x| x.into_inner().ok())
.map(|x| view! {
- {x.name().str().unwrap_or_default()} |
- |
+ {x.name().unwrap_or_default()} |
+ |
})
.collect_view();
@@ -110,7 +110,7 @@ pub fn ActorHeader() -> impl IntoView {
}}
-
+
diff --git a/web/src/components/post.rs b/web/src/components/post.rs
index b56b72e..d3f3f39 100644
--- a/web/src/components/post.rs
+++ b/web/src/components/post.rs
@@ -1,4 +1,4 @@
-use apb::{field::OptionalString, ActivityMut, Base, BaseMut, Object, ObjectMut};
+use apb::{ActivityMut, Base, BaseMut, Object, ObjectMut};
use leptos::*;
use crate::prelude::*;
@@ -12,7 +12,7 @@ pub struct ReplyControls {
impl ReplyControls {
pub fn reply(&self, oid: &str) {
if let Some(obj) = cache::OBJECTS.get(oid) {
- self.context.set(obj.context().id().str());
+ self.context.set(obj.context().id().ok());
self.reply_to.set(obj.id().ok().map(|x| x.to_string()));
}
}
@@ -24,7 +24,7 @@ impl ReplyControls {
}
fn post_author(post_id: &str) -> Option {
- let usr = cache::OBJECTS.get(post_id)?.attributed_to().id().str()?;
+ let usr = cache::OBJECTS.get(post_id)?.attributed_to().id().ok()?;
cache::OBJECTS.get(&usr)
}
@@ -135,9 +135,9 @@ pub fn PostBox(advanced: WriteSignal) -> impl IntoView {
.into_iter()
.map(|x| {
use apb::LinkMut;
- LinkMut::set_name(apb::new(), Some(&format!("@{}@{}", x.name, x.domain))) // TODO ewww but name clashes
+ LinkMut::set_name(apb::new(), Some(format!("@{}@{}", x.name, x.domain))) // TODO ewww but name clashes
.set_link_type(Some(apb::LinkType::Mention))
- .set_href(Some(&x.href))
+ .set_href(Some(x.href))
})
.collect();
@@ -146,10 +146,10 @@ pub fn PostBox(advanced: WriteSignal) -> impl IntoView {
if let Ok(uid) = au.id() {
to_vec.push(uid.to_string());
if let Ok(name) = au.name() {
- let domain = Uri::domain(uid);
+ let domain = Uri::domain(&uid);
mention_tags.push({
use apb::LinkMut;
- LinkMut::set_name(apb::new(), Some(&format!("@{}@{}", name, domain))) // TODO ewww but name clashes
+ LinkMut::set_name(apb::new(), Some(format!("@{}@{}", name, domain))) // TODO ewww but name clashes
.set_link_type(Some(apb::LinkType::Mention))
.set_href(Some(uid))
});
@@ -162,8 +162,8 @@ pub fn PostBox(advanced: WriteSignal) -> impl IntoView {
}
let payload = apb::new()
.set_object_type(Some(apb::ObjectType::Note))
- .set_summary(summary.as_deref())
- .set_content(Some(&content))
+ .set_summary(summary)
+ .set_content(Some(content))
.set_context(apb::Node::maybe_link(reply.context.get()))
.set_in_reply_to(apb::Node::maybe_link(reply.reply_to.get()))
.set_to(apb::Node::links(to_vec))
@@ -299,11 +299,11 @@ pub fn AdvancedPostBox(advanced: WriteSignal) -> impl IntoView {
if embedded.get() {
apb::Node::object(
serde_json::Value::Object(serde_json::Map::default())
- .set_id(object_id.as_deref())
+ .set_id(object_id)
.set_object_type(Some(apb::ObjectType::Note))
- .set_name(name.as_deref())
- .set_summary(summary.as_deref())
- .set_content(content.as_deref())
+ .set_name(name)
+ .set_summary(summary)
+ .set_content(content)
.set_in_reply_to(apb::Node::maybe_link(reply))
.set_context(apb::Node::maybe_link(context))
.set_to(apb::Node::links(to))
diff --git a/web/src/components/user.rs b/web/src/components/user.rs
index 4624713..cc2065d 100644
--- a/web/src/components/user.rs
+++ b/web/src/components/user.rs
@@ -1,7 +1,7 @@
use leptos::*;
use crate::{prelude::*, FALLBACK_IMAGE_URL};
-use apb::{field::OptionalString, Activity, ActivityMut, Actor, Base, Object, ObjectMut};
+use apb::{Activity, ActivityMut, Actor, Base, Object, ObjectMut, Shortcuts};
lazy_static::lazy_static! {
static ref REGEX: regex::Regex = regex::Regex::new(r":\w+:").expect("failed compiling custom emoji regex");
@@ -12,7 +12,7 @@ pub fn ActorStrip(object: crate::Object) -> impl IntoView {
let actor_id = object.id().unwrap_or_default().to_string();
let username = object.preferred_username().unwrap_or_default().to_string();
let domain = object.id().unwrap_or_default().replace("https://", "").split('/').next().unwrap_or_default().to_string();
- let avatar = object.icon().get().map(|x| x.url().id().str().unwrap_or(FALLBACK_IMAGE_URL.into())).unwrap_or(FALLBACK_IMAGE_URL.into());
+ let avatar = object.icon_url().unwrap_or(FALLBACK_IMAGE_URL.into());
view! {
{username}@{domain}
@@ -29,7 +29,7 @@ pub fn ActorBanner(object: crate::Object) -> impl IntoView {
serde_json::Value::Object(_) => {
let uid = object.id().unwrap_or_default().to_string();
let uri = Uri::web(U::Actor, &uid);
- let avatar_url = object.icon().get().map(|x| x.url().id().str().unwrap_or(FALLBACK_IMAGE_URL.into())).unwrap_or(FALLBACK_IMAGE_URL.into());
+ let avatar_url = object.icon_url().unwrap_or(FALLBACK_IMAGE_URL.into());
let username = object.preferred_username().unwrap_or_default().to_string();
let domain = object.id().unwrap_or_default().replace("https://", "").split('/').next().unwrap_or_default().to_string();
let display_name = object.name().unwrap_or_default().to_string();
@@ -70,7 +70,7 @@ pub fn FollowRequestButtons(activity_id: String, actor_id: String) -> impl IntoV
// TODO lmao what is going on with this double move / triple clone ???????????
let _activity_id = activity_id.clone();
let _actor_id = actor_id.clone();
- let from_actor = cache::OBJECTS.get(&activity_id).map(|x| x.actor().id().str().unwrap_or_default()).unwrap_or_default();
+ let from_actor = cache::OBJECTS.get(&activity_id).and_then(|x| x.actor().id().ok()).unwrap_or_default();
let _from_actor = from_actor.clone();
if actor_id == auth.user_id() {
Some(view! {
diff --git a/web/src/config.rs b/web/src/config.rs
index e460e8d..48c7109 100644
--- a/web/src/config.rs
+++ b/web/src/config.rs
@@ -66,7 +66,7 @@ impl FiltersConfig {
let mut reply_filter = true;
if let Ok(obj_id) = item.object().id() {
- if let Some(obj) = crate::cache::OBJECTS.get(obj_id) {
+ if let Some(obj) = crate::cache::OBJECTS.get(&obj_id) {
if obj.in_reply_to().id().is_ok() {
reply_filter = self.replies;
}
diff --git a/web/src/objects/attachment.rs b/web/src/objects/attachment.rs
index a028795..965d1e8 100644
--- a/web/src/objects/attachment.rs
+++ b/web/src/objects/attachment.rs
@@ -2,7 +2,7 @@ use leptos::*;
use crate::{prelude::*, URL_SENSITIVE};
use base64::prelude::*;
-use apb::{field::OptionalString, Document, Object};
+use apb::{Document, Object};
fn uncloak(txt: Option<&str>) -> Option {
let decoded = BASE64_URL_SAFE.decode(txt?).ok()?;
@@ -17,11 +17,10 @@ pub fn Attachment(
) -> impl IntoView {
let config = use_context::>().expect("missing config context");
let (expand, set_expand) = create_signal(false);
- let href = object.url().id().str().unwrap_or_default();
+ let href = object.url().id().ok().unwrap_or_default();
let uncloaked = uncloak(href.split('/').last()).unwrap_or_default();
let media_type = object.media_type()
- .unwrap_or("link") // TODO make it an Option rather than defaulting to link everywhere
- .to_string();
+ .unwrap_or("link".to_string()); // TODO make it an Option rather than defaulting to link everywhere
let mut kind = media_type
.split('/')
.next()
diff --git a/web/src/objects/item.rs b/web/src/objects/item.rs
index 21b8204..91f1ffa 100644
--- a/web/src/objects/item.rs
+++ b/web/src/objects/item.rs
@@ -3,29 +3,26 @@ use std::sync::Arc;
use leptos::*;
use crate::{prelude::*, URL_SENSITIVE};
-use apb::{field::OptionalString, target::Addressed, ActivityMut, Base, Collection, CollectionMut, Object, ObjectMut};
+use apb::{target::Addressed, ActivityMut, Base, Collection, CollectionMut, Object, ObjectMut};
#[component]
pub fn Object(object: crate::Object) -> impl IntoView {
let oid = object.id().unwrap_or_default().to_string();
- let author_id = object.attributed_to().id().str().unwrap_or_default();
+ let author_id = object.attributed_to().id().ok().unwrap_or_default();
let author = cache::OBJECTS.get_or(&author_id, serde_json::Value::String(author_id.clone()).into());
let sensitive = object.sensitive().unwrap_or_default();
let addressed = object.addressed();
let public = addressed.iter().any(|x| x.as_str() == apb::target::PUBLIC);
- let external_url = object.url().id().str().unwrap_or_else(|| oid.clone());
+ let external_url = object.url().id().ok().unwrap_or_else(|| oid.clone());
let attachments = object.attachment()
.flat()
.into_iter()
- .filter_map(|x| x.extract()) // TODO maybe show links?
+ .filter_map(|x| x.into_inner().ok()) // TODO maybe show links?
.map(|x| view! { })
.collect_view();
- let comments = object.replies().get()
- .map_or(0, |x| x.total_items().unwrap_or(0));
- let shares = object.shares().get()
- .map_or(0, |x| x.total_items().unwrap_or(0));
- let likes = object.likes().get()
- .map_or(0, |x| x.total_items().unwrap_or(0));
+ let comments = object.replies().inner().and_then(|x| x.total_items()).unwrap_or_default();
+ let shares = object.shares().inner().and_then(|x| x.total_items()).unwrap_or_default();
+ let likes = object.likes().inner().and_then(|x| x.total_items()).unwrap_or_default();
let already_liked = object.liked_by_me().unwrap_or(false);
let attachments_padding = if object.attachment().is_empty() {
@@ -34,9 +31,9 @@ pub fn Object(object: crate::Object) -> impl IntoView {
Some(view! { })
};
- let content = mdhtml::safe_html(object.content().unwrap_or_default());
+ let content = mdhtml::safe_html(&object.content().unwrap_or_default());
- let audience_badge = object.audience().id().str()
+ let audience_badge = object.audience().id().ok()
.map(|x| {
// TODO this isn't guaranteed to work every time...
let name = x.split('/').last().unwrap_or_default().to_string();
@@ -56,7 +53,7 @@ pub fn Object(object: crate::Object) -> impl IntoView {
.id()
.ok()
.map(|x| {
- let href = Uri::web(U::Object, x);
+ let href = Uri::web(U::Object, &x);
view! {
@@ -103,7 +100,7 @@ pub fn Object(object: crate::Object) -> impl IntoView {
uid.replace("https://", "").replace("http://", "").split('/').next().unwrap_or_default().to_string(),
)
};
- let href = Uri::web(U::Actor, uid);
+ let href = Uri::web(U::Actor, &uid);
Some(view! {
@@ -119,7 +116,7 @@ pub fn Object(object: crate::Object) -> impl IntoView {
}
}).collect_view();
- let post_image = object.image().get().and_then(|x| x.url().id().str()).map(|x| {
+ let post_image = object.image().inner().and_then(|x| x.url().id()).ok().map(|x| {
let (expand, set_expand) = create_signal(false);
view! {
impl IntoView {
|
- {object.in_reply_to().id().str().map(|reply| view! {
+ {object.in_reply_to().id().ok().map(|reply| view! {
reply
})}
-
+
"↗"
@@ -262,7 +259,7 @@ pub fn LikeButton(
set_count.set(count.get() + 1);
if let Some(cached) = cache::OBJECTS.get(&target) {
let mut new = (*cached).clone().set_liked_by_me(Some(true));
- if let Some(likes) = new.likes().get() {
+ if let Ok(likes) = new.likes().inner() {
if let Ok(count) = likes.total_items() {
new = new.set_likes(apb::Node::object(likes.clone().set_total_items(Some(count + 1))));
}
diff --git a/web/src/objects/view.rs b/web/src/objects/view.rs
index 7bf11b8..9aa7db5 100644
--- a/web/src/objects/view.rs
+++ b/web/src/objects/view.rs
@@ -13,7 +13,7 @@ pub fn ObjectView() -> impl IntoView {
move |oid| async move {
let obj = cache::OBJECTS.resolve(&oid, U::Object, auth).await?;
if let Ok(author) = obj.attributed_to().id() {
- cache::OBJECTS.resolve(author, U::Actor, auth).await;
+ cache::OBJECTS.resolve(&author, U::Actor, auth).await;
}
Some(obj)
@@ -36,8 +36,8 @@ pub fn ObjectView() -> impl IntoView {
Some(Some(o)) => {
let object = o.clone();
let oid = o.id().unwrap_or_default();
- let base = Uri::web(U::Object, oid);
- let api = Uri::api(U::Object, oid, false);
+ let base = Uri::web(U::Object, &oid);
+ let api = Uri::api(U::Object, &oid, false);
view!{
diff --git a/web/src/page/config.rs b/web/src/page/config.rs
index 23aa837..493676a 100644
--- a/web/src/page/config.rs
+++ b/web/src/page/config.rs
@@ -21,10 +21,15 @@ pub fn ConfigPage(setter: WriteSignal) -> impl IntoView {
let banner_url_ref: NodeRef = create_node_ref();
let myself = cache::OBJECTS.get(&auth.userid.get_untracked().unwrap_or_default());
- let curr_display_name = myself.as_ref().and_then(|x| Some(x.name().ok()?.to_string())).unwrap_or_default();
- let curr_summary = myself.as_ref().and_then(|x| Some(x.summary().ok()?.to_string())).unwrap_or_default();
- let curr_icon = myself.as_ref().and_then(|x| Some(x.icon().get()?.url().id().ok()?.to_string())).unwrap_or_default();
- let curr_banner = myself.as_ref().and_then(|x| Some(x.image().get()?.url().id().ok()?.to_string())).unwrap_or_default();
+ let (curr_display_name, curr_summary, curr_icon, curr_banner) = match myself.as_ref() {
+ None => (String::default(), String::default(), String::default(), String::default()),
+ Some(myself) => (
+ myself.name().unwrap_or_default().to_string(),
+ myself.summary().unwrap_or_default().to_string(),
+ myself.icon().inner().and_then(|x| Ok(x.url().id()?.to_string())).unwrap_or_default(),
+ myself.image().inner().and_then(|x| Ok(x.url().id()?.to_string())).unwrap_or_default(),
+ ),
+ };
macro_rules! get_cfg {
(filter $field:ident) => {
@@ -175,8 +180,8 @@ pub fn ConfigPage(setter: WriteSignal) -> impl IntoView {
.set_to(apb::Node::links(vec![apb::target::PUBLIC.to_string(), format!("{id}/followers")]))
.set_object(apb::Node::object(
(*me).clone()
- .set_name(display_name.as_deref())
- .set_summary(summary.as_deref())
+ .set_name(display_name)
+ .set_summary(summary)
.set_icon(apb::Node::maybe_object(avatar))
.set_image(apb::Node::maybe_object(banner))
.set_published(Some(chrono::Utc::now()))
diff --git a/web/src/page/search.rs b/web/src/page/search.rs
index fcb6cbd..2ac755f 100644
--- a/web/src/page/search.rs
+++ b/web/src/page/search.rs
@@ -41,7 +41,7 @@ pub fn SearchPage() -> impl IntoView {
.ordered_items()
.flat()
.into_iter()
- .filter_map(|x| x.extract())
+ .filter_map(|x| x.into_inner().ok())
.collect(),
auth
).await
diff --git a/web/src/timeline/mod.rs b/web/src/timeline/mod.rs
index 2ce91b3..0503766 100644
--- a/web/src/timeline/mod.rs
+++ b/web/src/timeline/mod.rs
@@ -3,7 +3,7 @@ pub mod thread;
use std::{collections::BTreeSet, pin::Pin, sync::Arc};
-use apb::{field::OptionalString, Activity, ActivityMut, Actor, Base, Object};
+use apb::{Activity, ActivityMut, Actor, Base, Object};
use leptos::*;
use crate::prelude::*;
@@ -89,7 +89,7 @@ impl Timeline {
.ordered_items()
.flat()
.into_iter()
- .filter_map(|x| x.extract())
+ .filter_map(|x| x.into_inner().ok())
.collect();
let mut feed = self.feed.get_untracked();
@@ -121,18 +121,18 @@ pub async fn process_activities(activities: Vec, auth: Auth)
for activity in activities {
let activity_type = activity.activity_type().unwrap_or(apb::ActivityType::Activity);
// save embedded object if present
- if let Some(object) = activity.object().get() {
+ if let Ok(object) = activity.object().inner() {
// also fetch actor attributed to
- if let Some(attributed_to) = object.attributed_to().id().str() {
+ if let Ok(attributed_to) = object.attributed_to().id() {
actors_seen.insert(attributed_to);
}
if let Ok(object_uri) = object.id() {
- cache::OBJECTS.store(object_uri, Arc::new(object.clone()));
+ cache::OBJECTS.store(&object_uri, Arc::new(object.clone()));
} else {
tracing::warn!("embedded object without id: {object:?}");
}
} else { // try fetching it
- if let Some(object_id) = activity.object().id().str() {
+ if let Ok(object_id) = activity.object().id() {
if !gonna_fetch.contains(&object_id) {
let fetch_kind = match activity_type {
apb::ActivityType::Follow => U::Actor,
@@ -145,25 +145,25 @@ pub async fn process_activities(activities: Vec, auth: Auth)
}
// save activity, removing embedded object
- let object_id = activity.object().id().str();
- if let Some(activity_id) = activity.id().str() {
+ let object_id = activity.object().id().ok();
+ if let Ok(activity_id) = activity.id() {
out.push(activity_id.to_string());
cache::OBJECTS.store(
&activity_id,
Arc::new(activity.clone().set_object(apb::Node::maybe_link(object_id)))
);
- } else if let Some(object_id) = activity.object().id().str() {
+ } else if let Ok(object_id) = activity.object().id() {
out.push(object_id);
}
- if let Some(uid) = activity.attributed_to().id().str() {
+ if let Ok(uid) = activity.attributed_to().id() {
if cache::OBJECTS.get(&uid).is_none() && !gonna_fetch.contains(&uid) {
gonna_fetch.insert(uid.clone());
sub_tasks.push(Box::pin(fetch_and_update(U::Actor, uid, auth)));
}
}
- if let Some(uid) = activity.actor().id().str() {
+ if let Ok(uid) = activity.actor().id() {
if cache::OBJECTS.get(&uid).is_none() && !gonna_fetch.contains(&uid) {
gonna_fetch.insert(uid.clone());
sub_tasks.push(Box::pin(fetch_and_update(U::Actor, uid, auth)));
@@ -185,7 +185,7 @@ async fn fetch_and_update(kind: U, id: String, auth: Auth) {
Err(e) => console_warn(&format!("could not fetch '{id}': {e}")),
Ok(data) => {
if data.actor_type().is_ok() {
- if let Some(url) = data.url().id().str() {
+ if let Ok(url) = data.url().id() {
cache::WEBFINGER.store(&id, url);
}
}
@@ -198,8 +198,8 @@ async fn fetch_and_update_with_user(kind: U, id: String, auth: Auth) {
fetch_and_update(kind, id.clone(), auth).await;
if let Some(obj) = cache::OBJECTS.get(&id) {
if let Some(actor_id) = match kind {
- U::Object => obj.attributed_to().id().str(),
- U::Activity => obj.actor().id().str(),
+ U::Object => obj.attributed_to().id().ok(),
+ U::Activity => obj.actor().id().ok(),
U::Actor => None,
U::Hashtag => None,
} {
diff --git a/web/src/timeline/thread.rs b/web/src/timeline/thread.rs
index 2eb650b..f22fc45 100644
--- a/web/src/timeline/thread.rs
+++ b/web/src/timeline/thread.rs
@@ -1,4 +1,4 @@
-use apb::{field::OptionalString, Activity, Base, Object};
+use apb::{Activity, Base, Object};
use leptos::*;
use crate::prelude::*;
use super::Timeline;
@@ -40,15 +40,15 @@ fn FeedRecursive(tl: Timeline, root: String) -> impl IntoView {
let (oid, reply) = match document.object_type().ok()? {
// if it's a create, get and check created object: does it reply to root?
apb::ObjectType::Activity(apb::ActivityType::Create) => {
- let object = cache::OBJECTS.get(document.object().id().ok()?)?;
- (object.id().str()?, object.in_reply_to().id().str()?)
+ let object = cache::OBJECTS.get(&document.object().id().ok()?)?;
+ (object.id().ok()?, object.in_reply_to().id().ok()?)
},
// if it's a raw note, directly check if it replies to root
- apb::ObjectType::Note => (document.id().str()?, document.in_reply_to().id().str()?),
+ apb::ObjectType::Note => (document.id().ok()?, document.in_reply_to().id().ok()?),
// if it's anything else, check if it relates to root, maybe like or announce?
- _ => (document.id().str()?, document.object().id().str()?),
+ _ => (document.id().ok()?, document.object().id().ok()?),
};
if reply == root {
Some((oid, document))
|