2 fetcher::{fetch::fetch_remote_object, is_deleted, should_refetch_actor},
3 objects::{person::Person as ApubPerson, FromApub},
6 use diesel::result::Error::NotFound;
7 use lemmy_api_common::blocking;
8 use lemmy_db_queries::{source::person::Person_, ApubObject};
9 use lemmy_db_schema::source::person::Person;
10 use lemmy_utils::LemmyError;
11 use lemmy_websocket::LemmyContext;
15 /// Get a person from its apub ID.
17 /// If it exists locally and `!should_refetch_actor()`, it is returned directly from the database.
18 /// Otherwise it is fetched from the remote instance, stored and returned.
19 pub async fn get_or_fetch_and_upsert_person(
21 context: &LemmyContext,
22 recursion_counter: &mut i32,
23 ) -> Result<Person, LemmyError> {
24 let apub_id_owned = apub_id.to_owned();
25 let person = blocking(context.pool(), move |conn| {
26 Person::read_from_apub_id(conn, &apub_id_owned.into())
31 // If its older than a day, re-fetch it
32 Ok(u) if !u.local && should_refetch_actor(u.last_refreshed_at) => {
33 debug!("Fetching and updating from remote person: {}", apub_id);
35 fetch_remote_object::<ApubPerson>(context.client(), apub_id, recursion_counter).await;
37 if is_deleted(&person) {
38 // TODO: use Person::update_deleted() once implemented
39 blocking(context.pool(), move |conn| {
40 Person::delete_account(conn, u.id)
43 return Err(anyhow!("Person was deleted by remote instance").into());
44 } else if person.is_err() {
48 let person = Person::from_apub(&person?, context, apub_id, recursion_counter).await?;
50 let person_id = person.id;
51 blocking(context.pool(), move |conn| {
52 Person::mark_as_updated(conn, person_id)
60 debug!("Fetching and creating remote person: {}", apub_id);
62 fetch_remote_object::<ApubPerson>(context.client(), apub_id, recursion_counter).await?;
64 let person = Person::from_apub(&person, context, apub_id, recursion_counter).await?;
68 Err(e) => Err(e.into()),