Compare commits
3 commits
0c954962cc
...
56beda6840
Author | SHA1 | Date | |
---|---|---|---|
56beda6840 | |||
61b7bd447d | |||
98acf3c74e |
4 changed files with 66 additions and 27 deletions
41
src/cli.rs
41
src/cli.rs
|
@ -5,10 +5,9 @@ use std::net::Shutdown;
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Parser)]
|
||||||
#[command(name = "timers")]
|
#[command(name = "timers")]
|
||||||
#[command(about = "A advanced timer daemon/cli.", long_about = None)]
|
/// A advanced timer daemon/cli.
|
||||||
#[command(arg_required_else_help = true)]
|
|
||||||
pub struct Cli {
|
pub struct Cli {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
pub command: Command,
|
pub command: Command,
|
||||||
|
@ -19,35 +18,67 @@ pub struct Cli {
|
||||||
|
|
||||||
#[derive(Debug, Subcommand)]
|
#[derive(Debug, Subcommand)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
|
/// Run as daemon
|
||||||
|
#[clap(visible_alias="d")]
|
||||||
Daemon {
|
Daemon {
|
||||||
|
/// do not send notifications
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
notify: bool,
|
no_notify: bool,
|
||||||
},
|
},
|
||||||
|
/// Add a timer
|
||||||
|
#[clap(visible_alias="a")]
|
||||||
Add {
|
Add {
|
||||||
|
/// name of the timer
|
||||||
name: String,
|
name: String,
|
||||||
|
/// duration of the timer
|
||||||
duration: humantime::Duration,
|
duration: humantime::Duration,
|
||||||
},
|
},
|
||||||
|
/// List timers
|
||||||
|
#[clap(visible_alias="l")]
|
||||||
List,
|
List,
|
||||||
|
/// Remove a timer
|
||||||
|
#[clap(visible_alias="r")]
|
||||||
Remove {
|
Remove {
|
||||||
|
/// name of the timer to remove
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
/// Pomodoro specific command
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
|
#[clap(visible_alias="p")]
|
||||||
Pomodoro(PomodoroCommand)
|
Pomodoro(PomodoroCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Subcommand)]
|
#[derive(Debug, Subcommand)]
|
||||||
pub enum PomodoroCommand {
|
pub enum PomodoroCommand {
|
||||||
|
/// Start pomodoro
|
||||||
|
#[clap(visible_alias="s")]
|
||||||
Start {
|
Start {
|
||||||
|
/// duration to work for
|
||||||
|
#[arg(long)]
|
||||||
#[clap(default_value_t = Duration::from_secs(25 * 60).into())]
|
#[clap(default_value_t = Duration::from_secs(25 * 60).into())]
|
||||||
work: humantime::Duration,
|
work: humantime::Duration,
|
||||||
|
|
||||||
|
/// duration for short pauses
|
||||||
|
#[arg(long)]
|
||||||
#[clap(default_value_t = Duration::from_secs(5 * 60).into())]
|
#[clap(default_value_t = Duration::from_secs(5 * 60).into())]
|
||||||
pause: humantime::Duration,
|
pause: humantime::Duration,
|
||||||
|
|
||||||
|
/// duration for long pauses
|
||||||
|
#[arg(long)]
|
||||||
#[clap(default_value_t = Duration::from_secs(10 * 60).into())]
|
#[clap(default_value_t = Duration::from_secs(10 * 60).into())]
|
||||||
long_pause: humantime::Duration,
|
long_pause: humantime::Duration,
|
||||||
|
|
||||||
|
/// number of short pauses till long pause
|
||||||
|
#[arg(long)]
|
||||||
#[clap(default_value_t = 3)]
|
#[clap(default_value_t = 3)]
|
||||||
pauses_till_long: u64,
|
pauses_till_long: u64,
|
||||||
},
|
},
|
||||||
Stop,
|
/// Stop the pomodoro
|
||||||
|
#[clap(visible_alias="p")]
|
||||||
|
Remove,
|
||||||
|
/// List the pomodoro settings and remaining duration
|
||||||
|
#[clap(visible_alias="l")]
|
||||||
|
List,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_stream(socket_path: &String) -> Result<UnixStream> {
|
fn get_stream(socket_path: &String) -> Result<UnixStream> {
|
||||||
|
|
|
@ -22,33 +22,34 @@ pub enum Command {
|
||||||
long_pause: Duration,
|
long_pause: Duration,
|
||||||
pauses_till_long: u64,
|
pauses_till_long: u64,
|
||||||
},
|
},
|
||||||
PomodoroStop
|
PomodoroRemove,
|
||||||
|
PomodoroList,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum Answer {
|
pub enum Answer {
|
||||||
Ok,
|
Ok,
|
||||||
Timers(Vec<Timer>, Option<Pomodoro>),
|
Timers(Vec<Timer>),
|
||||||
|
Pomodoro(Option<Pomodoro>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Answer {
|
impl Display for Answer {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
match self {
|
match self {
|
||||||
Answer::Ok => write!(f, "Ok"),
|
Answer::Ok => write!(f, "Ok"),
|
||||||
Answer::Timers(timers, pomodoro) => {
|
Answer::Timers(timers) => {
|
||||||
if timers.is_empty() {
|
if timers.is_empty() {
|
||||||
writeln!(f, "No timers running.")?;
|
writeln!(f, "No timers running.")
|
||||||
} else {
|
} else {
|
||||||
let strings: Vec<String> =
|
let strings: Vec<String> =
|
||||||
timers.iter().map(|timer| timer.to_string()).collect();
|
timers.iter().map(|timer| timer.to_string()).collect();
|
||||||
writeln!(f, "{}", strings.join("\n"))?;
|
writeln!(f, "{}", strings.join("\n"))
|
||||||
};
|
|
||||||
|
|
||||||
match pomodoro {
|
|
||||||
Some(p) => write!(f, "{}", p),
|
|
||||||
None => write!(f, "No pomodoro running."),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Answer::Pomodoro(pomodoro) => match pomodoro {
|
||||||
|
Some(p) => write!(f, "{}", p),
|
||||||
|
None => write!(f, "No pomodoro running."),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +70,7 @@ pub struct Daemon {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Daemon {
|
impl Daemon {
|
||||||
pub fn new(socket_path: String, notify: bool) -> anyhow::Result<Self> {
|
pub fn new(socket_path: String, no_notify: bool) -> anyhow::Result<Self> {
|
||||||
let path = std::path::Path::new(&socket_path);
|
let path = std::path::Path::new(&socket_path);
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
std::fs::remove_file(path)
|
std::fs::remove_file(path)
|
||||||
|
@ -81,7 +82,7 @@ impl Daemon {
|
||||||
listener,
|
listener,
|
||||||
timers: Vec::new(),
|
timers: Vec::new(),
|
||||||
pomodoro: None,
|
pomodoro: None,
|
||||||
notify,
|
notify: !no_notify,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ impl Daemon {
|
||||||
fn handle_command(&mut self, command: Command) -> Result<Answer, AnswerErr> {
|
fn handle_command(&mut self, command: Command) -> Result<Answer, AnswerErr> {
|
||||||
println!("Received command {:?}", command);
|
println!("Received command {:?}", command);
|
||||||
match command {
|
match command {
|
||||||
Command::List => Ok(Answer::Timers(self.timers.clone(), self.pomodoro.clone())),
|
Command::List => Ok(Answer::Timers(self.timers.clone())),
|
||||||
Command::Add(name, duration) => {
|
Command::Add(name, duration) => {
|
||||||
if self.has_timer(&name) {
|
if self.has_timer(&name) {
|
||||||
return Err(AnswerErr::TimerAlreadyExist(name));
|
return Err(AnswerErr::TimerAlreadyExist(name));
|
||||||
|
@ -145,10 +146,11 @@ impl Daemon {
|
||||||
self.pomodoro = Some(Pomodoro::new(work, pause, long_pause, pauses_till_long));
|
self.pomodoro = Some(Pomodoro::new(work, pause, long_pause, pauses_till_long));
|
||||||
Ok(Answer::Ok)
|
Ok(Answer::Ok)
|
||||||
}
|
}
|
||||||
Command::PomodoroStop => {
|
Command::PomodoroRemove => {
|
||||||
self.pomodoro = None;
|
self.pomodoro = None;
|
||||||
Ok(Answer::Ok)
|
Ok(Answer::Ok)
|
||||||
},
|
}
|
||||||
|
Command::PomodoroList => Ok(Answer::Pomodoro(self.pomodoro.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use cli::PomodoroCommand;
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let args = Cli::parse();
|
let args = Cli::parse();
|
||||||
let daemon_command = match args.command {
|
let daemon_command = match args.command {
|
||||||
CliCommand::Daemon { notify } => return Daemon::new(args.socket, notify)?.run(),
|
CliCommand::Daemon { no_notify } => return Daemon::new(args.socket, no_notify)?.run(),
|
||||||
CliCommand::Add { name, duration } => {
|
CliCommand::Add { name, duration } => {
|
||||||
DaemonCommand::Add(name.into_boxed_str(), duration.into())
|
DaemonCommand::Add(name.into_boxed_str(), duration.into())
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,8 @@ fn main() -> Result<()> {
|
||||||
long_pause: long_pause.into(),
|
long_pause: long_pause.into(),
|
||||||
pauses_till_long,
|
pauses_till_long,
|
||||||
},
|
},
|
||||||
PomodoroCommand::Stop => DaemonCommand::PomodoroStop,
|
PomodoroCommand::Remove => DaemonCommand::PomodoroRemove,
|
||||||
|
PomodoroCommand::List => DaemonCommand::PomodoroList,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
send_command(&args.socket, daemon_command)
|
send_command(&args.socket, daemon_command)
|
||||||
|
|
|
@ -39,9 +39,9 @@ enum Status {
|
||||||
impl Display for Status {
|
impl Display for Status {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Status::Working => write!(f, "pomodoro work"),
|
Status::Working => write!(f, "work"),
|
||||||
Status::Pausing => write!(f, "pomodoro pause"),
|
Status::Pausing => write!(f, "pause"),
|
||||||
Status::LongPause => write!(f, "pomodoro long pause"),
|
Status::LongPause => write!(f, "long pause"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,13 @@ impl Pomodoro {
|
||||||
};
|
};
|
||||||
self.status = match self.status {
|
self.status = match self.status {
|
||||||
Status::Working => {
|
Status::Working => {
|
||||||
self.pauses += 1;
|
if self.pauses == self.pauses_till_long {
|
||||||
Status::Pausing
|
self.pauses = 0;
|
||||||
|
Status::LongPause
|
||||||
|
} else {
|
||||||
|
self.pauses += 1;
|
||||||
|
Status::Pausing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => Status::Working,
|
_ => Status::Working,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue