ceres: a small planet in a giant solar system
32
fork

Configure Feed

Select the types of activity you want to include in your feed.

get_profiles

+101 -87
+101 -87
src/server/xrpc/app_bsky_actor.rs
··· 11 11 use jacquard::{ 12 12 IntoStatic, 13 13 prelude::IdentityResolver, 14 - types::{datetime::Datetime, did::Did, uri::UriValue}, 14 + types::{datetime::Datetime, ident::AtIdentifier, uri::UriValue}, 15 15 }; 16 + use jacquard_api::app_bsky::actor::get_profiles::{GetProfilesOutput, GetProfilesRequest}; 16 17 use jacquard_api::app_bsky::actor::{ 17 18 PreferencesItem, ProfileViewDetailed, 18 19 get_preferences::{GetPreferencesOutput, GetPreferencesRequest}, ··· 23 24 use jacquard_axum::{ExtractXrpc, IntoRouter, service_auth::ExtractOptionalServiceAuth}; 24 25 use log::info; 25 26 26 - pub async fn get_profile( 27 - State(state): State<AppState>, 28 - ExtractOptionalServiceAuth(auth): ExtractOptionalServiceAuth, 29 - ExtractXrpc(req): ExtractXrpc<GetProfileRequest>, 30 - ) -> Result<Json<GetProfileOutput<'static>>, XrpcErrorResponse> { 31 - info!("get_profile actor={}", req.actor.as_ref()); 32 - let did = match req.actor { 33 - jacquard::types::ident::AtIdentifier::Did(did) => did, 34 - jacquard::types::ident::AtIdentifier::Handle(handle) => state 35 - .resolver 36 - .resolve_handle(&handle) 37 - .await 38 - .map_err(|err| { 39 - log::error!("Error resolving the handle to a did for: {handle}"); 40 - log::error!("{err}"); 41 - XrpcErrorResponse::internal_server_error() 42 - })?, 27 + async fn resolve_profile_view( 28 + state: &AppState, 29 + actor: AtIdentifier<'_>, 30 + ) -> Result<ProfileViewDetailed<'static>, XrpcErrorResponse> { 31 + let did = match actor { 32 + AtIdentifier::Did(did) => did.into_static(), 33 + AtIdentifier::Handle(handle) => { 34 + state 35 + .resolver 36 + .resolve_handle(&handle) 37 + .await 38 + .map_err(|err| { 39 + log::error!("Error resolving the handle to a did for: {handle}"); 40 + log::error!("{err}"); 41 + XrpcErrorResponse::internal_server_error() 42 + })? 43 + } 43 44 }; 45 + 44 46 let requested_did_doc = state.resolver.resolve_did_doc(&did).await.map_err(|err| { 45 47 log::error!("{err}"); 46 48 XrpcErrorResponse::internal_server_error() ··· 80 82 XrpcErrorResponse::internal_server_error() 81 83 })?; 82 84 83 - // if let Some(auth) = auth { 84 - // storage::backfill_queue::enqueue( 85 - // &state.db, 86 - // SystemTime::now(), 87 - // &BackfillJob { 88 - // did: auth.did().to_string(), 89 - // pds_host: "idk".to_string(), 90 - // cursor: None, 91 - // retry_count: 0, 92 - // reason: "".to_string(), 93 - // }, 94 - // ) 95 - // .map_err(|err| { 96 - // log::error!("{err}"); 97 - // XrpcErrorResponse::internal_server_error() 98 - // })?; 99 - // } 85 + let avatar = profile_record 86 + .avatar 87 + .map(|blob_ref| { 88 + UriValue::new_owned(format!( 89 + "{pds_url}/xrpc/com.atproto.sync.getBlob?did={did}&cid={cid}", 90 + cid = blob_ref.blob().cid() 91 + )) 92 + }) 93 + .transpose() 94 + .map_err(|err| { 95 + log::error!("avatar uri: {err}"); 96 + XrpcErrorResponse::internal_server_error() 97 + })?; 100 98 101 - // info!("{:?}", auth); 102 - let profile = GetProfileOutput { 103 - value: ProfileViewDetailed { 104 - associated: None, 105 - avatar: profile_record 106 - .avatar 107 - .map(|blob_ref| { 108 - UriValue::new_owned(format!( 109 - "{pds_url}/xrpc/com.atproto.sync.getBlob?did={did}&cid={cid}", 110 - cid = blob_ref.blob().cid() 111 - )) 112 - }) 113 - .transpose() 114 - .map_err(|err| { 115 - log::error!("avatar uri: {err}"); 116 - XrpcErrorResponse::internal_server_error() 117 - })?, 118 - banner: profile_record 119 - .banner 120 - .map(|blob_ref| { 121 - UriValue::new_owned(format!( 122 - "{pds_url}/xrpc/com.atproto.sync.getBlob?did={did}&cid={cid}", 123 - cid = blob_ref.blob().cid() 124 - )) 125 - }) 126 - .transpose() 127 - .map_err(|err| { 128 - log::error!("banner uri: {err}"); 129 - XrpcErrorResponse::internal_server_error() 130 - })?, 131 - created_at: profile_record.created_at, 132 - debug: None, 133 - description: profile_record.description, 134 - did: did, 135 - display_name: profile_record.display_name, 136 - followers_count: Some(1234), 137 - follows_count: Some(56), 138 - handle: handle, 139 - indexed_at: Some(Datetime::now()), 140 - joined_via_starter_pack: None, 141 - labels: None, 142 - pinned_post: profile_record.pinned_post, 143 - posts_count: Some(42), 144 - pronouns: profile_record.pronouns, 145 - status: None, 146 - verification: None, 147 - viewer: None, 148 - website: profile_record.website, 149 - extra_data: Default::default(), 150 - }, 99 + let banner = profile_record 100 + .banner 101 + .map(|blob_ref| { 102 + UriValue::new_owned(format!( 103 + "{pds_url}/xrpc/com.atproto.sync.getBlob?did={did}&cid={cid}", 104 + cid = blob_ref.blob().cid() 105 + )) 106 + }) 107 + .transpose() 108 + .map_err(|err| { 109 + log::error!("banner uri: {err}"); 110 + XrpcErrorResponse::internal_server_error() 111 + })?; 112 + 113 + Ok(ProfileViewDetailed { 114 + associated: None, 115 + avatar, 116 + banner, 117 + created_at: profile_record.created_at, 118 + debug: None, 119 + description: profile_record.description, 120 + did, 121 + display_name: profile_record.display_name, 122 + followers_count: Some(67), 123 + follows_count: Some(67), 124 + handle, 125 + indexed_at: Some(Datetime::now()), 126 + joined_via_starter_pack: None, 127 + labels: None, 128 + pinned_post: profile_record.pinned_post, 129 + posts_count: None, 130 + pronouns: profile_record.pronouns, 131 + status: None, 132 + verification: None, 133 + viewer: None, 134 + website: profile_record.website, 151 135 extra_data: Default::default(), 152 - }; 136 + }) 137 + } 153 138 154 - Ok(profile.into()) 139 + pub async fn get_profile( 140 + State(state): State<AppState>, 141 + ExtractOptionalServiceAuth(_auth): ExtractOptionalServiceAuth, 142 + ExtractXrpc(req): ExtractXrpc<GetProfileRequest>, 143 + ) -> Result<Json<GetProfileOutput<'static>>, XrpcErrorResponse> { 144 + info!("get_profile actor={}", req.actor.as_ref()); 145 + let value = resolve_profile_view(&state, req.actor).await?; 146 + Ok(Json(GetProfileOutput { 147 + value, 148 + extra_data: Default::default(), 149 + })) 150 + } 151 + 152 + pub async fn get_profiles( 153 + State(state): State<AppState>, 154 + ExtractOptionalServiceAuth(_auth): ExtractOptionalServiceAuth, 155 + ExtractXrpc(req): ExtractXrpc<GetProfilesRequest>, 156 + ) -> Result<Json<GetProfilesOutput<'static>>, XrpcErrorResponse> { 157 + info!("get_profiles count={}", req.actors.len()); 158 + let mut profiles = Vec::with_capacity(req.actors.len()); 159 + for actor in req.actors { 160 + profiles.push(resolve_profile_view(&state, actor).await?); 161 + } 162 + Ok(Json(GetProfilesOutput { 163 + profiles, 164 + extra_data: Default::default(), 165 + })) 155 166 } 156 167 157 168 pub async fn get_preferences( ··· 207 218 Router::<AppState>::new() 208 219 .merge(GetProfileRequest::into_router::<_, AppState, _>( 209 220 get_profile, 221 + )) 222 + .merge(GetProfilesRequest::into_router::<_, AppState, _>( 223 + get_profiles, 210 224 )) 211 225 .merge(GetPreferencesRequest::into_router::<_, AppState, _>( 212 226 get_preferences,