use std::process::Command; use websocket::sync::client::ClientBuilder; mod args; mod did; mod knot; fn main() -> Result<(), ()> { // load configuration let config = match args::load_config() { Ok(res) => res, Err(_) => return Err(()), }; // resolve handle to did println!("Resolving {}", config.handle); let did_doc = match did::get_did(&config.handle) { Ok(res) => res, Err(_) => return Err(()), }; println!( " Found DID `{0}` hosted at `{1}`", did_doc.did, did_doc.pds ); // resolve did+repoName to knotserver println!("Resolving @{0}/{1}", config.handle, config.repo_name); let knot_server = match knot::find_knot(&did_doc.did, &config.repo_name, &did_doc.pds) { Ok(val) => val, Err(_) => return Err(()), }; println!(" Found knot `{}`", knot_server); // connect to /events on knotserver println!( "Connecting to `{}`", format!("wss://{}/events", knot_server) ); let mut client = match ClientBuilder::new(&format!("wss://{}/events", knot_server)) { Ok(mut val) => match val.connect(None) { Ok(val) => val, Err(_) => { println!(" Couldn't open a connection"); return Err(()); } }, Err(_) => { println!(" Knot server was malformed."); return Err(()); } }; println!(" Connected successfully."); // on event: for message in client.incoming_messages() { if let Ok(ref val) = message && let websocket::OwnedMessage::Text(body) = val { // parse json let body = match json::parse(&body) { Ok(val) => val, Err(_) => { println!(" Invalid body. Skipping message"); continue; } }; // filter by did and reponame if let Some(repo_did) = body["event"]["repoDid"].as_str() && let Some(repo) = body["event"]["repoName"].as_str() && repo_did != &did_doc.did && repo != &config.repo_name { // repo doesnt match so skip continue; } // exec shell command in /bin/sh match Command::new("/bin/sh") .arg("-c") .arg(&config.shell) .output() { Ok(val) => val, Err(_) => continue, }; } else if let Err(err) = message { println!(" Got websocket error: {}", err) } } return Ok(()); }