From 5ffef562e39efc7201503dc2fa46584222a1e994 Mon Sep 17 00:00:00 2001 From: Tyce Herrman Date: Thu, 16 Jul 2026 18:03:19 -0400 Subject: [PATCH] feat: make refresh interval configurable (#28) --- README.md | 4 ++ docker/docker-compose.yml | 3 +- src/config.rs | 84 +++++++++++++++++++++++++++++++-------- src/main.rs | 14 +++---- 4 files changed, 80 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 9682bea..7d2531b 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ Environment=SATPAPER_RESOLUTION_X=2560 Environment=SATPAPER_RESOLUTION_Y=1440 Environment=SATPAPER_DISK_SIZE=94 Environment=SATPAPER_TARGET_PATH=/var/home/colonial/.local/share/backgrounds/ +Environment=SATPAPER_SLEEP_DURATION=60 ExecStart=/var/home/colonial/.cargo/bin/satpaper Restart=on-failure @@ -124,6 +125,8 @@ launchctl start $HOME/Library/LaunchAgents/com.satpaper.plist 94 SATPAPER_TARGET_PATH /Users/${YOUR_USERNAME}/.local/share/backgrounds/ + SATPAPER_SLEEP_DURATION + 60 ProgramArguments @@ -177,6 +180,7 @@ Thanks to `cyberbit`, everything you need to build and run a Satpaper Docker ima - `-w`/`--wallpaper-command`/`SATPAPER_WALLPAPER_COMMAND` - custom command to run when a wallpaper is generated. - This overrides the automatic update handling. - The command will be run as `sh -c "{command} file://{image_path}"`. +- `--sleep-duration`/`SATPAPER_SLEEP_DURATION` - seconds between checks for new imagery (default: `60`; must be positive). - `-o`/`--once`/`SATPAPER_ONCE` - whether or not to only run once. - By default, Satpaper is designed to run as a daemon - it stays resident once launched and periodically attempts to update your wallpaper. - With `--once` set, Satpaper will generate one wallpaper and terminate, without altering your existing wallpaper. diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index be93942..008c3dc 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -9,5 +9,6 @@ services: - SATPAPER_RESOLUTION_X=2560 - SATPAPER_RESOLUTION_Y=1440 - SATPAPER_DISK_SIZE=95 + - SATPAPER_SLEEP_DURATION=60 volumes: - - ../images:/home/rust/images \ No newline at end of file + - ../images:/home/rust/images diff --git a/src/config.rs b/src/config.rs index 47dd2f9..d19c394 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,17 +7,17 @@ use fimg::Image; #[command(author, version, about, long_about = None)] pub struct Config { /// The satellite to source imagery from. - /// + /// /// Options include: - /// + /// /// - GOES East (covers most of North and South America) - /// + /// /// - GOES West (Pacific Ocean and parts of the western US) - /// + /// /// - Himawari (Oceania and East Asia) - /// + /// /// - Meteosat 9 (Africa, Middle East, India, Central Asia) - /// + /// /// - Meteosat 10 (Atlantic Ocean, Africa, Europe) #[arg(short, long, env = "SATPAPER_SATELLITE")] pub satellite: Satellite, @@ -29,34 +29,42 @@ pub struct Config { pub resolution_y: u32, /// The size of the "disk" (Earth) relative to the generated wallpaper's /// smaller dimension. - /// + /// /// Values in the 90-95 range are the best if you want maximum detail. #[arg(short, long, value_parser = clap::value_parser!(u32).range(1..=100), env = "SATPAPER_DISK_SIZE")] pub disk_size: u32, /// Where generated wallpapers should be saved. - /// + /// /// Satpaper will output to a file called "satpaper_latest.png" at this path. #[arg(short, long, env = "SATPAPER_TARGET_PATH")] pub target_path: PathBuf, /// Command to run to change the wallpaper. This overrides automatic update handling. - /// - /// The command will be ran as `sh -c "{wallpaper_command} file://{path}"`. + /// + /// The command will be ran as `sh -c "{wallpaper_command} file://{path}"`. #[arg(short, long, env = "SATPAPER_WALLPAPER_COMMAND")] pub wallpaper_command: Option, + /// The number of seconds to wait between checks for new satellite imagery. + #[arg( + long, + env = "SATPAPER_SLEEP_DURATION", + default_value_t = 60, + value_parser = clap::value_parser!(u64).range(1..) + )] + pub sleep_duration: u64, /// Whether or not to only run once. - /// + /// /// By default, Satpaper is designed to run in the background - it stays resident once launched /// and periodically attempts to update your wallpaper. - /// + /// /// With --once set, Satpaper will instead generate one wallpaper and terminate, without /// affecting your existing wallpaper or staying resident. - /// + /// /// This is ideal if you want to use Satpaper as a simple wallpaper generator or as part of a larger script/program. #[arg(short, long, env = "SATPAPER_ONCE", default_value_t = false)] pub once: bool, /// A background image to use instead of the default pure black. - /// - /// For best results, the image should match the specified resolution, + /// + /// For best results, the image should match the specified resolution, /// but Satpaper will resize the image to fit if need be. #[arg(short, long, env = "SATPAPER_BACKGROUND_IMAGE")] pub background_image: Option, @@ -89,7 +97,7 @@ impl Satellite { GOESWest => "goes-18", Himawari => "himawari", Meteosat9 => "meteosat-9", - Meteosat10 => "meteosat-0deg" + Meteosat10 => "meteosat-0deg", } } @@ -124,4 +132,46 @@ impl Satellite { Meteosat9 | Meteosat10 => 464, } } -} \ No newline at end of file +} + +#[cfg(test)] +mod tests { + use super::*; + + fn required_args() -> Vec<&'static str> { + vec![ + "satpaper", + "--satellite", + "goes-east", + "--resolution-x", + "1920", + "--resolution-y", + "1080", + "--disk-size", + "95", + "--target-path", + ".", + ] + } + + #[test] + fn sleep_duration_uses_default_and_cli_override() { + let config = Config::try_parse_from(required_args()).unwrap(); + assert_eq!(config.sleep_duration, 60); + + let mut args = required_args(); + args.extend(["--sleep-duration", "300"]); + let config = Config::try_parse_from(args).unwrap(); + assert_eq!(config.sleep_duration, 300); + } + + #[test] + fn sleep_duration_rejects_zero() { + let mut args = required_args(); + args.extend(["--sleep-duration", "0"]); + + let error = Config::try_parse_from(args).unwrap_err(); + + assert_eq!(error.kind(), clap::error::ErrorKind::ValueValidation); + } +} diff --git a/src/main.rs b/src/main.rs index ebdfea7..41cc61c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,8 +4,7 @@ mod config; mod slider; mod wallpaper; -use std::time::Duration; -use std::thread::sleep; +use std::{thread::sleep, time::Duration}; use anyhow::{Result, Context}; use clap::Parser; @@ -13,7 +12,6 @@ use clap::Parser; use crate::config::*; const OUTPUT_NAME: &str = "satpaper_latest.png"; -const SLEEP_DURATION: Duration = Duration::from_secs(60); fn main() -> Result<()> { if std::env::var("RUST_LOG").is_err() { @@ -30,6 +28,7 @@ fn main() -> Result<()> { fn update_wallpaper() -> Result<()> { let config = Config::parse(); + let sleep_duration = Duration::from_secs(config.sleep_duration); let mut timestamp = None; @@ -66,9 +65,9 @@ fn update_wallpaper() -> Result<()> { } } - log::debug!("Sleeping for {SLEEP_DURATION:?}..."); + log::debug!("Sleeping for {sleep_duration:?}..."); - sleep(SLEEP_DURATION); + sleep(sleep_duration); } #[allow(unreachable_code)] @@ -88,8 +87,9 @@ mod tests { disk_size: 95, target_path: ".".into(), wallpaper_command: None, + sleep_duration: 60, once: false, - background_image: None + background_image: None, }; slider::composite_latest_image(&config)?; @@ -98,4 +98,4 @@ mod tests { Ok(()) } -} \ No newline at end of file +}