+ weekdays + includes/excludes + upd deps
This commit is contained in:
parent
529ca478b1
commit
4ced16e8da
82
Cargo.lock
generated
82
Cargo.lock
generated
@ -99,7 +99,7 @@ dependencies = [
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
"windows-core 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -123,9 +123,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
@ -142,7 +142,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "laika"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -266,23 +266,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.28.4"
|
||||
version = "0.33.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4c2f3ca6693feb29a89724516f016488e9aafc7f37264f898593ee4b942f31b"
|
||||
checksum = "4fc858248ea01b66f19d8e8a6d55f41deaf91e9d495246fd01368d99935c6c01"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"once_cell",
|
||||
"winapi",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.7.8"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
|
||||
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
@ -301,9 +300,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.19.15"
|
||||
version = "0.22.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
@ -398,6 +397,16 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core 0.57.0",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
@ -407,6 +416,49 @@ dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
@ -473,9 +525,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.40"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
||||
checksum = "ad699df48212c6cc6eb4435f35500ac6fd3b9913324f938aea302022ce19d310"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "laika"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
@ -8,10 +8,10 @@ edition = "2021"
|
||||
[dependencies]
|
||||
anyhow = "1.0.95"
|
||||
chrono = "0.4.24"
|
||||
itertools = "0.10.5"
|
||||
itertools = "0.14.0"
|
||||
serde = { version = "1.0.160", features = ["derive"] }
|
||||
sysinfo = { version = "0.28.4", default-features = false }
|
||||
toml = "0.7.3"
|
||||
sysinfo = { version = "0.33.1", default-features = false, features = ["system"]}
|
||||
toml = "0.8.19"
|
||||
|
||||
[profile.release]
|
||||
opt-level = "s"
|
||||
|
127
src/config.rs
Normal file
127
src/config.rs
Normal file
@ -0,0 +1,127 @@
|
||||
use crate::datetime::{LocalDate, TimeHM, Weekdays};
|
||||
use serde::Deserialize;
|
||||
use std::path::Path;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use std::{env, fs, path::PathBuf};
|
||||
|
||||
/// Application config
|
||||
#[derive(Deserialize, Default, Debug)]
|
||||
pub(crate) struct Config {
|
||||
/// modification time
|
||||
#[serde(skip)]
|
||||
pub(crate) modified: Option<SystemTime>,
|
||||
/// is application active
|
||||
#[serde(default = "default_true")]
|
||||
pub(crate) active: bool,
|
||||
/// need to exit
|
||||
#[serde(default)]
|
||||
pub(crate) exit_now: bool,
|
||||
/// target command
|
||||
pub(crate) command: String,
|
||||
/// target process name
|
||||
#[serde(default)]
|
||||
pub(crate) target: String,
|
||||
/// workdir for launch target command
|
||||
#[serde(default)]
|
||||
pub(crate) workdir: String,
|
||||
/// args for launch target command
|
||||
#[serde(default)]
|
||||
pub(crate) args: Option<Vec<String>>,
|
||||
/// weekdays (Mon,Tue,Wed | Пн,Вт,Ср)
|
||||
pub(crate) weekdays: Weekdays,
|
||||
/// exclude dates
|
||||
pub(crate) exclude_dates: Vec<LocalDate>,
|
||||
/// include dates
|
||||
pub(crate) include_dates: Vec<LocalDate>,
|
||||
/// start time
|
||||
pub(crate) start: TimeHM,
|
||||
/// end time
|
||||
pub(crate) end: TimeHM,
|
||||
/// check delay (seconds)
|
||||
pub(crate) delay: u32,
|
||||
}
|
||||
|
||||
fn default_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub(crate) fn read<P: AsRef<Path>>(path: P) -> Result<Self> {
|
||||
let data = fs::read_to_string(path).map_err(|e| anyhow!("can't read config: {:?}", e))?;
|
||||
toml::from_str(&data).map_err(|e| anyhow!("can't parse config: {:?}", e))
|
||||
}
|
||||
pub(crate) fn file_location() -> Result<PathBuf> {
|
||||
let res = env::current_exe()
|
||||
.map_err(|e| anyhow!("can't get current exe path: {:?}", e))?
|
||||
.with_extension("toml");
|
||||
Ok(res)
|
||||
}
|
||||
pub(crate) 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(mut cfg) => {
|
||||
let metadata = fs::metadata(&path);
|
||||
if let Ok(meta) = metadata {
|
||||
if let Ok(time) = meta.modified() {
|
||||
cfg.modified = Some(time);
|
||||
}
|
||||
}
|
||||
cfg
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) fn is_file_modified(&self) -> bool {
|
||||
if self.modified.is_none() {
|
||||
return true;
|
||||
}
|
||||
let path = Config::file_location();
|
||||
if let Err(_e) = path {
|
||||
return false;
|
||||
}
|
||||
let path = path.unwrap();
|
||||
let metadata = fs::metadata(path);
|
||||
let mut result = false;
|
||||
if let Ok(meta) = metadata {
|
||||
if let Ok(time) = meta.modified() {
|
||||
result = self.modified.unwrap() < time
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
pub(crate) fn reload(&mut self) {
|
||||
if !self.is_file_modified() {
|
||||
return;
|
||||
}
|
||||
|
||||
let new_cfg = Self::get();
|
||||
*self = new_cfg;
|
||||
}
|
||||
pub(crate) 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()
|
||||
}
|
||||
}
|
||||
pub(crate) fn is_valid(&self) -> bool {
|
||||
(!self.command.is_empty()) && self.delay > 0
|
||||
}
|
||||
}
|
184
src/datetime.rs
Normal file
184
src/datetime.rs
Normal file
@ -0,0 +1,184 @@
|
||||
use chrono::prelude::*;
|
||||
use chrono::{DateTime, Local, TimeZone};
|
||||
use itertools::Itertools;
|
||||
use serde::Deserialize;
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
|
||||
const WEEKDAYS_STR_EN: [&str; 7] = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
||||
const WEEKDAYS_STR_RU: [&str; 7] = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"];
|
||||
|
||||
/// Time with hours (24) and minutes (60)
|
||||
#[derive(Deserialize, Default, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug)]
|
||||
#[serde(try_from = "String")]
|
||||
pub(crate) struct TimeHM {
|
||||
/// hour num (0..23)
|
||||
hour: u8,
|
||||
/// minute num (0..59)
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for TimeHM {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
if let Some((str_hour, str_minute)) = s.split(':').collect_tuple() {
|
||||
let hour: u8 = str_hour.parse()?;
|
||||
let minute: u8 = str_minute.parse()?;
|
||||
Ok(TimeHM { hour, minute })
|
||||
} else {
|
||||
Err(anyhow!("invalid time, must be hh:mm"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for TimeHM {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
value.parse()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Default, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug)]
|
||||
#[serde(try_from = "String")]
|
||||
pub(crate) struct Weekdays {
|
||||
/// bits of weekdays
|
||||
bits: u8,
|
||||
}
|
||||
|
||||
impl FromStr for Weekdays {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
let mut bits: u8 = 0b10000000;
|
||||
|
||||
let mut has_invalid = false;
|
||||
let mut has_valid = false;
|
||||
|
||||
for &weekdays_str in [&WEEKDAYS_STR_EN, &WEEKDAYS_STR_RU] {
|
||||
let found = s.split(',').map(|p| {
|
||||
weekdays_str
|
||||
.iter()
|
||||
.find_position(|&&x| x.to_lowercase() == p.trim().to_lowercase())
|
||||
});
|
||||
|
||||
for item in found {
|
||||
if let Some((pos, _)) = item {
|
||||
bits |= 1 << pos;
|
||||
has_valid = true;
|
||||
} else {
|
||||
has_invalid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if has_valid || !has_invalid {
|
||||
Ok(Weekdays { bits })
|
||||
} else {
|
||||
Err(anyhow!("invalid time, must be hh:mm"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for Weekdays {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
value.parse()
|
||||
}
|
||||
}
|
||||
|
||||
impl Weekdays {
|
||||
pub(crate) fn is_weekday_enabled(&self, day: u8) -> bool {
|
||||
(self.bits >> day) & 1 == 1
|
||||
}
|
||||
|
||||
pub(crate) fn is_today_enabled(&self) -> bool {
|
||||
let now = Local::now();
|
||||
let day = now.weekday().num_days_from_monday();
|
||||
self.is_weekday_enabled(day as u8)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Weekdays {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut res = String::new();
|
||||
for (i, item) in WEEKDAYS_STR_EN.iter().enumerate() {
|
||||
if self.is_weekday_enabled(i as u8) {
|
||||
res.push_str(&format!("{},", item));
|
||||
}
|
||||
}
|
||||
res.pop();
|
||||
write!(f, "{}", res)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
|
||||
#[serde(try_from = "String")]
|
||||
pub(crate) struct LocalDate {
|
||||
inner: NaiveDate,
|
||||
}
|
||||
|
||||
impl Default for LocalDate {
|
||||
fn default() -> Self {
|
||||
LocalDate {
|
||||
inner: Local::now().date_naive(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for LocalDate {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.inner.format("%d.%m.%Y"))
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for LocalDate {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let date = NaiveDateTime::parse_from_str(s, "%d.%m.%Y")?;
|
||||
Ok(LocalDate { inner: date.date() })
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for LocalDate {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
value.parse()
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalDate {
|
||||
pub(crate) fn is_date(&self, value: NaiveDate) -> bool {
|
||||
self.inner == value
|
||||
}
|
||||
|
||||
pub(crate) fn is_date_of(&self, value: DateTime<Local>) -> bool {
|
||||
self.is_date(value.date_naive())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait HasToday {
|
||||
fn has_today(&self) -> bool;
|
||||
}
|
||||
|
||||
impl HasToday for Vec<LocalDate> {
|
||||
fn has_today(&self) -> bool {
|
||||
let now = Local::now();
|
||||
self.iter().any(|x| x.is_date_of(now))
|
||||
}
|
||||
}
|
190
src/main.rs
190
src/main.rs
@ -1,172 +1,13 @@
|
||||
#![windows_subsystem = "windows"]
|
||||
|
||||
use chrono::prelude::*;
|
||||
use chrono::{DateTime, Local, TimeZone};
|
||||
use itertools::Itertools;
|
||||
use serde::Deserialize;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use std::time::SystemTime;
|
||||
use std::{thread, time::Duration};
|
||||
use sysinfo::{System, SystemExt};
|
||||
use chrono::{DateTime, Local};
|
||||
use config::Config;
|
||||
use datetime::{HasToday, TimeHM};
|
||||
use std::{process::Command, thread, time::Duration};
|
||||
use sysinfo::{ProcessRefreshKind, RefreshKind, System, UpdateKind};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use std::{env, fs, path::PathBuf, process::Command};
|
||||
|
||||
/// Time with hours (24) and minutes (60)
|
||||
#[derive(Deserialize, Default, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug)]
|
||||
#[serde(try_from = "String")]
|
||||
struct TimeHM {
|
||||
/// hour num (0..23)
|
||||
hour: u8,
|
||||
/// minute num (0..59)
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for TimeHM {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
if let Some((str_hour, str_minute)) = s.split(':').collect_tuple() {
|
||||
let hour: u8 = str_hour.parse()?;
|
||||
let minute: u8 = str_minute.parse()?;
|
||||
Ok(TimeHM { hour, minute })
|
||||
} else {
|
||||
Err(anyhow!("invalid time, must be hh:mm"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for TimeHM {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
value.parse()
|
||||
}
|
||||
}
|
||||
|
||||
/// Application config
|
||||
#[derive(Deserialize, Default, Debug)]
|
||||
struct Config {
|
||||
/// modification time
|
||||
#[serde(skip)]
|
||||
modified: Option<SystemTime>,
|
||||
/// is application active
|
||||
#[serde(default = "default_true")]
|
||||
active: bool,
|
||||
/// need to exit
|
||||
#[serde(default)]
|
||||
exit_now: bool,
|
||||
/// target command
|
||||
command: String,
|
||||
/// target process name
|
||||
#[serde(default)]
|
||||
target: String,
|
||||
/// workdir for launch target command
|
||||
#[serde(default)]
|
||||
workdir: String,
|
||||
/// args for launch target command
|
||||
#[serde(default)]
|
||||
args: Option<Vec<String>>,
|
||||
/// start time
|
||||
start: TimeHM,
|
||||
/// end time
|
||||
end: TimeHM,
|
||||
/// check delay (seconds)
|
||||
delay: u32,
|
||||
}
|
||||
|
||||
fn default_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
impl Config {
|
||||
fn read<P: AsRef<Path>>(path: P) -> Result<Self> {
|
||||
let data = fs::read_to_string(path).map_err(|e| anyhow!("can't read config: {:?}", e))?;
|
||||
toml::from_str(&data).map_err(|e| anyhow!("can't parse config: {:?}", e))
|
||||
}
|
||||
fn file_location() -> Result<PathBuf> {
|
||||
let res = env::current_exe()
|
||||
.map_err(|e| anyhow!("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(mut cfg) => {
|
||||
let metadata = fs::metadata(&path);
|
||||
if let Ok(meta) = metadata {
|
||||
if let Ok(time) = meta.modified() {
|
||||
cfg.modified = Some(time);
|
||||
}
|
||||
}
|
||||
cfg
|
||||
}
|
||||
}
|
||||
}
|
||||
fn is_file_modified(&self) -> bool {
|
||||
if self.modified.is_none() {
|
||||
return true;
|
||||
}
|
||||
let path = Config::file_location();
|
||||
if let Err(_e) = path {
|
||||
return false;
|
||||
}
|
||||
let path = path.unwrap();
|
||||
let metadata = fs::metadata(path);
|
||||
let mut result = false;
|
||||
if let Ok(meta) = metadata {
|
||||
if let Ok(time) = meta.modified() {
|
||||
result = self.modified.unwrap() < time
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
fn reload(&mut self) {
|
||||
if !self.is_file_modified() {
|
||||
return;
|
||||
}
|
||||
|
||||
let new_cfg = Self::get();
|
||||
*self = new_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_valid(&self) -> bool {
|
||||
(!self.command.is_empty()) && self.delay > 0
|
||||
}
|
||||
}
|
||||
mod config;
|
||||
mod datetime;
|
||||
|
||||
struct Laika {
|
||||
config: Config,
|
||||
@ -179,9 +20,15 @@ impl From<Config> for Laika {
|
||||
}
|
||||
|
||||
impl Laika {
|
||||
fn is_in_time(&self, value: TimeHM) -> bool {
|
||||
self.config.start <= value && value <= self.config.end
|
||||
fn is_today_enabled(&self) -> bool {
|
||||
(self.config.weekdays.is_today_enabled() && !self.config.exclude_dates.has_today())
|
||||
|| self.config.include_dates.has_today()
|
||||
}
|
||||
|
||||
fn is_in_time(&self, value: TimeHM) -> bool {
|
||||
self.is_today_enabled() && self.config.start <= value && value <= self.config.end
|
||||
}
|
||||
|
||||
fn is_active(&self) -> bool {
|
||||
let now: DateTime<Local> = Local::now();
|
||||
self.config.active && self.config.is_valid() && self.is_in_time(now.into())
|
||||
@ -194,8 +41,11 @@ impl Laika {
|
||||
if name.is_empty() {
|
||||
return false;
|
||||
}
|
||||
let sp = System::new_all();
|
||||
let procs = sp.processes_by_exact_name(&name);
|
||||
let sp = System::new_with_specifics(
|
||||
RefreshKind::nothing()
|
||||
.with_processes(ProcessRefreshKind::nothing().with_exe(UpdateKind::OnlyIfNotSet)),
|
||||
);
|
||||
let procs = sp.processes_by_exact_name(name.as_ref());
|
||||
procs.count() > 0
|
||||
}
|
||||
fn relaunch_target(&self) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user