Refactor import_post function

This commit is contained in:
silverpill 2023-03-26 00:52:09 +00:00
parent 5e1f441e8b
commit b85a0fb7ac
6 changed files with 59 additions and 36 deletions

View file

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use mitra_config::{Config, Instance}; use mitra_config::Instance;
use crate::activitypub::{ use crate::activitypub::{
actors::helpers::{create_remote_profile, update_remote_profile}, actors::helpers::{create_remote_profile, update_remote_profile},
@ -187,12 +187,12 @@ pub async fn get_post_by_object_id(
const RECURSION_DEPTH_MAX: usize = 50; const RECURSION_DEPTH_MAX: usize = 50;
pub async fn import_post( pub async fn import_post(
config: &Config,
db_client: &mut impl DatabaseClient, db_client: &mut impl DatabaseClient,
instance: &Instance,
storage: &MediaStorage,
object_id: String, object_id: String,
object_received: Option<Object>, object_received: Option<Object>,
) -> Result<Post, HandlerError> { ) -> Result<Post, HandlerError> {
let instance = config.instance();
if parse_local_object_id(&instance.url(), &object_id).is_ok() { if parse_local_object_id(&instance.url(), &object_id).is_ok() {
return Err(HandlerError::LocalObject); return Err(HandlerError::LocalObject);
}; };
@ -250,7 +250,7 @@ pub async fn import_post(
// TODO: create tombstone // TODO: create tombstone
return Err(FetchError::RecursionError.into()); return Err(FetchError::RecursionError.into());
}; };
let object = fetch_object(&instance, &object_id).await let object = fetch_object(instance, &object_id).await
.map_err(|err| { .map_err(|err| {
log::warn!("{}", err); log::warn!("{}", err);
ValidationError("failed to fetch object") ValidationError("failed to fetch object")
@ -287,8 +287,9 @@ pub async fn import_post(
objects.reverse(); objects.reverse();
for object in objects { for object in objects {
let post = handle_note( let post = handle_note(
config,
db_client, db_client,
instance,
storage,
object, object,
&redirects, &redirects,
).await?; ).await?;

View file

@ -52,20 +52,28 @@ pub async fn handle_announce(
Err(DatabaseError::NotFound(_)) => (), Err(DatabaseError::NotFound(_)) => (),
Err(other_error) => return Err(other_error.into()), Err(other_error) => return Err(other_error.into()),
}; };
let instance = config.instance();
let storage = MediaStorage::from(config);
let author = get_or_import_profile_by_actor_id( let author = get_or_import_profile_by_actor_id(
db_client, db_client,
&config.instance(), &instance,
&MediaStorage::from(config), &storage,
&activity.actor, &activity.actor,
).await?; ).await?;
let post_id = match parse_local_object_id( let post_id = match parse_local_object_id(
&config.instance_url(), &instance.url(),
&activity.object, &activity.object,
) { ) {
Ok(post_id) => post_id, Ok(post_id) => post_id,
Err(_) => { Err(_) => {
// Try to get remote post // Try to get remote post
let post = import_post(config, db_client, activity.object, None).await?; let post = import_post(
db_client,
&instance,
&storage,
activity.object,
None,
).await?;
post.id post.id
}, },
}; };

View file

@ -126,13 +126,12 @@ fn is_gnu_social_link(author_id: &str, attachment: &Attachment) -> bool {
} }
pub async fn get_object_attachments( pub async fn get_object_attachments(
config: &Config,
db_client: &impl DatabaseClient, db_client: &impl DatabaseClient,
instance: &Instance,
storage: &MediaStorage,
object: &Object, object: &Object,
author: &DbActorProfile, author: &DbActorProfile,
) -> Result<(Vec<Uuid>, Vec<String>), HandlerError> { ) -> Result<(Vec<Uuid>, Vec<String>), HandlerError> {
let instance = config.instance();
let media_dir = config.media_dir();
let mut attachments = vec![]; let mut attachments = vec![];
let mut unprocessed = vec![]; let mut unprocessed = vec![];
if let Some(ref value) = object.attachment { if let Some(ref value) = object.attachment {
@ -160,11 +159,11 @@ pub async fn get_object_attachments(
let attachment_url = attachment.url let attachment_url = attachment.url
.ok_or(ValidationError("attachment URL is missing"))?; .ok_or(ValidationError("attachment URL is missing"))?;
let (file_name, file_size, maybe_media_type) = match fetch_file( let (file_name, file_size, maybe_media_type) = match fetch_file(
&instance, instance,
&attachment_url, &attachment_url,
attachment.media_type.as_deref(), attachment.media_type.as_deref(),
config.limits.media.file_size_limit, storage.file_size_limit,
&media_dir, &storage.media_dir,
).await { ).await {
Ok(file) => file, Ok(file) => file,
Err(FetchError::FileTooLarge) => { Err(FetchError::FileTooLarge) => {
@ -331,13 +330,12 @@ pub async fn handle_emoji(
} }
pub async fn get_object_tags( pub async fn get_object_tags(
config: &Config,
db_client: &mut impl DatabaseClient, db_client: &mut impl DatabaseClient,
instance: &Instance,
storage: &MediaStorage,
object: &Object, object: &Object,
redirects: &HashMap<String, String>, redirects: &HashMap<String, String>,
) -> Result<(Vec<Uuid>, Vec<String>, Vec<Uuid>, Vec<Uuid>), HandlerError> { ) -> Result<(Vec<Uuid>, Vec<String>, Vec<Uuid>, Vec<Uuid>), HandlerError> {
let instance = config.instance();
let storage = MediaStorage::from(config);
let mut mentions = vec![]; let mut mentions = vec![];
let mut hashtags = vec![]; let mut hashtags = vec![];
let mut links = vec![]; let mut links = vec![];
@ -381,8 +379,8 @@ pub async fn get_object_tags(
// but also can be actor URL (profile link). // but also can be actor URL (profile link).
match get_or_import_profile_by_actor_id( match get_or_import_profile_by_actor_id(
db_client, db_client,
&instance, instance,
&storage, storage,
&href, &href,
).await { ).await {
Ok(profile) => { Ok(profile) => {
@ -411,8 +409,8 @@ pub async fn get_object_tags(
if let Ok(actor_address) = ActorAddress::from_mention(&tag_name) { if let Ok(actor_address) = ActorAddress::from_mention(&tag_name) {
let profile = match get_or_import_profile_by_actor_address( let profile = match get_or_import_profile_by_actor_address(
db_client, db_client,
&instance, instance,
&storage, storage,
&actor_address, &actor_address,
).await { ).await {
Ok(profile) => profile, Ok(profile) => profile,
@ -467,8 +465,8 @@ pub async fn get_object_tags(
}; };
match handle_emoji( match handle_emoji(
db_client, db_client,
&instance, instance,
&storage, storage,
tag_value, tag_value,
).await? { ).await? {
Some(emoji) => { Some(emoji) => {
@ -527,13 +525,12 @@ fn get_object_visibility(
} }
pub async fn handle_note( pub async fn handle_note(
config: &Config,
db_client: &mut impl DatabaseClient, db_client: &mut impl DatabaseClient,
instance: &Instance,
storage: &MediaStorage,
object: Object, object: Object,
redirects: &HashMap<String, String>, redirects: &HashMap<String, String>,
) -> Result<Post, HandlerError> { ) -> Result<Post, HandlerError> {
let instance = config.instance();
let storage = MediaStorage::from(config);
match object.object_type.as_str() { match object.object_type.as_str() {
NOTE => (), NOTE => (),
ARTICLE | EVENT | QUESTION | PAGE | VIDEO => { ARTICLE | EVENT | QUESTION | PAGE | VIDEO => {
@ -548,8 +545,8 @@ pub async fn handle_note(
let author_id = get_object_attributed_to(&object)?; let author_id = get_object_attributed_to(&object)?;
let author = get_or_import_profile_by_actor_id( let author = get_or_import_profile_by_actor_id(
db_client, db_client,
&instance, instance,
&storage, storage,
&author_id, &author_id,
).await.map_err(|err| { ).await.map_err(|err| {
log::warn!("failed to import {} ({})", author_id, err); log::warn!("failed to import {} ({})", author_id, err);
@ -563,8 +560,9 @@ pub async fn handle_note(
content += &create_content_link(object_url); content += &create_content_link(object_url);
}; };
let (attachments, unprocessed) = get_object_attachments( let (attachments, unprocessed) = get_object_attachments(
config,
db_client, db_client,
instance,
storage,
&object, &object,
&author, &author,
).await?; ).await?;
@ -576,8 +574,9 @@ pub async fn handle_note(
}; };
let (mentions, hashtags, links, emojis) = get_object_tags( let (mentions, hashtags, links, emojis) = get_object_tags(
config,
db_client, db_client,
instance,
storage,
&object, &object,
redirects, redirects,
).await?; ).await?;
@ -654,7 +653,13 @@ pub async fn handle_create(
// Most likely it's a forwarded reply. // Most likely it's a forwarded reply.
None None
}; };
import_post(config, db_client, object_id, object_received).await?; import_post(
db_client,
&config.instance(),
&MediaStorage::from(config),
object_id,
object_received,
).await?;
Ok(Some(NOTE)) Ok(Some(NOTE))
} }

View file

@ -56,9 +56,12 @@ async fn handle_update_note(
let object_url = get_object_url(&object)?; let object_url = get_object_url(&object)?;
content += &create_content_link(object_url); content += &create_content_link(object_url);
}; };
let instance = config.instance();
let storage = MediaStorage::from(config);
let (attachments, unprocessed) = get_object_attachments( let (attachments, unprocessed) = get_object_attachments(
config,
db_client, db_client,
&instance,
&storage,
&object, &object,
&post.author, &post.author,
).await?; ).await?;
@ -69,8 +72,9 @@ async fn handle_update_note(
return Err(ValidationError("post is empty").into()); return Err(ValidationError("post is empty").into());
}; };
let (mentions, hashtags, links, emojis) = get_object_tags( let (mentions, hashtags, links, emojis) = get_object_tags(
config,
db_client, db_client,
&instance,
&storage,
&object, &object,
&HashMap::new(), &HashMap::new(),
).await?; ).await?;

View file

@ -154,8 +154,10 @@ async fn find_post_by_url(
db_client: &mut impl DatabaseClient, db_client: &mut impl DatabaseClient,
url: &str, url: &str,
) -> Result<Option<Post>, DatabaseError> { ) -> Result<Option<Post>, DatabaseError> {
let instance = config.instance();
let storage = MediaStorage::from(config);
let maybe_post = match parse_local_object_id( let maybe_post = match parse_local_object_id(
&config.instance_url(), &instance.url(),
url, url,
) { ) {
Ok(post_id) => { Ok(post_id) => {
@ -168,8 +170,9 @@ async fn find_post_by_url(
}, },
Err(_) => { Err(_) => {
match import_post( match import_post(
config,
db_client, db_client,
&instance,
&storage,
url.to_string(), url.to_string(),
None, None,
).await { ).await {

View file

@ -89,6 +89,7 @@ pub async fn remove_media(
pub struct MediaStorage { pub struct MediaStorage {
pub media_dir: PathBuf, pub media_dir: PathBuf,
pub file_size_limit: usize,
pub emoji_size_limit: usize, pub emoji_size_limit: usize,
} }
@ -96,6 +97,7 @@ impl From<&Config> for MediaStorage {
fn from(config: &Config) -> Self { fn from(config: &Config) -> Self {
Self { Self {
media_dir: config.media_dir(), media_dir: config.media_dir(),
file_size_limit: config.limits.media.file_size_limit,
emoji_size_limit: config.limits.media.emoji_size_limit, emoji_size_limit: config.limits.media.emoji_size_limit,
} }
} }