1
0
mirror of https://github.com/pcvolkmer/checkbar.git synced 2025-04-19 11:06:50 +00:00

Add commands to be executed on mouse click

This commit is contained in:
Paul-Christian Volkmer 2022-03-05 14:14:30 +01:00
parent fb312d2102
commit fbc5237a8e
4 changed files with 1142 additions and 24 deletions

1040
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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 = "*"

View File

@ -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"
...
----

View File

@ -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);
}