mirror of
				https://github.com/pcvolkmer/checkbar.git
				synced 2025-11-04 05:26:12 +00:00 
			
		
		
		
	Add commands to be executed on mouse click
This commit is contained in:
		
							
								
								
									
										1040
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1040
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -2,13 +2,13 @@
 | 
			
		||||
name = "checkbar"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
author = "Paul-Christian Volkmer <code@pcvolkmer.de>"
 | 
			
		||||
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
dirs = "4"
 | 
			
		||||
serde = { version = "1", features = ["derive"] }
 | 
			
		||||
serde_json = "*"
 | 
			
		||||
chrono = { version = "*", features = ["serde"] }
 | 
			
		||||
tokio = { version = "1", features = ["full"] }
 | 
			
		||||
toml = "*"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								README.adoc
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								README.adoc
									
									
									
									
									
								
							@@ -32,3 +32,19 @@ You can optionally specify `check_type`:
 | 
			
		||||
 | 
			
		||||
* `Html`: Default value, checks if a request is succeessful and returns HTTP OK - 200.
 | 
			
		||||
* `Actuator`: Like `Html`, but checks if _Actuator_ shows that the application is up and running.
 | 
			
		||||
 | 
			
		||||
=== Execute commands
 | 
			
		||||
 | 
			
		||||
_This feature is experimental and starts further commands only after previous commands have been finished._
 | 
			
		||||
 | 
			
		||||
You can also specify a command to be executed when a mouse click occurs on a checked host.
 | 
			
		||||
Use `click_cmd` to specifiy the command to be executed, e.g.
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
...
 | 
			
		||||
[[checks]]
 | 
			
		||||
name = "Host 1"
 | 
			
		||||
url = "http://host1.example.com"
 | 
			
		||||
click_cmd = "xterm -e ssh admin@host1.example.com"
 | 
			
		||||
...
 | 
			
		||||
----
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										108
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -13,6 +13,7 @@ struct CheckConfig {
 | 
			
		||||
    name: String,
 | 
			
		||||
    url: String,
 | 
			
		||||
    check_type: Option<CheckType>,
 | 
			
		||||
    click_cmd: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Deserialize)]
 | 
			
		||||
@@ -26,6 +27,11 @@ struct ActuatorResponse {
 | 
			
		||||
    status: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Deserialize)]
 | 
			
		||||
struct ClickEvent {
 | 
			
		||||
    name: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct CheckResult {
 | 
			
		||||
    name: String,
 | 
			
		||||
    state: CheckState,
 | 
			
		||||
@@ -40,8 +46,8 @@ impl Display for CheckResult {
 | 
			
		||||
        };
 | 
			
		||||
        write!(
 | 
			
		||||
            f,
 | 
			
		||||
            "{{\"full_text\":\"{}\",\"separator_block_width\":16,\"color\":\"{}\"}}",
 | 
			
		||||
            self.name, color
 | 
			
		||||
            "{{\"full_text\":\"{}\",\"name\":\"{}\",\"separator_block_width\":16,\"color\":\"{}\"}}",
 | 
			
		||||
            self.name, self.name, color
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -96,30 +102,86 @@ async fn print_states(check_configs: &[CheckConfig]) {
 | 
			
		||||
    println!("{}],", entries.join(","));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[tokio::main(flavor = "current_thread")]
 | 
			
		||||
async fn main() {
 | 
			
		||||
    println!("{{\"version\":1,\"click_events\":false}}");
 | 
			
		||||
    println!("[");
 | 
			
		||||
    loop {
 | 
			
		||||
        let home_dir = dirs::home_dir().unwrap();
 | 
			
		||||
        let config = match std::fs::read_to_string(format!(
 | 
			
		||||
            "{}/.checkbar.toml",
 | 
			
		||||
            home_dir.to_str().unwrap_or("")
 | 
			
		||||
        )) {
 | 
			
		||||
            Ok(config) => match toml::from_str(config.as_str()) {
 | 
			
		||||
                Ok(config) => config,
 | 
			
		||||
                Err(_e) => Config {
 | 
			
		||||
                    interval: None,
 | 
			
		||||
                    checks: vec![],
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
async fn get_config() -> Config {
 | 
			
		||||
    let home_dir = dirs::home_dir().unwrap();
 | 
			
		||||
    match std::fs::read_to_string(format!(
 | 
			
		||||
        "{}/.checkbar.toml",
 | 
			
		||||
        home_dir.to_str().unwrap_or("")
 | 
			
		||||
    )) {
 | 
			
		||||
        Ok(config) => match toml::from_str(config.as_str()) {
 | 
			
		||||
            Ok(config) => config,
 | 
			
		||||
            Err(_e) => Config {
 | 
			
		||||
                interval: None,
 | 
			
		||||
                checks: vec![],
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        print_states(&config.checks).await;
 | 
			
		||||
        std::thread::sleep(Duration::from_secs(config.interval.unwrap_or(60)));
 | 
			
		||||
        },
 | 
			
		||||
        Err(_e) => Config {
 | 
			
		||||
            interval: None,
 | 
			
		||||
            checks: vec![],
 | 
			
		||||
        },
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn get_click_cmd(name: String) -> Option<String> {
 | 
			
		||||
    for check in get_config().await.checks {
 | 
			
		||||
        if check.name == name {
 | 
			
		||||
            return check.click_cmd;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    None
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn run_click_cmd(cmd: String) {
 | 
			
		||||
    let _r = match std::process::Command::new("sh")
 | 
			
		||||
        .stdin(std::process::Stdio::piped())
 | 
			
		||||
        .stderr(std::process::Stdio::piped())
 | 
			
		||||
        .spawn()
 | 
			
		||||
    {
 | 
			
		||||
        Ok(mut child) => {
 | 
			
		||||
            use std::io::Write;
 | 
			
		||||
            let _r = child.stdin.as_mut().unwrap().write_all(cmd.as_bytes());
 | 
			
		||||
            child.wait()
 | 
			
		||||
        }
 | 
			
		||||
        Err(e) => Err(e),
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[tokio::main(flavor = "multi_thread", worker_threads = 2)]
 | 
			
		||||
async fn main() {
 | 
			
		||||
    println!("{{\"version\":1,\"click_events\":true}}");
 | 
			
		||||
    println!("[");
 | 
			
		||||
 | 
			
		||||
    let inputs = tokio::task::spawn(async {
 | 
			
		||||
        let stdin = std::io::stdin();
 | 
			
		||||
        loop {
 | 
			
		||||
            let mut input = String::new();
 | 
			
		||||
 | 
			
		||||
            if stdin.read_line(&mut input).is_err() {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if input.is_empty() {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Remove leading comma
 | 
			
		||||
            let input = input.replace(",{", "{");
 | 
			
		||||
 | 
			
		||||
            if let Ok(click_event) = serde_json::from_str::<ClickEvent>(input.as_str()) {
 | 
			
		||||
                if let Some(click_cmd) = get_click_cmd(click_event.name).await {
 | 
			
		||||
                    run_click_cmd(click_cmd).await;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let checks = tokio::task::spawn(async {
 | 
			
		||||
        loop {
 | 
			
		||||
            let config = get_config().await;
 | 
			
		||||
            print_states(&config.checks).await;
 | 
			
		||||
            std::thread::sleep(Duration::from_secs(config.interval.unwrap_or(60)));
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let _r = tokio::join!(inputs, checks);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user