diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b568a2..2c5718d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Prevent `delete-extraneous-posts` command from removing locally-linked posts. - Make webfinger response compatible with GNU Social account lookup. - Prefer `Group` actor when doing webfinger query on Lemmy server. +- Fetch missing profiles before doing follower migration. ## [1.14.0] - 2023-02-22 diff --git a/src/activitypub/fetcher/helpers.rs b/src/activitypub/fetcher/helpers.rs index 22c6966..338fa76 100644 --- a/src/activitypub/fetcher/helpers.rs +++ b/src/activitypub/fetcher/helpers.rs @@ -136,6 +136,7 @@ pub async fn import_profile_by_actor_address( Ok(profile) } +// Works with local profiles pub async fn get_or_import_profile_by_actor_address( db_client: &impl DatabaseClient, instance: &Instance, diff --git a/src/mastodon_api/settings/helpers.rs b/src/mastodon_api/settings/helpers.rs index e0f68f1..1d5d11f 100644 --- a/src/mastodon_api/settings/helpers.rs +++ b/src/mastodon_api/settings/helpers.rs @@ -20,7 +20,6 @@ use crate::errors::ValidationError; use crate::mastodon_api::accounts::helpers::follow_or_create_request; use crate::models::{ posts::mentions::mention_to_address, - profiles::queries::get_profile_by_acct, profiles::types::DbActorProfile, relationships::queries::{ follow, @@ -128,14 +127,31 @@ pub async fn move_followers_task( ) -> Result<(), anyhow::Error> { let db_client = &mut **get_database_client(db_pool).await?; let instance = config.instance(); - let mut followers = vec![]; + let mut remote_followers = vec![]; for follower_address in address_list { - let follower_acct = follower_address.acct(&instance.hostname()); - // TODO: fetch unknown profiles - let follower = get_profile_by_acct(db_client, &follower_acct).await?; + let follower = match get_or_import_profile_by_actor_address( + db_client, + &instance, + &config.media_dir(), + &follower_address, + ).await { + Ok(profile) => profile, + Err(error @ ( + HandlerError::FetchError(_) | + HandlerError::DatabaseError(DatabaseError::NotFound(_)) + )) => { + log::warn!( + "failed to import profile {}: {}", + follower_address, + error, + ); + continue; + }, + Err(other_error) => return Err(other_error.into()), + }; if let Some(remote_actor) = follower.actor_json { // Add remote actor to activity recipients list - followers.push(remote_actor); + remote_followers.push(remote_actor); } else { // Immediately move local followers (only if alias can be verified) if let Some(ref from_profile) = maybe_from_profile { @@ -170,7 +186,7 @@ pub async fn move_followers_task( &instance, ¤t_user, from_actor_id, - followers, + remote_followers, None, ).enqueue(db_client).await?; Ok(())