Add replies and reposts to outbox collection
This commit is contained in:
parent
b6e7fa5d13
commit
b77d4a9bdf
4 changed files with 37 additions and 34 deletions
|
@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Ignore errors when importing activities from outbox.
|
||||
- Make activity limit in outbox fetcher adjustable.
|
||||
- Updated actix to latest version. MSRV changed to 1.57.
|
||||
- Add replies and reposts to outbox collection.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ use crate::activitypub::{
|
|||
};
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Announce {
|
||||
pub struct Announce {
|
||||
#[serde(rename = "@context")]
|
||||
context: Context,
|
||||
|
||||
|
@ -41,18 +41,17 @@ struct Announce {
|
|||
cc: Vec<String>,
|
||||
}
|
||||
|
||||
fn build_announce(
|
||||
pub fn build_announce(
|
||||
instance_url: &str,
|
||||
sender_username: &str,
|
||||
repost: &Post,
|
||||
) -> Announce {
|
||||
let actor_id = local_actor_id(instance_url, sender_username);
|
||||
let actor_id = local_actor_id(instance_url, &repost.author.username);
|
||||
let post = repost.repost_of.as_ref()
|
||||
.expect("repost_of field should be populated");
|
||||
let object_id = post_object_id(instance_url, post);
|
||||
let activity_id = local_object_id(instance_url, &repost.id);
|
||||
let recipient_id = profile_actor_id(instance_url, &post.author);
|
||||
let followers = local_actor_followers(instance_url, sender_username);
|
||||
let followers = local_actor_followers(instance_url, &repost.author.username);
|
||||
Announce {
|
||||
context: build_default_context(),
|
||||
activity_type: ANNOUNCE.to_string(),
|
||||
|
@ -91,7 +90,9 @@ pub async fn prepare_announce(
|
|||
sender: &User,
|
||||
repost: &Post,
|
||||
) -> Result<OutgoingActivity, DatabaseError> {
|
||||
let post = repost.repost_of.as_ref().unwrap();
|
||||
assert_eq!(sender.id, repost.author.id);
|
||||
let post = repost.repost_of.as_ref()
|
||||
.expect("repost_of field should be populated");
|
||||
let (recipients, _) = get_announce_recipients(
|
||||
db_client,
|
||||
&instance.url(),
|
||||
|
@ -100,7 +101,6 @@ pub async fn prepare_announce(
|
|||
).await?;
|
||||
let activity = build_announce(
|
||||
&instance.url(),
|
||||
&sender.profile.username,
|
||||
repost,
|
||||
);
|
||||
Ok(OutgoingActivity::new(
|
||||
|
@ -140,14 +140,13 @@ mod tests {
|
|||
..Default::default()
|
||||
};
|
||||
let repost = Post {
|
||||
author: repost_author.clone(),
|
||||
author: repost_author,
|
||||
repost_of_id: Some(post.id),
|
||||
repost_of: Some(Box::new(post)),
|
||||
..Default::default()
|
||||
};
|
||||
let activity = build_announce(
|
||||
INSTANCE_URL,
|
||||
&repost_author.username,
|
||||
&repost,
|
||||
);
|
||||
assert_eq!(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use serde_json::{json, Value};
|
||||
use serde_json::{Value as JsonValue};
|
||||
|
||||
use super::types::{build_default_context, Context};
|
||||
use super::vocabulary::{ORDERED_COLLECTION, ORDERED_COLLECTION_PAGE};
|
||||
|
@ -38,8 +38,6 @@ impl OrderedCollection {
|
|||
}
|
||||
}
|
||||
|
||||
pub const COLLECTION_PAGE_SIZE: u16 = 10;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct OrderedCollectionPage {
|
||||
|
@ -51,21 +49,19 @@ pub struct OrderedCollectionPage {
|
|||
#[serde(rename = "type")]
|
||||
pub object_type: String,
|
||||
|
||||
ordered_items: Vec<Value>,
|
||||
ordered_items: Vec<JsonValue>,
|
||||
}
|
||||
|
||||
impl OrderedCollectionPage {
|
||||
pub fn new(
|
||||
collection_page_id: String,
|
||||
items: Vec<impl Serialize>,
|
||||
items: Vec<JsonValue>,
|
||||
) -> Self {
|
||||
let ordered_items = items.into_iter()
|
||||
.map(|item| json!(item)).collect();
|
||||
Self {
|
||||
context: build_default_context(),
|
||||
id: collection_page_id,
|
||||
object_type: ORDERED_COLLECTION_PAGE.to_string(),
|
||||
ordered_items,
|
||||
ordered_items: items,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,13 +30,15 @@ use crate::web_client::urls::{
|
|||
get_tag_page_url,
|
||||
};
|
||||
use super::actors::types::{get_local_actor, get_instance_actor};
|
||||
use super::builders::create_note::{
|
||||
use super::builders::{
|
||||
announce::build_announce,
|
||||
create_note::{
|
||||
build_emoji_tag,
|
||||
build_note,
|
||||
build_create_note,
|
||||
},
|
||||
};
|
||||
use super::collections::{
|
||||
COLLECTION_PAGE_SIZE,
|
||||
OrderedCollection,
|
||||
OrderedCollectionPage,
|
||||
};
|
||||
|
@ -171,26 +173,31 @@ async fn outbox(
|
|||
let db_client = &**get_database_client(&db_pool).await?;
|
||||
let user = get_user_by_name(db_client, &username).await?;
|
||||
// Posts are ordered by creation date
|
||||
const COLLECTION_PAGE_SIZE: u16 = 20;
|
||||
let mut posts = get_posts_by_author(
|
||||
db_client,
|
||||
&user.id,
|
||||
None, // include only public posts
|
||||
false, // exclude replies
|
||||
false, // exclude reposts
|
||||
true, // include replies
|
||||
true, // include reposts
|
||||
None,
|
||||
COLLECTION_PAGE_SIZE,
|
||||
).await?;
|
||||
add_related_posts(db_client, posts.iter_mut().collect()).await?;
|
||||
let activities: Vec<_> = posts.iter().filter_map(|post| {
|
||||
if post.in_reply_to_id.is_some() || post.repost_of_id.is_some() {
|
||||
return None;
|
||||
};
|
||||
let activities = posts.iter().map(|post| {
|
||||
if post.repost_of_id.is_some() {
|
||||
let activity = build_announce(&instance.url(), post);
|
||||
serde_json::to_value(activity)
|
||||
.expect("activity should be serializable")
|
||||
} else {
|
||||
let activity = build_create_note(
|
||||
&instance.hostname(),
|
||||
&instance.url(),
|
||||
post,
|
||||
);
|
||||
Some(activity)
|
||||
serde_json::to_value(activity)
|
||||
.expect("activity should be serializable")
|
||||
}
|
||||
}).collect();
|
||||
let collection_page = OrderedCollectionPage::new(
|
||||
first_page_id,
|
||||
|
|
Loading…
Reference in a new issue