Fetch object referenced by quoteUrl property and create a link between posts

This commit is contained in:
silverpill 2022-08-21 22:51:40 +00:00
parent d9def75b32
commit f4d1e756d4
3 changed files with 60 additions and 19 deletions

View file

@ -78,6 +78,9 @@ pub struct Object {
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub quote_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tag: Option<Vec<Tag>>,

View file

@ -205,6 +205,7 @@ pub async fn import_post(
// Fetch ancestors by going through inReplyTo references
// TODO: fetch replies too
#[allow(clippy::while_let_loop)]
#[allow(clippy::manual_map)]
loop {
let object_id = match maybe_object_id_to_fetch {
Some(object_id) => {
@ -212,7 +213,7 @@ pub async fn import_post(
// Object is a local post
assert!(objects.len() > 0);
break;
}
};
match get_post_by_object_id(db_client, &object_id).await {
Ok(post) => {
// Object already fetched
@ -252,11 +253,21 @@ pub async fn import_post(
// Don't re-fetch object on the next iteration
maybe_object = Some(object);
} else {
maybe_object_id_to_fetch = object.in_reply_to.clone();
maybe_object_id_to_fetch = if let Some(ref object_id) = object.in_reply_to {
// Fetch parent object on next iteration
Some(object_id.to_owned())
} else if let Some(ref object_id) = object.quote_url {
// Fetch quoted object on next iteration
// (only if object doesn't have a parent).
Some(object_id.to_owned())
} else {
// Stop
None
};
maybe_object = None;
objects.push(object);
};
}
};
let initial_object_id = objects[0].id.clone();
// Objects are ordered according to their place in reply tree,
@ -271,7 +282,7 @@ pub async fn import_post(
&redirects,
).await?;
posts.push(post);
}
};
let initial_post = posts.into_iter()
.find(|post| post.object_id.as_ref() == Some(&initial_object_id))

View file

@ -114,6 +114,27 @@ fn get_note_visibility(
Visibility::Direct
}
async fn get_internal_post_id(
db_client: &impl GenericClient,
instance_url: &str,
object_id: &String,
redirects: &HashMap<String, String>,
) -> Result<Uuid, ImportError> {
match parse_local_object_id(instance_url, object_id) {
Ok(post_id) => {
// Local post
let post = get_post_by_id(db_client, &post_id).await?;
Ok(post.id)
},
Err(_) => {
let real_object_id = redirects.get(object_id)
.unwrap_or(object_id);
let post = get_post_by_object_id(db_client, real_object_id).await?;
Ok(post.id)
},
}
}
pub async fn handle_note(
db_client: &mut impl GenericClient,
instance: &Instance,
@ -175,6 +196,7 @@ pub async fn handle_note(
};
let mut mentions: Vec<Uuid> = Vec::new();
let mut tags = vec![];
let mut links = vec![];
if let Some(list) = object.tag {
for tag in list {
if tag.tag_type == HASHTAG {
@ -269,21 +291,26 @@ pub async fn handle_note(
};
};
};
if let Some(ref object_id) = object.quote_url {
log::warn!("link to object found: {}", object_id);
let quoted_id = get_internal_post_id(
db_client,
&instance.url(),
object_id,
redirects,
).await?;
links.push(quoted_id);
};
let in_reply_to_id = match object.in_reply_to {
Some(object_id) => {
match parse_local_object_id(&instance.url(), &object_id) {
Ok(post_id) => {
// Local post
let post = get_post_by_id(db_client, &post_id).await?;
Some(post.id)
},
Err(_) => {
let note_id = redirects.get(&object_id)
.unwrap_or(&object_id);
let post = get_post_by_object_id(db_client, note_id).await?;
Some(post.id)
},
}
Some(ref object_id) => {
let in_reply_to_id = get_internal_post_id(
db_client,
&instance.url(),
object_id,
redirects,
).await?;
Some(in_reply_to_id)
},
None => None,
};
@ -321,7 +348,7 @@ pub async fn handle_note(
attachments: attachments,
mentions: mentions,
tags: tags,
links: vec![],
links: links,
object_id: Some(object.id),
created_at: object.published,
};