Move profile importers to fetcher::helpers module
This commit is contained in:
parent
2db43df631
commit
f7211d2a14
6 changed files with 112 additions and 94 deletions
|
@ -3,14 +3,14 @@ use std::path::Path;
|
||||||
use reqwest::Method;
|
use reqwest::Method;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
|
use crate::activitypub::activity::Object;
|
||||||
|
use crate::activitypub::actor::Actor;
|
||||||
|
use crate::activitypub::constants::ACTIVITY_CONTENT_TYPE;
|
||||||
use crate::config::Instance;
|
use crate::config::Instance;
|
||||||
use crate::http_signatures::create::{create_http_signature, SignatureError};
|
use crate::http_signatures::create::{create_http_signature, SignatureError};
|
||||||
use crate::models::profiles::types::ProfileCreateData;
|
use crate::models::profiles::types::ProfileCreateData;
|
||||||
use crate::utils::files::{save_file, FileError};
|
use crate::utils::files::{save_file, FileError};
|
||||||
use crate::webfinger::types::JsonResourceDescriptor;
|
use crate::webfinger::types::JsonResourceDescriptor;
|
||||||
use super::activity::Object;
|
|
||||||
use super::actor::Actor;
|
|
||||||
use super::constants::ACTIVITY_CONTENT_TYPE;
|
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum FetchError {
|
pub enum FetchError {
|
95
src/activitypub/fetcher/helpers.rs
Normal file
95
src/activitypub/fetcher/helpers.rs
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use tokio_postgres::GenericClient;
|
||||||
|
|
||||||
|
use crate::activitypub::actor::ActorAddress;
|
||||||
|
use crate::config::Instance;
|
||||||
|
use crate::errors::{DatabaseError, HttpError, ValidationError};
|
||||||
|
use crate::models::profiles::queries::{
|
||||||
|
get_profile_by_actor_id,
|
||||||
|
get_profile_by_acct,
|
||||||
|
create_profile,
|
||||||
|
};
|
||||||
|
use crate::models::profiles::types::DbActorProfile;
|
||||||
|
use super::fetchers::{
|
||||||
|
fetch_profile,
|
||||||
|
fetch_profile_by_actor_id,
|
||||||
|
FetchError,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum ImportError {
|
||||||
|
#[error(transparent)]
|
||||||
|
FetchError(#[from] FetchError),
|
||||||
|
|
||||||
|
#[error(transparent)]
|
||||||
|
ValidationError(#[from] ValidationError),
|
||||||
|
|
||||||
|
#[error(transparent)]
|
||||||
|
DatabaseError(#[from] DatabaseError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ImportError> for HttpError {
|
||||||
|
fn from(error: ImportError) -> Self {
|
||||||
|
match error {
|
||||||
|
ImportError::FetchError(error) => {
|
||||||
|
HttpError::ValidationError(error.to_string())
|
||||||
|
},
|
||||||
|
ImportError::ValidationError(error) => error.into(),
|
||||||
|
ImportError::DatabaseError(error) => error.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_or_fetch_profile_by_actor_id(
|
||||||
|
db_client: &impl GenericClient,
|
||||||
|
instance: &Instance,
|
||||||
|
actor_id: &str,
|
||||||
|
media_dir: &Path,
|
||||||
|
) -> Result<DbActorProfile, HttpError> {
|
||||||
|
let profile = match get_profile_by_actor_id(db_client, actor_id).await {
|
||||||
|
Ok(profile) => profile,
|
||||||
|
Err(DatabaseError::NotFound(_)) => {
|
||||||
|
let profile_data = fetch_profile_by_actor_id(
|
||||||
|
instance, actor_id, media_dir,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|err| {
|
||||||
|
log::warn!("{}", err);
|
||||||
|
ValidationError("failed to fetch actor")
|
||||||
|
})?;
|
||||||
|
log::info!("fetched profile {}", profile_data.acct);
|
||||||
|
let profile = create_profile(db_client, &profile_data).await?;
|
||||||
|
profile
|
||||||
|
},
|
||||||
|
Err(other_error) => return Err(other_error.into()),
|
||||||
|
};
|
||||||
|
Ok(profile)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fetches actor profile and saves it into database
|
||||||
|
pub async fn import_profile_by_actor_address(
|
||||||
|
db_client: &impl GenericClient,
|
||||||
|
instance: &Instance,
|
||||||
|
media_dir: &Path,
|
||||||
|
actor_address: &ActorAddress,
|
||||||
|
) -> Result<DbActorProfile, ImportError> {
|
||||||
|
let profile_data = fetch_profile(
|
||||||
|
instance,
|
||||||
|
&actor_address.username,
|
||||||
|
&actor_address.instance,
|
||||||
|
media_dir,
|
||||||
|
).await?;
|
||||||
|
if profile_data.acct != actor_address.acct() {
|
||||||
|
// Redirected to different server
|
||||||
|
match get_profile_by_acct(db_client, &profile_data.acct).await {
|
||||||
|
Ok(profile) => return Ok(profile),
|
||||||
|
Err(DatabaseError::NotFound(_)) => (),
|
||||||
|
Err(other_error) => return Err(other_error.into()),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
log::info!("fetched profile {}", profile_data.acct);
|
||||||
|
profile_data.clean()?;
|
||||||
|
let profile = create_profile(db_client, &profile_data).await?;
|
||||||
|
Ok(profile)
|
||||||
|
}
|
2
src/activitypub/fetcher/mod.rs
Normal file
2
src/activitypub/fetcher/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod fetchers;
|
||||||
|
pub mod helpers;
|
|
@ -1,12 +1,11 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use tokio_postgres::GenericClient;
|
use tokio_postgres::GenericClient;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::config::{Config, Instance};
|
use crate::config::Config;
|
||||||
use crate::database::{Pool, get_database_client};
|
use crate::database::{Pool, get_database_client};
|
||||||
use crate::errors::{ConversionError, DatabaseError, HttpError, ValidationError};
|
use crate::errors::{ConversionError, DatabaseError, HttpError, ValidationError};
|
||||||
use crate::models::attachments::queries::create_attachment;
|
use crate::models::attachments::queries::create_attachment;
|
||||||
|
@ -22,10 +21,9 @@ use crate::models::posts::types::{Post, PostCreateData, Visibility};
|
||||||
use crate::models::profiles::queries::{
|
use crate::models::profiles::queries::{
|
||||||
get_profile_by_actor_id,
|
get_profile_by_actor_id,
|
||||||
get_profile_by_acct,
|
get_profile_by_acct,
|
||||||
create_profile,
|
|
||||||
update_profile,
|
update_profile,
|
||||||
};
|
};
|
||||||
use crate::models::profiles::types::{DbActorProfile, ProfileUpdateData};
|
use crate::models::profiles::types::ProfileUpdateData;
|
||||||
use crate::models::reactions::queries::{
|
use crate::models::reactions::queries::{
|
||||||
create_reaction,
|
create_reaction,
|
||||||
get_reaction_by_activity_id,
|
get_reaction_by_activity_id,
|
||||||
|
@ -39,16 +37,18 @@ use crate::models::relationships::queries::{
|
||||||
};
|
};
|
||||||
use crate::models::users::queries::get_user_by_id;
|
use crate::models::users::queries::get_user_by_id;
|
||||||
use super::activity::{Object, Activity, create_activity_accept_follow};
|
use super::activity::{Object, Activity, create_activity_accept_follow};
|
||||||
use super::actor::{Actor, ActorAddress};
|
use super::actor::Actor;
|
||||||
use super::deliverer::deliver_activity;
|
use super::deliverer::deliver_activity;
|
||||||
use super::fetcher::{
|
use super::fetcher::fetchers::{
|
||||||
FetchError,
|
|
||||||
fetch_avatar_and_banner,
|
fetch_avatar_and_banner,
|
||||||
fetch_profile,
|
|
||||||
fetch_profile_by_actor_id,
|
|
||||||
fetch_attachment,
|
fetch_attachment,
|
||||||
fetch_object,
|
fetch_object,
|
||||||
};
|
};
|
||||||
|
use super::fetcher::helpers::{
|
||||||
|
get_or_fetch_profile_by_actor_id,
|
||||||
|
import_profile_by_actor_address,
|
||||||
|
ImportError,
|
||||||
|
};
|
||||||
use super::vocabulary::*;
|
use super::vocabulary::*;
|
||||||
|
|
||||||
fn parse_actor_id(
|
fn parse_actor_id(
|
||||||
|
@ -130,83 +130,6 @@ fn get_object_id(object: Value) -> Result<String, ValidationError> {
|
||||||
Ok(object_id)
|
Ok(object_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
|
||||||
pub enum ImportError {
|
|
||||||
#[error(transparent)]
|
|
||||||
FetchError(#[from] FetchError),
|
|
||||||
|
|
||||||
#[error(transparent)]
|
|
||||||
ValidationError(#[from] ValidationError),
|
|
||||||
|
|
||||||
#[error(transparent)]
|
|
||||||
DatabaseError(#[from] DatabaseError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ImportError> for HttpError {
|
|
||||||
fn from(error: ImportError) -> Self {
|
|
||||||
match error {
|
|
||||||
ImportError::FetchError(error) => {
|
|
||||||
HttpError::ValidationError(error.to_string())
|
|
||||||
},
|
|
||||||
ImportError::ValidationError(error) => error.into(),
|
|
||||||
ImportError::DatabaseError(error) => error.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_or_fetch_profile_by_actor_id(
|
|
||||||
db_client: &impl GenericClient,
|
|
||||||
instance: &Instance,
|
|
||||||
actor_id: &str,
|
|
||||||
media_dir: &Path,
|
|
||||||
) -> Result<DbActorProfile, HttpError> {
|
|
||||||
let profile = match get_profile_by_actor_id(db_client, actor_id).await {
|
|
||||||
Ok(profile) => profile,
|
|
||||||
Err(DatabaseError::NotFound(_)) => {
|
|
||||||
let profile_data = fetch_profile_by_actor_id(
|
|
||||||
instance, actor_id, media_dir,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map_err(|err| {
|
|
||||||
log::warn!("{}", err);
|
|
||||||
ValidationError("failed to fetch actor")
|
|
||||||
})?;
|
|
||||||
log::info!("fetched profile {}", profile_data.acct);
|
|
||||||
let profile = create_profile(db_client, &profile_data).await?;
|
|
||||||
profile
|
|
||||||
},
|
|
||||||
Err(other_error) => return Err(other_error.into()),
|
|
||||||
};
|
|
||||||
Ok(profile)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fetches actor profile and saves it into database
|
|
||||||
pub async fn import_profile_by_actor_address(
|
|
||||||
db_client: &impl GenericClient,
|
|
||||||
instance: &Instance,
|
|
||||||
media_dir: &Path,
|
|
||||||
actor_address: &ActorAddress,
|
|
||||||
) -> Result<DbActorProfile, ImportError> {
|
|
||||||
let profile_data = fetch_profile(
|
|
||||||
instance,
|
|
||||||
&actor_address.username,
|
|
||||||
&actor_address.instance,
|
|
||||||
media_dir,
|
|
||||||
).await?;
|
|
||||||
if profile_data.acct != actor_address.acct() {
|
|
||||||
// Redirected to different server
|
|
||||||
match get_profile_by_acct(db_client, &profile_data.acct).await {
|
|
||||||
Ok(profile) => return Ok(profile),
|
|
||||||
Err(DatabaseError::NotFound(_)) => (),
|
|
||||||
Err(other_error) => return Err(other_error.into()),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
log::info!("fetched profile {}", profile_data.acct);
|
|
||||||
profile_data.clean()?;
|
|
||||||
let profile = create_profile(db_client, &profile_data).await?;
|
|
||||||
Ok(profile)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn process_note(
|
pub async fn process_note(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
db_client: &mut impl GenericClient,
|
db_client: &mut impl GenericClient,
|
||||||
|
|
|
@ -6,7 +6,7 @@ use actix_web::{
|
||||||
};
|
};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
use crate::activitypub::fetcher::fetch_profile_by_actor_id;
|
use crate::activitypub::fetcher::fetchers::fetch_profile_by_actor_id;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::database::{Pool, get_database_client};
|
use crate::database::{Pool, get_database_client};
|
||||||
use crate::errors::DatabaseError;
|
use crate::errors::DatabaseError;
|
||||||
|
|
|
@ -2,10 +2,8 @@ use regex::Regex;
|
||||||
use tokio_postgres::GenericClient;
|
use tokio_postgres::GenericClient;
|
||||||
|
|
||||||
use crate::activitypub::actor::ActorAddress;
|
use crate::activitypub::actor::ActorAddress;
|
||||||
use crate::activitypub::receiver::{
|
use crate::activitypub::receiver::process_note;
|
||||||
import_profile_by_actor_address,
|
use crate::activitypub::fetcher::helpers::import_profile_by_actor_address;
|
||||||
process_note,
|
|
||||||
};
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::errors::{ValidationError, HttpError};
|
use crate::errors::{ValidationError, HttpError};
|
||||||
use crate::mastodon_api::accounts::types::Account;
|
use crate::mastodon_api::accounts::types::Account;
|
||||||
|
|
Loading…
Reference in a new issue