use serde::{Deserialize, Serialize}; use reqwest::blocking::Client; use toml; use clap::Parser; use std::process::Command; // TODO: logging fn main() -> Result<(), Box> { let args = CliArgs::parse(); println!("Opening Config file: {}", args.config_file); println!("File exists: {}", std::fs::metadata(args.config_file.clone()).is_ok()); let file_contents = match std::fs::read_to_string(args.config_file) { Ok(val) => val, Err(e) => { println!("Could not read file: {}", e.to_string()); return Ok(()); } }; let cfg: Config = match toml::from_str(file_contents.as_str()) { Ok(val) => val, Err(e) => { println!("Could not parse file: {}", e.to_string()); return Ok(()); } }; let mut body_content: String = format!("*Last Updated:* {} \n", chrono::Local::now().format("%D - %H:%M:%S")); let mut drives: Vec = vec![]; { let rust_drives = match std::fs::read_dir("/dev/") { Ok(val) => val, Err(e) => { println!("Error opening /dev/: {}", e.to_string()); return Ok(()); } }; for path in rust_drives { match path { Ok(ref val) => { let tmp = val.path().to_string_lossy().to_string(); if tmp.starts_with("/dev/sd") { if tmp.len() == 8 { drives.push(tmp); } } }, _ => {} } } } { let mut drive_temps: Vec = vec![]; for drive in drives { let output = match Command::new(args.hddtemp_executable.clone()).arg(drive.clone()).output() { Ok(val) => val, Err(e) => { println!("Error running hddtemp: {}", e.to_string()); println!("Drive was: '{}'", drive); return Ok(()); } }; let tmp = String::from_utf8_lossy(&output.stdout).into_owned(); if !tmp.contains("sensor") { drive_temps.push(tmp.replace("\n", "")); } else { drive_temps.push(tmp[0..9].to_string() + " No Sensor"); } } body_content.push_str("## Hard Drive Temps\n"); body_content.push_str(drive_temps.join("\n").as_str()); } Client::new() .put(format!("https://{}/index.php/apps/notes/api/v1/notes/{}", cfg.server_url.clone(), cfg.note_id.clone())) .header("Accept", "application/json") .header("Content-Type", "application/json") .basic_auth(cfg.user.clone(), Some(cfg.pswd.clone())) .body(serde_json::to_string(&NoteUpdate {content: body_content}).unwrap()) .send()?; Ok(()) } #[derive(Serialize, Deserialize, Debug)] struct Note { id: usize, etag: String, readonly: bool, modified: u64, title: String, category: String, content: String, favorite: bool } #[derive(Serialize, Deserialize, Debug)] struct NoteUpdate { content: String, } #[derive(Serialize, Deserialize)] struct Config { user: String, pswd: String, note_id: String, server_url: String } impl Default for Config { fn default() -> Self { Self { user: "".to_string(), pswd: "".to_string(), note_id: "".to_string(), server_url: "".to_string(), } } } #[derive(Parser, Debug)] #[command(author, version, about, long_about=None)] struct CliArgs { /// Path to config .toml file #[arg(short, long)] config_file: String, #[arg(short, long)] hddtemp_executable: String, }