[WIP] A (somewhat barebones) atproto app for creating custom sites without hosting!

upload: get a list of all remote records for the site

vielle.dev 49bcaa0c 9377c5ca

verified
Changed files
+63 -3
upload
src
+63 -3
upload/src/main.rs
··· 1 1 use clap::{ArgAction, Parser}; 2 2 use jacquard::{ 3 + Data, 4 + api::com_atproto::{self, repo::list_records::ListRecords}, 3 5 client::{Agent, credential_session::CredentialSession}, 6 + cowstr::ToCowStr, 4 7 identity::JacquardResolver, 5 8 session::MemorySessionStore, 9 + types::{ident::AtIdentifier, nsid::Nsid, string::AtprotoStr, uri::Uri}, 10 + xrpc::XrpcExt, 6 11 }; 7 12 use std::{path::PathBuf, sync::Arc}; 8 13 ··· 53 58 let store = MemorySessionStore::default(); 54 59 let session = CredentialSession::new(Arc::new(store), Arc::new(client)); 55 60 56 - match session 61 + let auth = match session 57 62 .login(config.user.into(), config.password.into(), None, None, None) 58 63 .await 59 64 { 60 65 Ok(val) => { 61 66 println!("Authenticated {} ({})", val.handle, val.did); 67 + val 62 68 } 63 69 Err(err) => { 64 70 println!("Got error while authenticating:\n{}", err); 71 + return Err(()); 65 72 } 66 73 }; 67 74 68 75 let agent = Agent::from(session); 69 76 70 - // upload local site blobs 71 - 72 77 // find live site records 78 + let mut cursor = None; 79 + let mut remote_records = Vec::new(); 80 + loop { 81 + let req = com_atproto::repo::list_records::ListRecords::new() 82 + .collection( 83 + Nsid::new("dev.atcities.route").expect("failed to generate dev.atcities.route nsid"), 84 + ) 85 + .repo(AtIdentifier::Did(auth.did.clone())) 86 + .limit(100) 87 + .maybe_cursor(cursor) 88 + .build(); 89 + 90 + let res = agent 91 + .xrpc(agent.endpoint().await) 92 + .send::<ListRecords>(&req) 93 + .await 94 + .or(Err(()))? 95 + .into_output() 96 + .or(Err(()))?; 97 + 98 + for record in res.records { 99 + match record { 100 + Data::Object(obj) => { 101 + let obj = obj.0.clone(); 102 + let uri = obj.get_key_value("uri").and_then(|x| match x.1 { 103 + Data::String(str) => Some(str), 104 + _ => None, 105 + }); 106 + 107 + if let Some(uri) = uri 108 + && let AtprotoStr::Uri(uri) = uri 109 + && let Uri::At(uri) = uri 110 + && let Some(rkey) = uri.rkey() 111 + { 112 + let rkey = rkey.0.to_cowstr().to_string(); 113 + remote_records.push(rkey); 114 + } else { 115 + panic!("Warning: pds returned invalid data.") 116 + } 117 + } 118 + _ => { 119 + panic!("Warning: pds returned invalid data.") 120 + } 121 + } 122 + } 123 + 124 + cursor = res.cursor; 125 + if cursor.is_none() { 126 + break; 127 + } 128 + } 129 + 130 + print!("{remote_records:?}"); 131 + 132 + // upload local site blobs 73 133 74 134 // batch delete/upload records 75 135