Parakeet is a Rust-based Bluesky AppServer aiming to implement most of the functionality required to support the Bluesky client
appview atproto bluesky rust appserver
66
fork

Configure Feed

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

feat(parakeet): really incomplete com.atproto.repo.getRecord impl

Mia cc615a8e 52c585ad

+79
+2
parakeet/src/xrpc/com_atproto/mod.rs
··· 2 2 use axum::Router; 3 3 4 4 mod identity; 5 + mod repo; 5 6 6 7 #[rustfmt::skip] 7 8 pub fn routes() -> Router<crate::GlobalState> { 8 9 Router::new() 9 10 .route("/com.atproto.identity.resolveHandle", get(identity::resolve_handle)) 11 + .route("/com.atproto.repo.getRecord", get(repo::get_record)) 10 12 }
+77
parakeet/src/xrpc/com_atproto/repo.rs
··· 1 + use crate::xrpc::check_actor_status; 2 + use crate::xrpc::error::{Error, XrpcResult}; 3 + use crate::xrpc::extract::AtpAuth; 4 + use crate::GlobalState; 5 + use axum::extract::{Query, State}; 6 + use axum::Json; 7 + use diesel::prelude::*; 8 + use diesel_async::RunQueryDsl; 9 + use parakeet_db::schema; 10 + use serde::{Deserialize, Serialize}; 11 + use serde_json::Value; 12 + 13 + #[derive(Debug, Deserialize)] 14 + pub struct GetRecordQuery { 15 + pub repo: String, 16 + pub collection: String, 17 + pub rkey: String, 18 + } 19 + 20 + #[derive(Debug, Serialize)] 21 + pub struct GetRecordRes { 22 + pub uri: String, 23 + pub cid: String, 24 + pub value: Value, 25 + } 26 + 27 + pub async fn get_record( 28 + State(state): State<GlobalState>, 29 + _maybe_auth: Option<AtpAuth>, 30 + Query(query): Query<GetRecordQuery>, 31 + ) -> XrpcResult<Json<GetRecordRes>> { 32 + let mut conn = state.pool.get().await?; 33 + 34 + check_actor_status(&mut conn, &query.repo).await?; 35 + 36 + let at_uri = format!("at://{}/{}/{}", &query.repo, &query.collection, &query.rkey); 37 + 38 + let (cid, value) = match query.collection.as_str() { 39 + "app.bsky.feed.generator" => { 40 + // we don't store the full data so this returns partial 41 + let (cid, service_did) = schema::feedgens::table 42 + .select((schema::feedgens::cid, schema::feedgens::service_did)) 43 + .find(&at_uri) 44 + .get_result::<(String, String)>(&mut conn) 45 + .await?; 46 + 47 + ( 48 + cid, 49 + serde_json::json!({ 50 + "$type": "app.bsky.feed.generator", 51 + "did": service_did, 52 + }), 53 + ) 54 + } 55 + "app.bsky.feed.post" => { 56 + schema::posts::table 57 + .select((schema::posts::cid, schema::posts::record)) 58 + .find(&at_uri) 59 + .get_result::<(String, Value)>(&mut conn) 60 + .await? 61 + } 62 + "app.bsky.graph.starterpack" => { 63 + schema::starterpacks::table 64 + .select((schema::starterpacks::cid, schema::starterpacks::record)) 65 + .find(&at_uri) 66 + .get_result::<(String, Value)>(&mut conn) 67 + .await? 68 + } 69 + _ => return Err(Error::invalid_request(None)), 70 + }; 71 + 72 + Ok(Json(GetRecordRes { 73 + uri: at_uri, 74 + cid, 75 + value, 76 + })) 77 + }