1use clap::Parser;
2use jacquard::CowStr;
3use jacquard::api::com_whtwnd::blog::entry::Entry;
4use jacquard::client::{Agent, AgentSessionExt, FileAuthStore};
5use jacquard::oauth::client::OAuthClient;
6use jacquard::oauth::loopback::LoopbackConfig;
7use jacquard::types::string::Datetime;
8use miette::IntoDiagnostic;
9use url::Url;
10
11#[derive(Parser, Debug)]
12#[command(author, version, about = "Create a WhiteWind blog post")]
13struct Args {
14 /// Handle (e.g., alice.bsky.social), DID, or PDS URL
15 input: CowStr<'static>,
16
17 /// Blog post title
18 #[arg(short, long)]
19 title: String,
20
21 /// Blog post content (markdown)
22 #[arg(short, long)]
23 content: String,
24
25 /// Optional subtitle
26 #[arg(short, long)]
27 subtitle: Option<String>,
28
29 /// Path to auth store file (will be created if missing)
30 #[arg(long, default_value = "/tmp/jacquard-oauth-session.json")]
31 store: String,
32}
33
34#[tokio::main]
35async fn main() -> miette::Result<()> {
36 let args = Args::parse();
37
38 let oauth = OAuthClient::with_default_config(FileAuthStore::new(&args.store));
39 let session = oauth
40 .login_with_local_server(args.input, Default::default(), LoopbackConfig::default())
41 .await?;
42
43 let agent: Agent<_> = Agent::from(session);
44
45 // Create a WhiteWind blog entry
46 // The content field accepts markdown
47 let entry = Entry {
48 title: Some(CowStr::from(args.title)),
49 subtitle: args.subtitle.map(CowStr::from),
50 content: CowStr::from(args.content),
51 created_at: Some(Datetime::now()),
52 visibility: Some(CowStr::from("url")), // "url" = public with link, "author" = public on profile
53 theme: None,
54 ogp: None,
55 blobs: None,
56 is_draft: None,
57 extra_data: Default::default(),
58 };
59
60 let output = agent.create_record(entry, None).await?;
61 println!("Created WhiteWind blog post: {}", output.uri);
62 let url = Url::parse(&format!(
63 "https://whtwnd.nat.vg/{}/{}",
64 output.uri.authority(),
65 output.uri.rkey().map(|r| r.as_ref()).unwrap_or("")
66 ))
67 .into_diagnostic()?;
68 println!("View at: {}", url);
69
70 Ok(())
71}