Read alarm times from stdin.

This commit is contained in:
shy 2021-04-14 18:09:45 +02:00
parent d0aa9f7a4f
commit 3039af5aee
3 changed files with 65 additions and 32 deletions

View file

@ -316,34 +316,58 @@ impl AlarmRoster {
alarm.reset(); alarm.reset();
} }
} }
// Read alarm times from stdin.
pub fn from_stdin(&mut self, stdin: std::io::Stdin)
-> Result<(), String>
{
let mut buffer = String::new();
loop {
match stdin.read_line(&mut buffer) {
Ok(0) => break, // EOF.
Ok(1) => continue, // Empty (newline only).
Ok(_) => (),
Err(e) => return Err(e.to_string()),
}
// Strip newline.
buffer.retain(|c| c != '\n');
// Ignore lines containing only white spaces.
if buffer.contains(|c: char| !c.is_whitespace()) {
if let Err(e) = self.add(&buffer) {
return Err(e.to_string());
}
}
buffer.clear();
}
Ok(())
}
} }
// Execute the command given on the command line. // Execute the command given on the command line.
pub fn exec_command(config: &Config, elapsed: u32, label: &String) -> Option<Child> { pub fn exec_command(command: &Vec<String>, elapsed: u32, label: &String) -> Option<Child> {
let mut args: Vec<String> = Vec::new(); let time = if elapsed < 3600 {
let time: String; format!("{:02}:{:02}", elapsed / 60, elapsed % 60)
if elapsed < 3600 {
time = format!("{:02}:{:02}", elapsed / 60, elapsed % 60);
} else { } else {
time = format!("{:02}:{:02}:{:02}", elapsed /3600, (elapsed / 60) % 60, elapsed % 60); format!("{:02}:{:02}:{:02}", elapsed /3600, (elapsed / 60) % 60, elapsed % 60)
} };
if let Some(command) = &config.command { let mut args: Vec<String> = Vec::new();
// Replace every occurrence of "{}". // Build vector of command line arguments. Replace every occurrence of
args.reserve_exact(command.len()); // "{t}" and "{l}".
for s in command { for s in command.iter().skip(1) {
args.push(s.replace("{t}", &time).replace("{l}", &label)); args.push(s.replace("{t}", &time).replace("{l}", &label));
} }
match Command::new(&command[0]).args(&args[1..]) match Command::new(&command[0])
.stdout(Stdio::null()).stdin(Stdio::null()).spawn() { .args(args)
Ok(child) => return Some(child), .stdout(Stdio::null())
.stdin(Stdio::null())
.spawn() {
Ok(child) => Some(child),
Err(error) => { Err(error) => {
eprintln!("Error: Could not execute command. ({})", error); eprintln!("Error: Could not execute command. ({})", error);
}
}
}
None None
} }
}
}

View file

@ -38,6 +38,7 @@ pub fn run(
let mut clock = Clock::new(&config); let mut clock = Clock::new(&config);
let mut countdown = Countdown::new(); let mut countdown = Countdown::new();
let mut buffer = Buffer::new(); let mut buffer = Buffer::new();
let async_stdin = termion::async_stdin(); let async_stdin = termion::async_stdin();
let mut input_keys = async_stdin.keys(); let mut input_keys = async_stdin.keys();
let stdout = std::io::stdout(); let stdout = std::io::stdout();
@ -119,19 +120,17 @@ pub fn run(
write!(stdout, "{}", 0x07 as char)?; write!(stdout, "{}", 0x07 as char)?;
layout.force_redraw = true; layout.force_redraw = true;
// Run command if configured. match config.command {
if config.command.is_some() { // Run command if configured and no command is running.
if spawned.is_none() { Some(ref command) if spawned.is_none() => {
*spawned = exec_command(&config, time, &label); *spawned = exec_command(command, time, &label);
} else { },
// The last command is still running. // Last command is still running.
eprintln!("Not executing command, as its predecessor is still running"); Some(_) => eprintln!("Not executing command, as its predecessor is still running"),
} None => (),
} }
// Quit if configured. // Quit if configured.
if config.quit && alarm_roster.idle() { if config.quit && alarm_roster.idle() { break };
break;
}
} }
// Clear the window and redraw menu bar, alarm roster and buffer if // Clear the window and redraw menu bar, alarm roster and buffer if

View file

@ -12,6 +12,16 @@ fn main() {
process::exit(1); process::exit(1);
}); });
// Read alarm times from stdin if stdin not a tty.
let stdin = std::io::stdin();
if !termion::is_tty(&stdin) {
stdin.lock();
if let Err(e) = alarm_roster.from_stdin(stdin) {
eprintln!("Error while reading alarm times from stdin. ({})", e);
process::exit(1);
}
}
// Holds spawned child process if any. // Holds spawned child process if any.
let mut spawned: Option<process::Child> = None; let mut spawned: Option<process::Child> = None;