use anyhow::{anyhow, Context, Result}; use redis::AsyncCommands; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fs::File; #[derive(Default, Serialize, Deserialize)] struct PyindieblogData { posts: Vec, cards: Vec, } #[async_std::main] async fn main() -> Result<()> { let mut args = std::env::args(); args.next(); // skip argv[0] which is the name let redis_uri = args .next() .ok_or_else(|| anyhow!("No Redis URI provided"))?; let client = redis::Client::open(redis_uri.as_str()) .with_context(|| format!("Failed to construct Redis client on {}", redis_uri))?; let filename = args .next() .ok_or_else(|| anyhow!("No filename provided for export"))?; let mut data: Vec; let file = File::create(filename)?; let mut conn = client .get_async_std_connection() .await .with_context(|| "Failed to connect to the Redis server")?; data = conn .hgetall::<&str, HashMap>("posts") .await? .values() .map(|s| { serde_json::from_str::(s) .with_context(|| format!("Failed to parse the following entry: {:?}", s)) }) .collect::, anyhow::Error>>() .with_context(|| "Failed to export h-entries from pyindieblog")?; data.extend( conn.hgetall::<&str, HashMap>("hcards") .await? .values() .map(|s| { serde_json::from_str::(s) .with_context(|| format!("Failed to parse the following card: {:?}", s)) }) .collect::, anyhow::Error>>() .with_context(|| "Failed to export h-cards from pyindieblog")?, ); data.sort_by_key(|v| { v["properties"]["published"][0] .as_str() .map(|s| s.to_string()) }); serde_json::to_writer(file, &data)?; Ok(()) }