A Wrapped / Replay like for teal.fm and rocksky.app (currently on hiatus)
at main 64 lines 2.2 kB view raw
1use jacquard_api::app_bsky::actor::ProfileViewBasic; 2use jacquard_api::app_bsky::actor::get_profile::GetProfile; 3use jacquard_common::types::did::Did; 4use jacquard_common::types::ident::AtIdentifier; 5use jacquard_common::xrpc::XrpcExt; 6use jacquard_identity::JacquardResolver; 7use jacquard_identity::resolver::{HandleStep, IdentityResolver, PlcSource, ResolverOptions}; 8use std::sync::LazyLock; 9use tokio::task::{JoinHandle, spawn_blocking}; 10use crate::{SqliteConnection, SqlitePool}; 11 12const BSKY_PUBLIC_API: &str = "https://public.api.bsky.app"; 13static CLIENT: LazyLock<reqwest::Client> = LazyLock::new(reqwest::Client::new); 14static RESOLVER: LazyLock<JacquardResolver> = LazyLock::new(|| { 15 JacquardResolver::new( 16 CLIENT.clone(), 17 ResolverOptions { 18 plc_source: PlcSource::slingshot_default(), 19 handle_order: vec![HandleStep::PdsResolveHandle], 20 ..Default::default() 21 }, 22 ) 23}); 24 25pub fn db_call<F, R>(db: &SqlitePool, func: F) -> JoinHandle<eyre::Result<R>> 26where 27 F: Fn(SqliteConnection) -> rusqlite::Result<R> + Send + Sync + 'static, 28 R: Send + Sync + 'static, 29{ 30 let conn = db.get(); 31 spawn_blocking(move || Ok(func(conn?)?)) 32} 33 34pub async fn get_public_profile(did: &Did<'_>) -> eyre::Result<ProfileViewBasic<'static>> { 35 let resp = CLIENT 36 .xrpc(BSKY_PUBLIC_API.parse()?) 37 .send(&GetProfile::new().actor(AtIdentifier::raw(did)).build()) 38 .await?; 39 40 let out = resp.into_output()?; 41 42 Ok(ProfileViewBasic { 43 associated: out.value.associated, 44 avatar: out.value.avatar, 45 created_at: out.value.created_at, 46 debug: out.value.debug, 47 did: out.value.did, 48 display_name: out.value.display_name, 49 handle: out.value.handle, 50 labels: out.value.labels, 51 pronouns: out.value.pronouns, 52 status: out.value.status, 53 verification: out.value.verification, 54 viewer: out.value.viewer, 55 extra_data: out.value.extra_data, 56 }) 57} 58 59pub async fn resolve_atid(atid: AtIdentifier<'_>) -> eyre::Result<Did<'_>> { 60 match atid { 61 AtIdentifier::Did(did) => Ok(did), 62 AtIdentifier::Handle(handle) => Ok(RESOLVER.resolve_handle(&handle).await?), 63 } 64}