use std::io; use std::fs::File; use anyhow::{anyhow, Context, Result, bail}; #[async_std::main] async fn main() -> Result<()> { let args = std::env::args().collect::>(); if args.iter().skip(1).any(|s| s == "--help") { println!("Usage: {} [file]", args[0]); println!("\nIf launched with no arguments, reads from stdin."); println!("\nUse KITTYBOX_AUTH_TOKEN environment variable to authorize to the Micropub endpoint."); std::process::exit(0); } let token = std::env::var("KITTYBOX_AUTH_TOKEN").map_err(|_| anyhow!("No auth token found! Use KITTYBOX_AUTH_TOKEN env variable."))?; let data: Vec = (if args.len() == 2 || (args.len() == 3 && args[2] == "-") { serde_json::from_reader(io::stdin()) } else if args.len() == 3 { serde_json::from_reader(File::open(&args[2]).with_context(|| "Error opening input file")?) } else { bail!("See `{} --help` for usage.", args[0]); }).with_context(|| "Error while loading the input file")?; let url = surf::Url::parse(&args[1])?; let client = surf::Client::new(); let iter = data.into_iter(); for post in iter { println!("Processing {}...", post["properties"]["url"][0].as_str().or_else(|| post["properties"]["published"][0].as_str().or_else(|| post["properties"]["name"][0].as_str().or(Some("")))).unwrap()); match client.post(&url) .body(surf::http::Body::from_string( serde_json::to_string(&post)?)) .header("Content-Type", "application/json") .header("Authorization", format!("Bearer {}", &token)) .send().await { Ok(mut response) => { if response.status() == 201 || response.status() == 202 { println!("Posted at {}", response.header("location").unwrap().last()); } else { println!("Error: {:?}", response.body_string().await); } } Err(err) => { println!("{}", err); } } } Ok(()) }