working prototype
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
9b1630d71c
commit
4608977088
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -113,11 +113,12 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lark-killer"
|
name = "larkinator"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
|
"winreg",
|
||||||
"winrt-notification",
|
"winrt-notification",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -411,6 +412,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winreg"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d107f8c6e916235c4c01cabb3e8acf7bea8ef6a63ca2e7fa0527c049badfc48c"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winrt-notification"
|
name = "winrt-notification"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
authors = ["Sean Cross <sean@xobs.io>"]
|
authors = ["Sean Cross <sean@xobs.io>"]
|
||||||
description = "Terminate Lark when it's not office hours"
|
description = "Terminator for Lark when it's not office hours"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "lark-killer"
|
name = "larkinator"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
sysinfo = "0.17"
|
sysinfo = "0.17"
|
||||||
|
winreg = "0.8"
|
||||||
winrt-notification = "0.3"
|
winrt-notification = "0.3"
|
||||||
|
97
src/main.rs
97
src/main.rs
@ -1,7 +1,12 @@
|
|||||||
fn make_holidays() -> std::collections::BTreeMap<chrono::Date<chrono::Local>, &'static str> {
|
use chrono::{Date, Local, TimeZone};
|
||||||
use chrono::offset::TimeZone;
|
use std::collections::BTreeMap;
|
||||||
use chrono::Local;
|
use std::path::{Path, PathBuf};
|
||||||
let mut holidays = std::collections::BTreeMap::new();
|
use sysinfo::{ProcessExt, SystemExt};
|
||||||
|
use winreg::{RegValue, types::FromRegValue};
|
||||||
|
use winrt_notification::{Duration, Sound, Toast};
|
||||||
|
|
||||||
|
fn make_holidays() -> BTreeMap<Date<Local>, &'static str> {
|
||||||
|
let mut holidays = BTreeMap::new();
|
||||||
|
|
||||||
holidays.insert(Local.ymd(2021, 1, 1), "New Year's Day");
|
holidays.insert(Local.ymd(2021, 1, 1), "New Year's Day");
|
||||||
holidays.insert(Local.ymd(2021, 2, 12), "Chinese New Year");
|
holidays.insert(Local.ymd(2021, 2, 12), "Chinese New Year");
|
||||||
@ -30,7 +35,6 @@ fn make_holidays() -> std::collections::BTreeMap<chrono::Date<chrono::Local>, &'
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn process_is_running(name: &str) -> bool {
|
fn process_is_running(name: &str) -> bool {
|
||||||
use sysinfo::{ProcessExt, SystemExt};
|
|
||||||
// First we update all information of our system struct.
|
// First we update all information of our system struct.
|
||||||
let mut system = sysinfo::System::new_all();
|
let mut system = sysinfo::System::new_all();
|
||||||
system.refresh_all();
|
system.refresh_all();
|
||||||
@ -44,7 +48,6 @@ fn process_is_running(name: &str) -> bool {
|
|||||||
|
|
||||||
fn try_terminating(name: &str) -> Option<std::path::PathBuf> {
|
fn try_terminating(name: &str) -> Option<std::path::PathBuf> {
|
||||||
let mut process_path = None;
|
let mut process_path = None;
|
||||||
use sysinfo::{ProcessExt, SystemExt};
|
|
||||||
|
|
||||||
// First we update all information of our system struct.
|
// First we update all information of our system struct.
|
||||||
let mut system = sysinfo::System::new_all();
|
let mut system = sysinfo::System::new_all();
|
||||||
@ -79,18 +82,60 @@ fn is_working_hours<T: chrono::Datelike + chrono::Timelike>(date_time: &T) -> bo
|
|||||||
date_time.hour() >= 9 && date_time.hour() <= 18
|
date_time.hour() >= 9 && date_time.hour() <= 18
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_lark_path() -> Option<PathBuf> {
|
||||||
|
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<RegValue> = 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() {
|
fn main() {
|
||||||
use chrono::Local;
|
|
||||||
use winrt_notification::{Duration, Sound, Toast};
|
|
||||||
let mut process_path: Option<std::path::PathBuf> = None;
|
|
||||||
let process_name = "Lark.exe";
|
let process_name = "Lark.exe";
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let local = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00`
|
let local = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00`
|
||||||
let should_be_running = is_working_hours(&local);
|
let should_be_running = is_working_hours(&local);
|
||||||
if let Some(p) = &process_path {
|
let is_running = process_is_running(process_name);
|
||||||
if should_be_running && !process_is_running(process_name) {
|
// println!("Should? {} Running? {}", should_be_running, is_running);
|
||||||
println!("Running Lark!");
|
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)
|
std::process::Command::new(p)
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("Couldn't run Lark!");
|
.expect("Couldn't run Lark!");
|
||||||
@ -102,22 +147,22 @@ fn main() {
|
|||||||
.duration(Duration::Short)
|
.duration(Duration::Short)
|
||||||
.show()
|
.show()
|
||||||
.expect("unable to toast");
|
.expect("unable to toast");
|
||||||
|
} else {
|
||||||
|
println!("Would run Lark, but no path found");
|
||||||
}
|
}
|
||||||
} else {
|
} else if !should_be_running && is_running {
|
||||||
if !should_be_running && process_is_running(process_name) {
|
println!("Terminating Lark, since it should't be running");
|
||||||
println!("Terminating Lark, since it should't be running");
|
if let Some(p) = try_terminating(process_name) {
|
||||||
process_path = try_terminating(process_name);
|
set_lark_path(&p).ok();
|
||||||
if process_path.is_some() {
|
Toast::new(Toast::POWERSHELL_APP_ID)
|
||||||
Toast::new(Toast::POWERSHELL_APP_ID)
|
.title("Terminated Lark")
|
||||||
.title("Terminated Lark")
|
.text1("Lark was terminated because it is outside working hours")
|
||||||
.text1("Lark was terminated because it is outside working hours")
|
.sound(Some(Sound::SMS))
|
||||||
.sound(Some(Sound::SMS))
|
.duration(Duration::Short)
|
||||||
.duration(Duration::Short)
|
.show()
|
||||||
.show()
|
.expect("unable to toast");
|
||||||
.expect("unable to toast");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::thread::sleep(std::time::Duration::from_secs(100));
|
std::thread::sleep(std::time::Duration::from_secs(3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user