1use clap::Parser;
2use jacquard::StreamingResponse;
3use jacquard::api::com_atproto::sync::get_blob::GetBlob;
4use jacquard::client::Agent;
5use jacquard::types::cid::Cid;
6use jacquard::types::did::Did;
7use jacquard::xrpc::XrpcStreamingClient;
8use jacquard_oauth::authstore::MemoryAuthStore;
9use jacquard_oauth::client::OAuthClient;
10use jacquard_oauth::loopback::LoopbackConfig;
11use n0_future::StreamExt;
12
13#[derive(Parser, Debug)]
14#[command(
15 author,
16 version,
17 about = "Download a blob from a PDS and stream the response, then display it, if it's an image"
18)]
19struct Args {
20 input: String,
21 #[arg(short, long)]
22 did: String,
23 #[arg(short, long)]
24 cid: String,
25}
26
27#[tokio::main]
28async fn main() -> miette::Result<()> {
29 let args = Args::parse();
30
31 let oauth = OAuthClient::with_default_config(MemoryAuthStore::new());
32 let session = oauth
33 .login_with_local_server(args.input, Default::default(), LoopbackConfig::default())
34 .await?;
35
36 let agent: Agent<_> = Agent::from(session);
37 // Use the streaming `.download()` method with the generated API parameter struct
38 let output: StreamingResponse = agent
39 .download(GetBlob {
40 did: Did::new_owned(args.did)?,
41 cid: Cid::str(&args.cid),
42 })
43 .await?;
44
45 let (parts, body_stream) = output.into_parts();
46
47 println!("Parts: {:?}", parts);
48
49 let mut buf: Vec<u8> = Vec::new();
50 let mut stream = body_stream.into_inner();
51
52 while let Some(Ok(chunk)) = stream.as_mut().next().await {
53 buf.append(&mut chunk.to_vec());
54 }
55
56 if let Ok(img) = image::load_from_memory(&buf) {
57 viuer::print(&img, &viuer::Config::default()).expect("Image printing failed.");
58 }
59
60 Ok(())
61}