feat: handle interrupts cleanly
This commit is contained in:
parent
1a2cdf2c2f
commit
e3e734c39e
|
@ -121,6 +121,15 @@ dependencies = [
|
|||
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deflate"
|
||||
version = "0.7.18"
|
||||
|
@ -360,6 +369,18 @@ dependencies = [
|
|||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.12"
|
||||
|
@ -551,6 +572,7 @@ name = "screenshot_organiser"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"notify 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -750,6 +772,7 @@ dependencies = [
|
|||
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
|
||||
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
|
||||
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
||||
"checksum ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "630391922b1b893692c6334369ff528dcc3a9d8061ccf4c803aa8f83cb13db5e"
|
||||
"checksum deflate 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)" = "32c8120d981901a9970a3a1c97cf8b630e0fa8c3ca31e75b6fd6fd5f9f427b31"
|
||||
"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd"
|
||||
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
|
||||
|
@ -777,6 +800,7 @@ dependencies = [
|
|||
"checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e"
|
||||
"checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1"
|
||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||
"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17"
|
||||
"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79"
|
||||
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
||||
"checksum notify 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d023ef40ca7680784b07be3f49913e1ea176da1b63949f2eb2fed96438bd7f42"
|
||||
|
|
|
@ -20,3 +20,4 @@ failure = "0.1"
|
|||
tempdir = "0.3"
|
||||
num_cpus = "1"
|
||||
rayon = "1"
|
||||
ctrlc = "3"
|
||||
|
|
54
src/main.rs
54
src/main.rs
|
@ -1,4 +1,4 @@
|
|||
#![feature(rust_2018_preview, iterator_find_map, use_extern_macros)]
|
||||
#![feature(rust_2018_preview, iterator_find_map, use_extern_macros, mpsc_select)]
|
||||
|
||||
#[macro_use] extern crate serde_derive;
|
||||
|
||||
|
@ -20,34 +20,50 @@ use rayon::prelude::*;
|
|||
|
||||
use tempdir::TempDir;
|
||||
|
||||
use std::{fs::{self, DirEntry}, path::PathBuf, sync::mpsc};
|
||||
use std::{fs::{self, DirEntry}, path::PathBuf, sync::mpsc::{self, Receiver}};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
println!("Starting FFXIV Screenshot Organiser.");
|
||||
|
||||
let ctrlc_rx = set_ctrlc_handler()?;
|
||||
|
||||
let config_path = match std::env::args().nth(1) {
|
||||
Some(x) => x,
|
||||
None => "config.json".into(),
|
||||
};
|
||||
println!("Attempting to read config from `{}`.", config_path);
|
||||
|
||||
let f = fs::File::open(config_path)?;
|
||||
let config: Config = serde_json::from_reader(f)?;
|
||||
|
||||
println!("Config successfully read.");
|
||||
|
||||
let screenshots_dir = config.options.screenshots_dir.canonicalize()?;
|
||||
|
||||
println!("Screenshots are located at `{}`.", screenshots_dir.to_string_lossy());
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
||||
let temp_dir = TempDir::new("fso-")?;
|
||||
let temp_path = temp_dir.path().to_owned();
|
||||
println!("Storing temporary files in `{}`.", temp_path.to_string_lossy());
|
||||
|
||||
println!("Collecting existing files.");
|
||||
|
||||
let existing_files: Vec<DirEntry> = std::fs::read_dir(&screenshots_dir)?.collect::<std::result::Result<_, _>>()?;
|
||||
|
||||
println!("Processing {} existing file(s).", existing_files.len());
|
||||
|
||||
existing_files.into_par_iter().for_each(|entry| {
|
||||
if let Err(e) = handle(&config, temp_path.clone(), entry.path()) {
|
||||
eprintln!("{}", e);
|
||||
}
|
||||
});
|
||||
|
||||
println!("Done!");
|
||||
|
||||
let mut watcher = notify::watcher(
|
||||
tx,
|
||||
Duration::milliseconds(config.options.event_delay).to_std().unwrap(),
|
||||
|
@ -58,15 +74,26 @@ fn main() -> Result<()> {
|
|||
RecursiveMode::NonRecursive
|
||||
)?;
|
||||
|
||||
println!("Waiting for new files.");
|
||||
|
||||
loop {
|
||||
match rx.recv() {
|
||||
Ok(DebouncedEvent::Create(p)) => if let Err(e) = handle(&config, temp_path.clone(), p) {
|
||||
eprintln!("{}", e);
|
||||
},
|
||||
Ok(_) => {},
|
||||
Err(e) => eprintln!("{:#?}", e),
|
||||
select! {
|
||||
_ = ctrlc_rx.recv() => break,
|
||||
e = rx.recv() => {
|
||||
match e {
|
||||
Ok(DebouncedEvent::Create(p)) => if let Err(e) = handle(&config, temp_path.clone(), p) {
|
||||
eprintln!("{}", e);
|
||||
},
|
||||
Ok(_) => {},
|
||||
Err(e) => eprintln!("{:#?}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("Exiting.");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle(config: &Config, temp_dir: PathBuf, p: PathBuf) -> Result<()> {
|
||||
|
@ -119,3 +146,14 @@ fn parse_screenshot_name(config: &Config, s: &str) -> Option<DateTime<Utc>> {
|
|||
);
|
||||
Some(dt.with_timezone(&Utc))
|
||||
}
|
||||
|
||||
fn set_ctrlc_handler() -> Result<Receiver<()>> {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
||||
ctrlc::set_handler(move || {
|
||||
println!("Received interrupt.");
|
||||
tx.send(()).ok();
|
||||
})?;
|
||||
|
||||
Ok(rx)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue