initial commit
This commit is contained in:
127
src/main.rs
Normal file
127
src/main.rs
Normal file
@@ -0,0 +1,127 @@
|
||||
//#![windows_subsystem = "windows"]
|
||||
|
||||
use chrono::prelude::*;
|
||||
use chrono::{DateTime, Local, TimeZone};
|
||||
use serde::Deserialize;
|
||||
use std::path::Path;
|
||||
use std::{thread, time::Duration};
|
||||
use sysinfo::{System, SystemExt};
|
||||
|
||||
use std::{env, fs, path::PathBuf, process::Command};
|
||||
|
||||
#[derive(Deserialize, Default, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug)]
|
||||
struct TimeHM {
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
}
|
||||
|
||||
impl<Tz: TimeZone> From<DateTime<Tz>> for TimeHM {
|
||||
fn from(value: DateTime<Tz>) -> TimeHM {
|
||||
TimeHM {
|
||||
hour: value.hour() as u8,
|
||||
minute: value.minute() as u8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Default)]
|
||||
struct Config {
|
||||
command: String,
|
||||
target: String,
|
||||
workdir: String,
|
||||
args: Option<Vec<String>>,
|
||||
start: TimeHM,
|
||||
end: TimeHM,
|
||||
delay: u32,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
fn read<P: AsRef<Path>>(path: P) -> Result<Self, String> {
|
||||
let data = fs::read_to_string(path).map_err(|e| format!("can't read config: {:?}", e))?;
|
||||
toml::from_str(&data).map_err(|e| format!("can't parse config: {:?}", e))
|
||||
}
|
||||
fn file_location() -> Result<PathBuf, String> {
|
||||
let res = env::current_exe()
|
||||
.map_err(|e| format!("can't get current exe path: {:?}", e))?
|
||||
.with_extension("toml");
|
||||
Ok(res)
|
||||
}
|
||||
fn get() -> Self {
|
||||
let path = Config::file_location();
|
||||
if let Err(_e) = path {
|
||||
//println!("{}", _e);
|
||||
return Config::default();
|
||||
}
|
||||
|
||||
let path = path.unwrap();
|
||||
let cfg = Config::read(path);
|
||||
match cfg {
|
||||
Err(_e) => {
|
||||
//println!("{}", _e);
|
||||
Config::default()
|
||||
}
|
||||
Ok(cfg) => cfg,
|
||||
}
|
||||
}
|
||||
fn target_name(&self) -> String {
|
||||
if !self.target.is_empty() {
|
||||
self.target.clone()
|
||||
} else {
|
||||
PathBuf::from(self.command.clone())
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
fn is_in_time(&self, value: TimeHM) -> bool {
|
||||
dbg!(value);
|
||||
dbg!(self.start <= value && value <= self.end);
|
||||
self.start <= value && value <= self.end
|
||||
}
|
||||
fn is_active(&self) -> bool {
|
||||
let now: DateTime<Local> = Local::now();
|
||||
self.is_in_time(now.into())
|
||||
}
|
||||
fn sleep(&self) {
|
||||
thread::sleep(Duration::from_secs(self.delay.into()));
|
||||
}
|
||||
fn is_target_alive(&self) -> bool {
|
||||
let name = self.target_name();
|
||||
dbg!(&name);
|
||||
let sp = System::new_all();
|
||||
let procs = sp.processes_by_exact_name(&name);
|
||||
let count = procs.count();
|
||||
dbg!(count);
|
||||
count > 0
|
||||
}
|
||||
fn relaunch_target(&self) {
|
||||
dbg!(&self.command);
|
||||
let mut cmd = Command::new(&self.command);
|
||||
cmd.current_dir(&self.workdir);
|
||||
if let Some(args) = &self.args {
|
||||
cmd.args(args);
|
||||
}
|
||||
let _res = cmd.spawn();
|
||||
}
|
||||
fn is_valid(&self) -> bool {
|
||||
(!self.command.is_empty()) && self.delay > 0
|
||||
}
|
||||
fn main_loop(self) {
|
||||
dbg!(self.is_valid());
|
||||
if !self.is_valid() {
|
||||
return;
|
||||
}
|
||||
loop {
|
||||
if self.is_active() && !self.is_target_alive() {
|
||||
self.relaunch_target();
|
||||
}
|
||||
self.sleep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
Config::get().main_loop()
|
||||
}
|
Reference in New Issue
Block a user