From 46089770885759ae20b247e797020ed4bf33d591 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Tue, 11 May 2021 12:24:27 +0800 Subject: [PATCH] working prototype Signed-off-by: Sean Cross --- Cargo.lock | 12 ++++++- Cargo.toml | 7 ++-- src/main.rs | 97 +++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 85 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9cbec32..6d0a6b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,11 +113,12 @@ dependencies = [ ] [[package]] -name = "lark-killer" +name = "larkinator" version = "0.1.0" dependencies = [ "chrono", "sysinfo", + "winreg", "winrt-notification", ] @@ -411,6 +412,15 @@ dependencies = [ "syn", ] +[[package]] +name = "winreg" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d107f8c6e916235c4c01cabb3e8acf7bea8ef6a63ca2e7fa0527c049badfc48c" +dependencies = [ + "winapi", +] + [[package]] name = "winrt-notification" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index d69f035..85fddeb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,12 @@ [package] authors = ["Sean Cross "] -description = "Terminate Lark when it's not office hours" +description = "Terminator for Lark when it's not office hours" edition = "2018" -name = "lark-killer" +name = "larkinator" version = "0.1.0" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] chrono = "0.4" sysinfo = "0.17" +winreg = "0.8" winrt-notification = "0.3" diff --git a/src/main.rs b/src/main.rs index 86e9474..7948fca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,12 @@ -fn make_holidays() -> std::collections::BTreeMap, &'static str> { - use chrono::offset::TimeZone; - use chrono::Local; - let mut holidays = std::collections::BTreeMap::new(); +use chrono::{Date, Local, TimeZone}; +use std::collections::BTreeMap; +use std::path::{Path, PathBuf}; +use sysinfo::{ProcessExt, SystemExt}; +use winreg::{RegValue, types::FromRegValue}; +use winrt_notification::{Duration, Sound, Toast}; + +fn make_holidays() -> BTreeMap, &'static str> { + let mut holidays = BTreeMap::new(); holidays.insert(Local.ymd(2021, 1, 1), "New Year's Day"); holidays.insert(Local.ymd(2021, 2, 12), "Chinese New Year"); @@ -30,7 +35,6 @@ fn make_holidays() -> std::collections::BTreeMap, &' } fn process_is_running(name: &str) -> bool { - use sysinfo::{ProcessExt, SystemExt}; // First we update all information of our system struct. let mut system = sysinfo::System::new_all(); system.refresh_all(); @@ -44,7 +48,6 @@ fn process_is_running(name: &str) -> bool { fn try_terminating(name: &str) -> Option { let mut process_path = None; - use sysinfo::{ProcessExt, SystemExt}; // First we update all information of our system struct. let mut system = sysinfo::System::new_all(); @@ -79,18 +82,60 @@ fn is_working_hours(date_time: &T) -> bo date_time.hour() >= 9 && date_time.hour() <= 18 } +fn get_lark_path() -> Option { + use winreg::enums::*; + use winreg::RegKey; + let hkcu = RegKey::predef(HKEY_CURRENT_USER); + let lark_cfg = match hkcu.open_subkey("SOFTWARE\\Ion\\Larkinator") { + Ok(v) => Some(v), + Err(_) => None, + }?; + let v: std::io::Result = lark_cfg.get_raw_value("Lark Path"); + let mut buf = v.unwrap(); + // Strip off NULL termination + buf.bytes.pop(); + buf.bytes.pop(); + let osstr = std::ffi::OsString::from_reg_value(&buf).unwrap(); + Some(Path::new(&osstr).to_owned()) + // match v { + // Ok(v) => { + // print!("Values: "); + // use std::os::windows::ffi::OsStrExt; + // for (_idx, c) in v.encode_wide().enumerate() { + // print!(" {:04x}", c); + // } + // println!(); + + // let converted: PathBuf = v.into(); + // Some(converted.to_owned()) + // } + // Err(_) => None, + // } + // None +} + +fn set_lark_path(new_path: &Path) -> std::io::Result<()> { + use winreg::enums::*; + use winreg::RegKey; + let hkcu = RegKey::predef(HKEY_CURRENT_USER); + let (key, _disp) = hkcu.create_subkey("SOFTWARE\\Ion\\Larkinator")?; + key.set_value("Lark Path", &new_path.as_os_str())?; + Ok(()) +} + fn main() { - use chrono::Local; - use winrt_notification::{Duration, Sound, Toast}; - let mut process_path: Option = None; let process_name = "Lark.exe"; loop { let local = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00` let should_be_running = is_working_hours(&local); - if let Some(p) = &process_path { - if should_be_running && !process_is_running(process_name) { - println!("Running Lark!"); + let is_running = process_is_running(process_name); + // println!("Should? {} Running? {}", should_be_running, is_running); + if should_be_running && !is_running { + println!("Running Lark!"); + if let Some(p) = get_lark_path() { + println!("Lark path: {}", p.display()); + std::process::Command::new(p) .spawn() .expect("Couldn't run Lark!"); @@ -102,22 +147,22 @@ fn main() { .duration(Duration::Short) .show() .expect("unable to toast"); + } else { + println!("Would run Lark, but no path found"); } - } else { - if !should_be_running && process_is_running(process_name) { - println!("Terminating Lark, since it should't be running"); - process_path = try_terminating(process_name); - if process_path.is_some() { - Toast::new(Toast::POWERSHELL_APP_ID) - .title("Terminated Lark") - .text1("Lark was terminated because it is outside working hours") - .sound(Some(Sound::SMS)) - .duration(Duration::Short) - .show() - .expect("unable to toast"); - } + } else if !should_be_running && is_running { + println!("Terminating Lark, since it should't be running"); + if let Some(p) = try_terminating(process_name) { + set_lark_path(&p).ok(); + Toast::new(Toast::POWERSHELL_APP_ID) + .title("Terminated Lark") + .text1("Lark was terminated because it is outside working hours") + .sound(Some(Sound::SMS)) + .duration(Duration::Short) + .show() + .expect("unable to toast"); } } - std::thread::sleep(std::time::Duration::from_secs(100)); + std::thread::sleep(std::time::Duration::from_secs(3)); } }