Move import_post to fetcher::helpers module
This commit is contained in:
parent
914fae8137
commit
75ef8bba7c
4 changed files with 106 additions and 101 deletions
|
@ -1,10 +1,16 @@
|
|||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
||||
use tokio_postgres::GenericClient;
|
||||
|
||||
use crate::activitypub::activity::Object;
|
||||
use crate::activitypub::actor::ActorAddress;
|
||||
use crate::config::Instance;
|
||||
use crate::activitypub::inbox::create_note::handle_note;
|
||||
use crate::activitypub::receiver::parse_object_id;
|
||||
use crate::config::{Config, Instance};
|
||||
use crate::errors::{DatabaseError, HttpError, ValidationError};
|
||||
use crate::models::posts::queries::get_post_by_object_id;
|
||||
use crate::models::posts::types::Post;
|
||||
use crate::models::profiles::queries::{
|
||||
get_profile_by_actor_id,
|
||||
get_profile_by_acct,
|
||||
|
@ -12,6 +18,7 @@ use crate::models::profiles::queries::{
|
|||
};
|
||||
use crate::models::profiles::types::DbActorProfile;
|
||||
use super::fetchers::{
|
||||
fetch_object,
|
||||
fetch_profile,
|
||||
fetch_profile_by_actor_id,
|
||||
FetchError,
|
||||
|
@ -104,3 +111,94 @@ pub async fn import_profile_by_actor_address(
|
|||
let profile = create_profile(db_client, profile_data).await?;
|
||||
Ok(profile)
|
||||
}
|
||||
|
||||
pub async fn import_post(
|
||||
config: &Config,
|
||||
db_client: &mut impl GenericClient,
|
||||
object_id: String,
|
||||
object_received: Option<Object>,
|
||||
) -> Result<Post, ImportError> {
|
||||
let instance = config.instance();
|
||||
let media_dir = config.media_dir();
|
||||
let mut maybe_object_id_to_fetch = Some(object_id);
|
||||
let mut maybe_object = object_received;
|
||||
let mut objects = vec![];
|
||||
let mut redirects: HashMap<String, String> = HashMap::new();
|
||||
let mut posts = vec![];
|
||||
|
||||
// Fetch ancestors by going through inReplyTo references
|
||||
// TODO: fetch replies too
|
||||
#[allow(clippy::while_let_loop)]
|
||||
loop {
|
||||
let object_id = match maybe_object_id_to_fetch {
|
||||
Some(object_id) => {
|
||||
if parse_object_id(&instance.url(), &object_id).is_ok() {
|
||||
// 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
|
||||
if objects.len() == 0 {
|
||||
// Return post corresponding to initial object ID
|
||||
return Ok(post);
|
||||
};
|
||||
break;
|
||||
},
|
||||
Err(DatabaseError::NotFound(_)) => (),
|
||||
Err(other_error) => return Err(other_error.into()),
|
||||
};
|
||||
object_id
|
||||
},
|
||||
None => {
|
||||
// No object to fetch
|
||||
break;
|
||||
},
|
||||
};
|
||||
let object = match maybe_object {
|
||||
Some(object) => object,
|
||||
None => {
|
||||
let object = fetch_object(&instance, &object_id).await
|
||||
.map_err(|err| {
|
||||
log::warn!("{}", err);
|
||||
ValidationError("failed to fetch object")
|
||||
})?;
|
||||
log::info!("fetched object {}", object.id);
|
||||
object
|
||||
},
|
||||
};
|
||||
if object.id != object_id {
|
||||
// ID of fetched object doesn't match requested ID
|
||||
// Add IDs to the map of redirects
|
||||
redirects.insert(object_id, object.id.clone());
|
||||
maybe_object_id_to_fetch = Some(object.id.clone());
|
||||
// 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 = None;
|
||||
objects.push(object);
|
||||
};
|
||||
}
|
||||
let initial_object_id = objects[0].id.clone();
|
||||
|
||||
// Objects are ordered according to their place in reply tree,
|
||||
// starting with the root
|
||||
objects.reverse();
|
||||
for object in objects {
|
||||
let post = handle_note(
|
||||
db_client,
|
||||
&instance,
|
||||
&media_dir,
|
||||
object,
|
||||
&redirects,
|
||||
).await?;
|
||||
posts.push(post);
|
||||
}
|
||||
|
||||
let initial_post = posts.into_iter()
|
||||
.find(|post| post.object_id.as_ref() == Some(&initial_object_id))
|
||||
.unwrap();
|
||||
Ok(initial_post)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,6 @@ pub mod constants;
|
|||
pub mod deliverer;
|
||||
pub mod fetcher;
|
||||
mod inbox;
|
||||
pub mod receiver;
|
||||
mod receiver;
|
||||
pub mod views;
|
||||
mod vocabulary;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use actix_web::HttpRequest;
|
||||
use regex::Regex;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
@ -15,7 +13,7 @@ use crate::models::posts::queries::{
|
|||
get_post_by_object_id,
|
||||
delete_post,
|
||||
};
|
||||
use crate::models::posts::types::{Post, PostCreateData};
|
||||
use crate::models::posts::types::PostCreateData;
|
||||
use crate::models::profiles::queries::{
|
||||
get_profile_by_actor_id,
|
||||
get_profile_by_acct,
|
||||
|
@ -39,12 +37,10 @@ use super::activity::{
|
|||
create_activity_accept_follow,
|
||||
};
|
||||
use super::deliverer::deliver_activity;
|
||||
use super::fetcher::fetchers::fetch_object;
|
||||
use super::fetcher::helpers::{
|
||||
get_or_import_profile_by_actor_id,
|
||||
ImportError,
|
||||
import_post,
|
||||
};
|
||||
use super::inbox::create_note::handle_note;
|
||||
use super::inbox::update_person::handle_update_person;
|
||||
use super::vocabulary::*;
|
||||
|
||||
|
@ -145,97 +141,6 @@ fn get_object_id(object: Value) -> Result<String, ValidationError> {
|
|||
Ok(object_id)
|
||||
}
|
||||
|
||||
pub async fn import_post(
|
||||
config: &Config,
|
||||
db_client: &mut impl GenericClient,
|
||||
object_id: String,
|
||||
object_received: Option<Object>,
|
||||
) -> Result<Post, ImportError> {
|
||||
let instance = config.instance();
|
||||
let media_dir = config.media_dir();
|
||||
let mut maybe_object_id_to_fetch = Some(object_id);
|
||||
let mut maybe_object = object_received;
|
||||
let mut objects = vec![];
|
||||
let mut redirects: HashMap<String, String> = HashMap::new();
|
||||
let mut posts = vec![];
|
||||
|
||||
// Fetch ancestors by going through inReplyTo references
|
||||
// TODO: fetch replies too
|
||||
#[allow(clippy::while_let_loop)]
|
||||
loop {
|
||||
let object_id = match maybe_object_id_to_fetch {
|
||||
Some(object_id) => {
|
||||
if parse_object_id(&instance.url(), &object_id).is_ok() {
|
||||
// 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
|
||||
if objects.len() == 0 {
|
||||
// Return post corresponding to initial object ID
|
||||
return Ok(post);
|
||||
};
|
||||
break;
|
||||
},
|
||||
Err(DatabaseError::NotFound(_)) => (),
|
||||
Err(other_error) => return Err(other_error.into()),
|
||||
};
|
||||
object_id
|
||||
},
|
||||
None => {
|
||||
// No object to fetch
|
||||
break;
|
||||
},
|
||||
};
|
||||
let object = match maybe_object {
|
||||
Some(object) => object,
|
||||
None => {
|
||||
let object = fetch_object(&instance, &object_id).await
|
||||
.map_err(|err| {
|
||||
log::warn!("{}", err);
|
||||
ValidationError("failed to fetch object")
|
||||
})?;
|
||||
log::info!("fetched object {}", object.id);
|
||||
object
|
||||
},
|
||||
};
|
||||
if object.id != object_id {
|
||||
// ID of fetched object doesn't match requested ID
|
||||
// Add IDs to the map of redirects
|
||||
redirects.insert(object_id, object.id.clone());
|
||||
maybe_object_id_to_fetch = Some(object.id.clone());
|
||||
// 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 = None;
|
||||
objects.push(object);
|
||||
};
|
||||
}
|
||||
let initial_object_id = objects[0].id.clone();
|
||||
|
||||
// Objects are ordered according to their place in reply tree,
|
||||
// starting with the root
|
||||
objects.reverse();
|
||||
for object in objects {
|
||||
let post = handle_note(
|
||||
db_client,
|
||||
&instance,
|
||||
&media_dir,
|
||||
object,
|
||||
&redirects,
|
||||
).await?;
|
||||
posts.push(post);
|
||||
}
|
||||
|
||||
let initial_post = posts.into_iter()
|
||||
.find(|post| post.object_id.as_ref() == Some(&initial_object_id))
|
||||
.unwrap();
|
||||
Ok(initial_post)
|
||||
}
|
||||
|
||||
fn require_actor_signature(actor_id: &str, signer_id: &str)
|
||||
-> Result<(), HttpError>
|
||||
{
|
||||
|
|
|
@ -3,8 +3,10 @@ use tokio_postgres::GenericClient;
|
|||
use url::Url;
|
||||
|
||||
use crate::activitypub::actor::ActorAddress;
|
||||
use crate::activitypub::receiver::import_post;
|
||||
use crate::activitypub::fetcher::helpers::import_profile_by_actor_address;
|
||||
use crate::activitypub::fetcher::helpers::{
|
||||
import_post,
|
||||
import_profile_by_actor_address,
|
||||
};
|
||||
use crate::config::Config;
|
||||
use crate::errors::{ValidationError, HttpError};
|
||||
use crate::mastodon_api::accounts::types::Account;
|
||||
|
|
Loading…
Reference in a new issue