2023-07-29 10:41:56 +02:00
|
|
|
use crate::daemon::{Answer, AnswerErr, Command as OtherCommand};
|
2023-07-29 18:11:32 +02:00
|
|
|
use crate::run_path;
|
2023-07-28 19:52:23 +02:00
|
|
|
use anyhow::{Context, Result};
|
|
|
|
use clap::{Parser, Subcommand};
|
|
|
|
use std::net::Shutdown;
|
|
|
|
use std::os::unix::net::UnixStream;
|
2023-07-29 12:52:50 +02:00
|
|
|
use std::time::Duration;
|
2023-07-28 19:52:23 +02:00
|
|
|
|
2023-07-29 15:56:31 +02:00
|
|
|
#[derive(Parser)]
|
2023-07-28 19:52:23 +02:00
|
|
|
#[command(name = "timers")]
|
2023-07-29 16:59:46 +02:00
|
|
|
/// A simple timer daemon/cli.
|
2023-07-28 19:52:23 +02:00
|
|
|
pub struct Cli {
|
|
|
|
#[command(subcommand)]
|
|
|
|
pub command: Command,
|
|
|
|
#[arg(short, long)]
|
2023-07-29 18:11:32 +02:00
|
|
|
#[clap(default_value_t = format!("{}/timers.socket", run_path()))]
|
2023-07-28 19:52:23 +02:00
|
|
|
pub socket: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Subcommand)]
|
|
|
|
pub enum Command {
|
2023-07-29 15:56:31 +02:00
|
|
|
/// Run as daemon
|
2023-07-29 16:52:39 +02:00
|
|
|
#[clap(visible_alias = "d")]
|
2023-07-29 10:41:56 +02:00
|
|
|
Daemon {
|
2023-07-29 15:56:31 +02:00
|
|
|
/// do not send notifications
|
2023-07-29 10:41:56 +02:00
|
|
|
#[arg(short, long)]
|
2023-07-29 15:56:31 +02:00
|
|
|
no_notify: bool,
|
2023-07-30 17:53:28 +02:00
|
|
|
#[arg(short, long)]
|
|
|
|
#[clap(default_value_t = format!("{}/timers.pid", run_path()))]
|
|
|
|
pid_file: String,
|
2023-07-29 10:41:56 +02:00
|
|
|
},
|
2023-07-29 15:56:31 +02:00
|
|
|
/// Add a timer
|
2023-07-29 16:52:39 +02:00
|
|
|
#[clap(visible_alias = "a")]
|
2023-07-29 10:41:56 +02:00
|
|
|
Add {
|
2023-07-29 15:56:31 +02:00
|
|
|
/// name of the timer
|
2023-07-29 10:41:56 +02:00
|
|
|
name: String,
|
2023-07-29 15:56:31 +02:00
|
|
|
/// duration of the timer
|
2023-07-29 12:52:50 +02:00
|
|
|
duration: humantime::Duration,
|
2023-07-29 10:41:56 +02:00
|
|
|
},
|
2023-07-29 15:56:31 +02:00
|
|
|
/// List timers
|
2023-07-29 16:52:39 +02:00
|
|
|
#[clap(visible_alias = "l")]
|
2023-07-28 19:52:23 +02:00
|
|
|
List,
|
2023-07-29 15:56:31 +02:00
|
|
|
/// Remove a timer
|
2023-07-29 16:52:39 +02:00
|
|
|
#[clap(visible_alias = "r")]
|
2023-07-29 10:41:56 +02:00
|
|
|
Remove {
|
2023-07-29 15:56:31 +02:00
|
|
|
/// name of the timer to remove
|
2023-07-29 10:41:56 +02:00
|
|
|
name: String,
|
|
|
|
},
|
2023-07-29 15:56:31 +02:00
|
|
|
/// Pomodoro specific command
|
2023-07-29 12:52:50 +02:00
|
|
|
#[command(subcommand)]
|
2023-07-29 16:52:39 +02:00
|
|
|
#[clap(visible_alias = "p")]
|
|
|
|
Pomodoro(PomodoroCommand),
|
2023-07-29 12:52:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Subcommand)]
|
|
|
|
pub enum PomodoroCommand {
|
2023-07-29 15:56:31 +02:00
|
|
|
/// Start pomodoro
|
2023-07-29 16:52:39 +02:00
|
|
|
#[clap(visible_alias = "s")]
|
2023-07-29 12:52:50 +02:00
|
|
|
Start {
|
2023-07-29 15:56:31 +02:00
|
|
|
/// duration to work for
|
|
|
|
#[arg(long)]
|
2023-07-29 12:52:50 +02:00
|
|
|
#[clap(default_value_t = Duration::from_secs(25 * 60).into())]
|
|
|
|
work: humantime::Duration,
|
2023-07-29 15:56:31 +02:00
|
|
|
|
|
|
|
/// duration for short pauses
|
|
|
|
#[arg(long)]
|
2023-07-29 12:52:50 +02:00
|
|
|
#[clap(default_value_t = Duration::from_secs(5 * 60).into())]
|
|
|
|
pause: humantime::Duration,
|
2023-07-29 15:56:31 +02:00
|
|
|
|
|
|
|
/// duration for long pauses
|
|
|
|
#[arg(long)]
|
2023-07-29 12:52:50 +02:00
|
|
|
#[clap(default_value_t = Duration::from_secs(10 * 60).into())]
|
|
|
|
long_pause: humantime::Duration,
|
2023-07-29 15:56:31 +02:00
|
|
|
|
|
|
|
/// number of short pauses till long pause
|
|
|
|
#[arg(long)]
|
2023-07-29 12:15:19 +02:00
|
|
|
#[clap(default_value_t = 3)]
|
|
|
|
pauses_till_long: u64,
|
2023-07-29 12:52:50 +02:00
|
|
|
},
|
2023-07-29 15:56:31 +02:00
|
|
|
/// Stop the pomodoro
|
2023-07-29 16:52:39 +02:00
|
|
|
#[clap(visible_alias = "p")]
|
2023-07-29 15:56:31 +02:00
|
|
|
Remove,
|
2023-07-29 16:02:42 +02:00
|
|
|
/// List the pomodoro settings and remaining duration
|
2023-07-29 16:52:39 +02:00
|
|
|
#[clap(visible_alias = "l")]
|
2023-07-29 16:02:42 +02:00
|
|
|
List,
|
2023-07-28 19:52:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fn get_stream(socket_path: &String) -> Result<UnixStream> {
|
|
|
|
UnixStream::connect(socket_path)
|
|
|
|
.context(format!("Could not connect to socket {}!", socket_path))
|
|
|
|
}
|
|
|
|
|
2023-07-29 16:52:39 +02:00
|
|
|
pub fn send_command(socket_path: &String, command: OtherCommand) -> Result<Answer> {
|
2023-07-28 19:52:23 +02:00
|
|
|
let stream = get_stream(socket_path)?;
|
|
|
|
serde_cbor::to_writer(&stream, &command).context("Could not write command!")?;
|
|
|
|
stream
|
|
|
|
.shutdown(Shutdown::Write)
|
|
|
|
.context("Could not shutdown write!")?;
|
2023-07-29 10:41:56 +02:00
|
|
|
let answer: Result<Answer, AnswerErr> =
|
|
|
|
serde_cbor::from_reader(&stream).context("Could not read answer!")?;
|
2023-07-29 16:52:39 +02:00
|
|
|
Ok(answer?)
|
2023-07-28 19:52:23 +02:00
|
|
|
}
|