index : gmss.git

ascending towards madness

use std::path::PathBuf;

use chrono::{DateTime, Local, Utc};
use clap::Parser;
use imaging::Renderer;

mod cli;
mod graphics;
mod imaging;

fn main() {
    let args = cli::Args::parse();

    capture_all_displays(args.out);
}

/// Captures a screenshot of all active displays and writes the resulting image to disk.
fn capture_all_displays(filename: String) {
    let captures: Vec<_> = graphics::Display::get_displays()
        .iter()
        .filter_map(|screen| screen.capture().ok())
        .collect();

    let img = Renderer::stitch_horizontally(captures);

    if !img.is_empty() {
        let timestamp: DateTime<Local> = Utc::now().with_timezone(&Local);
        const FILENAME_FORMAT: &str = "screenshot-%Y-%m-%d_%H-%M-%S.png";

        let mut path = PathBuf::from(timestamp.format(&filename).to_string());
        if path.is_dir() {
            path = path.join(timestamp.format(FILENAME_FORMAT).to_string());
        }

        match img.save(generate_filename(&path)) {
            Ok(_) => println!("screenshot saved successfully!"),
            Err(err) => println!("there was an error saving the image: {:?}", err),
        }
    }
}

/// Generate a new filename if a file already exists at the target.
///
/// If the file exists, the format of `<FILENAME>_<NUM>.<EXT>` will be generated.
///
/// eg. `my_screenshot-2023-12-20.png` becomes `my_screenshot-2023-12-20_1.png`
fn generate_filename(filename: &PathBuf) -> PathBuf {
    let mut index = 0;
    let mut new_filename = filename.clone();

    let extension = filename
        .extension()
        .map(|ext| format!(".{}", ext.to_string_lossy()))
        .unwrap_or_default();

    while new_filename.exists() {
        index += 1;
        new_filename.set_file_name(format!(
            "{}_{}{}",
            filename.file_stem().unwrap().to_string_lossy(),
            index,
            extension
        ));
    }

    new_filename
}