commit: | 715661e5277b6fa2dda29bde4e9879cf00d143c4 |
author: | Trevor Bentley |
committer: | Trevor Bentley |
date: | Mon Nov 13 23:01:21 2017 +0100 |
parents: | 624afd12a6e8fca09fda97f9d3f0c947c84383b4 |
diff --git a/Cargo.lock b/Cargo.lock line changes: +131/-0 index a5b4ef7..ee9c060 --- a/Cargo.lock +++ b/Cargo.lock
@@ -2,8 +2,10 @@ name = "circadian" version = "0.1.0" dependencies = [ + "clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-ini 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]]
@@ -15,11 +17,55 @@ dependencies = [ ] [[package]] +name = "ansi_term" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "atty" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "clap" +version = "2.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "lazy_static" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -30,6 +76,11 @@ version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "log" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "memchr" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -38,6 +89,19 @@ dependencies = [ ] [[package]] +name = "redox_syscall" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "regex" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -55,6 +119,37 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "rust-ini" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "strsim" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "thread_local" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -64,6 +159,11 @@ dependencies = [ ] [[package]] +name = "unicode-width" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "unreachable" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -77,19 +177,50 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "vec_map" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [metadata] "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" +"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" +"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" +"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" +"checksum clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b8c532887f1a292d17de05ae858a8fe50a301e196f9ef0ddb7ccd0d1d00f180" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5" "checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2" +"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" +"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" +"checksum rust-ini 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06d4e8b0b50e7e7f827d609fa9746e1cf6371a1fa15404a1a0a86152a801079f" +"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" "checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" +"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
diff --git a/Cargo.toml b/Cargo.toml line changes: +1/-0 index e0a888c..725b89a --- a/Cargo.toml +++ b/Cargo.toml
@@ -17,3 +17,4 @@ lto = true regex = "0.2" glob = "0.2.11" rust-ini = "0.10.0" +clap = "2.27.1"
diff --git a/resources/circadian.conf.in b/resources/circadian.conf.in line changes: +2/-0 index 9e40882..4c25a50 --- a/resources/circadian.conf.in +++ b/resources/circadian.conf.in
@@ -71,6 +71,8 @@ process_block = ^dd$,^rsync$,^apt-get$,^dpkg$,^cp$,^mv$ [actions] # How long the system must be idle before the idle action is taken. # +# Empty or 0 is disabled. +# # NOTE: only the '*_input' heuristics need to be continuously idle without # interruption. The other heuristics only need to be true instantaneously # after idle_time has passed. (ex: with an idle_time of 1 hour, the mouse
diff --git a/src/main.rs b/src/main.rs line changes: +112/-1 index 36c35e1..27f5204 --- a/src/main.rs +++ b/src/main.rs
@@ -26,16 +26,35 @@ use regex::Regex; extern crate glob; use glob::glob; +extern crate clap; + +extern crate ini; +use ini::Ini; + use std::error::Error; use std::process::Stdio; use std::process::Command; pub struct CircadianError(String); +impl std::fmt::Display for CircadianError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} impl std::fmt::Debug for CircadianError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", self.0) } } +impl std::error::Error for CircadianError { + fn description(&self) -> &str { + self.0.as_str() + } + + fn cause(&self) -> Option<&std::error::Error> { + None + } +} impl From<std::io::Error> for CircadianError { fn from(error: std::io::Error) -> Self { CircadianError(error.description().to_owned())
@@ -61,6 +80,11 @@ impl From<glob::PatternError> for CircadianError { CircadianError(error.description().to_owned()) } } +impl From<ini::ini::Error> for CircadianError { + fn from(error: ini::ini::Error) -> Self { + CircadianError(error.description().to_owned()) + } +} type IdleResult = Result<u32, CircadianError>; type ThreshResult = Result<bool, CircadianError>;
@@ -260,8 +284,95 @@ fn exist_audio() -> ExistResult { Ok(count > 0) } +struct CircadianLaunchOptions { + config_file: String, + //script_dir: String, +} + +#[derive(Default,Debug)] +struct CircadianConfig { + idle_time: u64, + auto_wake: Option<String>, + on_idle: Option<String>, + on_wake: Option<String>, + tty_input: bool, + x11_input: bool, + ssh_block: bool, + smb_block: bool, + audio_block: bool, + max_cpu_load: Option<f64>, + process_block: Vec<String>, +} + +fn read_config(file_path: &str) -> Result<CircadianConfig, CircadianError> { + println!("Reading config from file: {}", file_path); + let i = Ini::load_from_file(file_path)?; + let mut config: CircadianConfig = Default::default(); + if let Some(section) = i.section(Some("actions".to_owned())) { + config.idle_time = section.get("idle_time") + .map_or(0, |x| if x.len() > 0 { + let (body,suffix) = x.split_at(x.len()-1); + let num: u64 = match suffix { + "m" => body.parse::<u64>().unwrap_or(0) * 60, + "h" => body.parse::<u64>().unwrap_or(0) * 60 * 60, + _ => x.parse::<u64>().unwrap_or(0), + }; + num + } else {0}); + config.auto_wake = section.get("auto_wake") + .and_then(|x| if x.len() > 0 {Some(x.to_owned())} else {None}); + config.on_idle = section.get("on_idle") + .and_then(|x| if x.len() > 0 {Some(x.to_owned())} else {None}); + config.on_wake = section.get("on_wake") + .and_then(|x| if x.len() > 0 {Some(x.to_owned())} else {None}); + } + fn read_bool(s: &std::collections::HashMap<String,String>, + key: &str) -> bool { + match s.get(key).unwrap_or(&"no".to_string()).to_lowercase().as_str() { + "yes" | "true" | "1" => true, + _ => false, + } + } + if let Some(section) = i.section(Some("heuristics".to_owned())) { + config.tty_input = read_bool(section, "tty_input"); + config.x11_input = read_bool(section, "x11_input"); + config.ssh_block = read_bool(section, "ssh_block"); + config.smb_block = read_bool(section, "smb_block"); + config.audio_block = read_bool(section, "audio_block"); + config.max_cpu_load = section.get("max_cpu_load") + .and_then(|x| if x.len() > 0 + {Some(x.parse::<f64>().unwrap_or(999.0))} else {None}); + if let Some(proc_str) = section.get("process_block") { + let proc_list = proc_str.split(","); + config.process_block = proc_list + .map(|x| x.trim().to_owned()).collect(); + } + } + Ok(config) +} + +fn read_cmdline() -> CircadianLaunchOptions { + let matches = clap::App::new("circadian") + .version(env!("CARGO_PKG_VERSION")) + .author(env!("CARGO_PKG_AUTHORS")) + .about(env!("CARGO_PKG_DESCRIPTION")) + .args_from_usage( + "-f, --config=[FILE] '' + -d, --script-dir=[DIR] ''") + .get_matches(); + let config = matches.value_of("config").unwrap_or("/etc/circadian.conf"); + //let script_dir = matches.value_of("script-dir").unwrap_or(""); + //println!("Script dir: {}", script_dir); + CircadianLaunchOptions { + config_file: config.to_owned(), + //script_dir: script_dir.to_owned(), + } +} + fn main() { - println!("Hello, world!"); + let launch_opts = read_cmdline(); + let config = read_config(&launch_opts.config_file); + println!("{:?}", config); println!("Sec: {:?}", parse_w_time("10.45s")); println!("Sec: {:?}", parse_w_time("1:11")); println!("Sec: {:?}", parse_w_time("0:10m"));