1 use crate::{fetcher::webfinger::webfinger_resolve_actor, ActorType};
2 use activitypub_federation::traits::ApubObject;
3 use itertools::Itertools;
4 use lemmy_api_common::utils::blocking;
5 use lemmy_db_schema::traits::ApubActor;
6 use lemmy_utils::{error::LemmyError, settings::structs::Settings};
7 use lemmy_websocket::LemmyContext;
9 pub mod post_or_comment;
11 pub mod user_or_community;
14 /// Resolve actor identifier (eg `!news@example.com`) from local database to avoid network requests.
15 /// This only works for local actors, and remote actors which were previously fetched (so it doesnt
16 /// trigger any new fetch).
17 #[tracing::instrument(skip_all)]
18 pub async fn resolve_actor_identifier<Actor, DbActor>(
20 context: &LemmyContext,
21 ) -> Result<DbActor, LemmyError>
23 Actor: ApubObject<DataType = LemmyContext, Error = LemmyError>
24 + ApubObject<DbType = DbActor>
28 for<'de2> <Actor as ApubObject>::ApubType: serde::Deserialize<'de2>,
29 DbActor: ApubActor + Send + 'static,
32 if identifier.contains('@') {
33 let (name, domain) = identifier
36 .expect("invalid query");
37 let name = name.to_string();
38 let domain = format!("{}://{}", Settings::get().get_protocol_string(), domain);
39 let actor = blocking(context.pool(), move |conn| {
40 DbActor::read_from_name_and_domain(conn, &name, &domain)
46 // Fetch the actor from its home instance using webfinger
47 let id = webfinger_resolve_actor::<Actor>(identifier, context, &mut 0).await?;
48 let actor: DbActor = blocking(context.pool(), move |conn| {
49 DbActor::read_from_apub_id(conn, &id)
52 .expect("actor exists as we fetched just before");
58 let identifier = identifier.to_string();
60 blocking(context.pool(), move |conn| {
61 DbActor::read_from_name(conn, &identifier)