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.

chore: clippy and formatting

Mia 006eb4a3 0c46bb0a

+20 -21
+1 -1
consumer/src/db/gates.rs
··· 152 152 }) 153 153 .collect::<Vec<_>>(); 154 154 155 - let allow: HashSet<_> = HashSet::from_iter(allow.into_iter().map(|v| v.as_str())); 155 + let allow: HashSet<_> = HashSet::from_iter(allow.iter().map(|v| v.as_str())); 156 156 157 157 if allow.contains(THREADGATE_RULE_FOLLOWER) && !dids.is_empty() { 158 158 let current_dids: Vec<_> = dids.iter().collect();
+2 -2
parakeet/src/cache.rs
··· 29 29 type Val = V; 30 30 31 31 async fn get(&mut self, key: &Self::Key) -> Option<Self::Val> { 32 - let res: Option<Vec<u8>> = redis::AsyncCommands::get(&mut self.conn, &key).await.ok()?; 32 + let res: Option<Vec<u8>> = redis::AsyncCommands::get(&mut self.conn, key).await.ok()?; 33 33 34 34 match serde_ipld_dagcbor::from_slice(&res?) { 35 35 Ok(v) => Some(v), ··· 57 57 } 58 58 59 59 async fn remove(&mut self, key: &Self::Key) -> Option<Self::Val> { 60 - let res: Option<Vec<u8>> = redis::AsyncCommands::get_del(&mut self.conn, &key) 60 + let res: Option<Vec<u8>> = redis::AsyncCommands::get_del(&mut self.conn, key) 61 61 .await 62 62 .ok()?; 63 63
+2 -2
parakeet/src/db.rs
··· 1 1 use diesel::prelude::*; 2 2 use diesel::sql_types::{Array, Bool, Integer, Nullable, Text}; 3 3 use diesel_async::{AsyncPgConnection, RunQueryDsl}; 4 - use tracing::instrument; 5 - use parakeet_db::{schema, types}; 6 4 use parakeet_db::models::TextArray; 5 + use parakeet_db::{schema, types}; 6 + use tracing::instrument; 7 7 8 8 #[instrument(skip_all)] 9 9 pub async fn get_actor_status(
+6 -5
parakeet/src/hydration/starter_packs.rs
··· 97 97 let creator = self.hydrate_profile_basic(sp.owner.clone()).await?; 98 98 let list = self.hydrate_list_basic(sp.list.clone()).await; 99 99 100 - let feeds = sp 101 - .feeds 102 - .clone() 103 - .unwrap_or_default(); 104 - let feeds = self.hydrate_feedgens(feeds.into()).await.into_values().collect(); 100 + let feeds = sp.feeds.clone().unwrap_or_default(); 101 + let feeds = self 102 + .hydrate_feedgens(feeds.into()) 103 + .await 104 + .into_values() 105 + .collect(); 105 106 106 107 Some(build_spview(sp, creator, labels, list, feeds)) 107 108 }
+4 -4
parakeet/src/loaders.rs
··· 64 64 ) -> Dataloaders { 65 65 Dataloaders { 66 66 embed: new_plc_loader(EmbedLoader(pool.clone()), &rc, "embed", 3600), 67 - feedgen: new_plc_loader(FeedGenLoader(pool.clone(), idxc.clone()), &rc, "feedgen", 600), 67 + feedgen: new_plc_loader(FeedGenLoader(pool.clone()), &rc, "feedgen", 600), 68 68 handle: new_plc_loader(HandleLoader(pool.clone()), &rc, "handle", 60), 69 69 label: LabelLoader(pool.clone()), // CARE: never cache this. 70 - labeler: new_plc_loader(LabelServiceLoader(pool.clone(), idxc.clone()), &rc, "labeler", 600), 70 + labeler: new_plc_loader(LabelServiceLoader(pool.clone()), &rc, "labeler", 600), 71 71 like: NonCachedLoader::new(LikeLoader(idxc.clone())), 72 72 like_state: LikeRecordLoader(pool.clone()), 73 73 list: new_plc_loader(ListLoader(pool.clone()), &rc, "list", 600), ··· 350 350 } 351 351 } 352 352 353 - pub struct FeedGenLoader(Pool<AsyncPgConnection>, parakeet_index::Client); 353 + pub struct FeedGenLoader(Pool<AsyncPgConnection>); 354 354 impl BatchFn<String, models::FeedGen> for FeedGenLoader { 355 355 #[instrument(name = "FeedGenLoader", skip_all)] 356 356 async fn load(&mut self, keys: &[String]) -> HashMap<String, models::FeedGen> { ··· 572 572 } 573 573 } 574 574 575 - pub struct LabelServiceLoader(Pool<AsyncPgConnection>, parakeet_index::Client); 575 + pub struct LabelServiceLoader(Pool<AsyncPgConnection>); 576 576 type LabelServiceLoaderRet = (models::LabelerService, Vec<models::LabelDefinition>); 577 577 impl BatchFn<String, LabelServiceLoaderRet> for LabelServiceLoader { 578 578 #[instrument(name = "LabelServiceLoader", skip_all)]
+1 -1
parakeet/src/xrpc/app_bsky/bookmark.rs
··· 36 36 rkey: None, 37 37 subject: &form.uri, 38 38 subject_cid: Some(form.cid), 39 - subject_type: &parts[1], 39 + subject_type: parts[1], 40 40 tags: vec![], 41 41 }; 42 42
+3 -2
parakeet/src/xrpc/app_bsky/feed/posts.rs
··· 161 161 162 162 #[derive(Debug, Default, Eq, PartialEq, Deserialize)] 163 163 #[serde(rename_all = "snake_case")] 164 + #[allow(clippy::enum_variant_names)] 164 165 pub enum GetAuthorFeedFilter { 165 166 #[default] 166 167 PostsWithReplies, ··· 199 200 if let Some(psr) = crate::db::get_profile_state(&mut conn, &auth.0, &did).await? { 200 201 if psr.blocked.unwrap_or_default() { 201 202 // they block us 202 - return Err(Error::new(StatusCode::BAD_REQUEST, "BlockedByActor", None)) 203 + return Err(Error::new(StatusCode::BAD_REQUEST, "BlockedByActor", None)); 203 204 } else if psr.blocking.is_some() { 204 205 // we block them 205 - return Err(Error::new(StatusCode::BAD_REQUEST, "BlockedActor", None)) 206 + return Err(Error::new(StatusCode::BAD_REQUEST, "BlockedActor", None)); 206 207 } 207 208 } 208 209 }
+1 -4
parakeet/src/xrpc/app_bsky/unspecced/thread_v2.rs
··· 253 253 .hydrate_posts(reply_uris) 254 254 .await 255 255 .into_iter() 256 - .filter(|(_, post)| match &post.author.viewer { 257 - Some(viewer) if viewer.blocked_by || viewer.blocking.is_some() => false, 258 - _ => true, 259 - }) 256 + .filter(|(_, post)| matches!(&post.author.viewer, Some(viewer) if viewer.blocked_by || viewer.blocking.is_some())) 260 257 .map(|(uri, post)| { 261 258 let post = ThreadItemPost { 262 259 post,