diff --git a/Cargo.lock b/Cargo.lock index 5659164..dc2ec80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.4" @@ -50,6 +65,47 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + [[package]] name = "clap" version = "4.4.7" @@ -96,6 +152,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + [[package]] name = "deranged" version = "0.3.9" @@ -109,6 +171,7 @@ dependencies = [ name = "ewwtilities" version = "0.1.0" dependencies = [ + "chrono", "clap", "log", "serde", @@ -122,12 +185,44 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "itoa" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "js-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "libc" version = "0.2.150" @@ -140,6 +235,15 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + [[package]] name = "num_threads" version = "0.1.6" @@ -149,6 +253,12 @@ dependencies = [ "libc", ] +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + [[package]] name = "powerfmt" version = "0.2.0" @@ -290,6 +400,60 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "wasm-bindgen" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" + [[package]] name = "winapi" version = "0.3.9" @@ -321,6 +485,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/ewwtilities/Cargo.toml b/ewwtilities/Cargo.toml index a2f7bd7..b1679a4 100644 --- a/ewwtilities/Cargo.toml +++ b/ewwtilities/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +chrono = "0.4.31" clap = { version = "4.4.7", features = ["derive"] } log = "0.4.20" serde = { version = "1.0.192", features = ["derive"] } diff --git a/ewwtilities/src/calendar_background.rs b/ewwtilities/src/calendar_background.rs new file mode 100644 index 0000000..d4e66f0 --- /dev/null +++ b/ewwtilities/src/calendar_background.rs @@ -0,0 +1,192 @@ +use chrono::offset::Local; +use chrono::Timelike; +use log::{debug, error}; +use serde::{Deserialize, Serialize}; +use std::io::stdin; +use std::io::IsTerminal; + +use crate::CliArgs; +// use serde_json; + +pub fn run_calendar(args: &CliArgs) { + let in_pipe = stdin(); + if in_pipe.is_terminal() { + error!("Calendar Background process requires an input redirection (use a pipe)"); + panic!("Expected to be used with a pipe, but was not"); + } + + let (mut moonrise, mut moonset, mut moonday, mut sunrise, mut sunset): ( + Option<(u32, u32)>, + Option<(u32, u32)>, + Option<(u32, u32)>, + Option<(u32, u32)>, + Option<(u32, u32)>, + ) = (None, None, None, None, None); + let moonphase: Option = None; + + let mut false_empty_count = 0; + loop { + let mut buffer = String::new(); + + let bytes = in_pipe.read_line(&mut buffer).unwrap(); + if bytes == 0 { + false_empty_count += 1; + if false_empty_count < 3 { + continue; + } + break; + } + if buffer.len() < 27 { + continue; + } + let value = buffer[21..].to_string(); + + if value.starts_with("Moonrise") { + moonrise = parse_time(value[8..].trim(), args.debug); + } else if value.starts_with("Moonset") { + moonset = parse_time(value[7..].trim(), args.debug); + } else if value.starts_with("Moonday") { + moonday = parse_time(value[7..].trim(), args.debug); + } else if value.starts_with("Moonphase") { + let moonphase = match value[9..].trim()[0..2].parse::() { + Ok(val) => Some(val), + Err(e) => { + if args.debug { + debug!("Error parsing: {e}"); + } + None + } + }; + } else if value.starts_with("Sunrise") { + sunrise = parse_time(value[7..].trim(), args.debug); + } else if value.starts_with("Sunset") { + sunset = parse_time(value[6..].trim(), args.debug); + } else { + continue; + } + } + + if moonrise.is_none() + && moonset.is_none() + && moonphase.is_none() + && sunrise.is_none() + && sunset.is_none() + { + error!("No values were recieved from gcal. Exiting"); + panic!("No values were provided by gcal. Call with --debug to see what values were parsed"); + } + + let mut output_state = CalandarState { + has_bg: false, + is_sun: false, + gradient_angle: 0, + }; + + let (now_hr, now_min) = (Local::now().hour(), Local::now().minute()); + + if sunrise.is_none() { + sunrise = Some((8, 0)); + } + if sunset.is_none() { + sunset = Some((18, 0)); + } + + let sun_rise = sunrise.clone().unwrap(); + let sun_set = sunset.clone().unwrap(); + if now_hr > sun_rise.0 && now_min > sun_rise.1 && now_hr < sun_set.0 && now_min < sun_set.1 { + // it is after sunrise, and before sunset + output_state.has_bg = true; + output_state.is_sun = true; + output_state.gradient_angle = { + let sunrise_mins = sun_rise.0 * 60 + sun_rise.1; + (((now_hr * 60 + now_min) - sunrise_mins) as f32 + / ((sun_set.0 * 60 + sun_set.1) - sunrise_mins) as f32) + .floor() as i32 + }; + } else { + // Check if the moon is up + if moonrise.is_some() { + let (moonrise_hr, moonrise_min) = moonrise.clone().unwrap(); + if moonset.is_some() { + let (moonset_hr, moonset_min) = moonset.clone().unwrap(); + if now_hr > moonrise_hr + && now_min > moonrise_min + && now_hr < moonset_hr + && now_min < moonset_min + { + // moon is up + output_state.has_bg = true; + output_state.is_sun = false; + } + } else { + if now_hr > moonrise_hr && now_min > moonrise_hr { + output_state.has_bg = true; + output_state.is_sun = false; + } + } + } else { + if moonset.is_some() { + let (moonset_hr, moonset_min) = moonset.clone().unwrap(); + if now_hr < moonset_hr && now_min < moonset_min { + // moon is up + output_state.has_bg = true; + output_state.is_sun = false; + } + } + } + + if output_state.has_bg == true && output_state.is_sun == false { + // moon is up, get the position + if moonrise.is_some() { + let (moonrise_hr, moonrise_min) = moonrise.clone().unwrap(); + let (moonday_hrs, moonday_mins) = moonday.clone().unwrap(); + + output_state.gradient_angle = { + (((now_hr * 60 + now_min) - (moonrise_hr * 60 + moonrise_min)) as f32 + / (moonday_hrs * 60 + moonday_mins) as f32) as i32 + }; + } else { + let (moonset_hr, moonset_min) = moonset.clone().unwrap(); + let (moonday_hrs, moonday_mins) = moonday.clone().unwrap(); + let begin_mins: i32 = (moonset_hr as i32 - moonday_hrs as i32) * 60 + (moonset_min as i32 - moonday_mins as i32); + let time_since_rise = (now_hr * 60 + now_min) as i32 + (begin_mins.abs()); + output_state.gradient_angle = (time_since_rise as f32 / (moonset_hr * 60 + moonset_min) as f32) as i32; + + } + } + } + + println!("{}", serde_json::to_string(&output_state).unwrap()); +} + +fn parse_time(i: &str, do_debug: bool) -> Option<(u32, u32)> { + if do_debug { + debug!("parsing: {}", i); + } + let hr = match i[0..2].parse::() { + Ok(val) => val, + Err(e) => { + if do_debug { + debug!("Error parsing: {e}"); + } + return None; + } + }; + let min = match i[3..5].parse::() { + Ok(val) => val, + Err(e) => { + if do_debug { + debug!("Error parsing: {e}"); + } + return None; + } + }; + Some((hr, min)) +} + +#[derive(Serialize, Deserialize)] +struct CalandarState { + pub has_bg: bool, + pub is_sun: bool, + pub gradient_angle: i32, +} diff --git a/ewwtilities/src/main.rs b/ewwtilities/src/main.rs index 659de5c..58390ef 100644 --- a/ewwtilities/src/main.rs +++ b/ewwtilities/src/main.rs @@ -1,25 +1,21 @@ use clap::{Parser, ValueEnum}; -use serde_json; -use log::{error, debug}; -use serde::{Serialize, Deserialize}; -use std::process::Command; -use std::env; + +mod calendar_background; +use calendar_background::run_calendar; #[derive(ValueEnum, Debug, Clone)] enum ProcessType { - CalBckgrn + CalendarBackground, } #[derive(Parser, Debug)] #[command(author, version, about, long_about=None)] -struct CliArgs { - +pub struct CliArgs { #[arg(index = 1, value_enum)] action: Option, #[arg(short, long)] debug: bool, - } fn main() -> Result<(), Box> { @@ -33,27 +29,16 @@ fn main() -> Result<(), Box> { simplelog::Config::default(), )?; + match args + .action + .clone() + .expect("`action` parameter required when calling command") + { + ProcessType::CalendarBackground => { + run_calendar(&args); + } + } + println!("Hello, world!"); Ok(()) } - - -fn run_calendar(args: &CliArgs) { - let home = match env::var("HOME") { - Ok(val) => val, - Err(e) => { - error!("Unable to read HOME environment var"); - panic!("{e}"); - } - }; - - -} - - -#[derive(Serialize, Deserialize)] -struct CalandarState { - pub has_bg: bool, - pub is_sun: bool, - pub gradient_angle: i32, -}