shrupl/src/main.rs

164 lines
4.2 KiB
Rust
Raw Normal View History

2025-06-02 23:57:17 +00:00
mod appstate;
mod cachefile;
2025-05-28 00:07:59 +00:00
mod cli;
mod file;
2025-05-22 17:34:44 +00:00
mod sharry;
2025-06-05 01:44:39 +00:00
use std::{
process,
2025-06-05 01:44:39 +00:00
sync::{
Arc,
atomic::{AtomicBool, Ordering},
},
2025-06-05 01:34:12 +00:00
};
2025-05-27 14:01:09 +00:00
use clap::Parser;
use console::style;
2025-06-05 11:20:27 +00:00
use dialoguer::{Confirm, theme::ColorfulTheme};
2025-06-13 23:11:40 +00:00
use log::{error, info, trace};
2025-05-22 17:34:44 +00:00
2025-06-02 23:57:17 +00:00
use appstate::AppState;
2025-05-28 00:07:59 +00:00
use cli::Cli;
use sharry::ClientError;
2025-05-27 14:01:09 +00:00
fn print_error(e: &ClientError) {
if let Some(cause) = match e {
// known errors
ClientError::ResponseStatus {
actual: 403,
expected: _,
} => Some("Alias ID"),
ClientError::StdIo(_) => Some("URL"),
// unknown error
_ => None,
} {
// handle known error
info!("known error: {e:?}");
println!(
"{} probably wrong: {}",
style("Error!").red().bold(),
style(cause).cyan(),
);
println!("{}", style(e.to_string()).yellow().italic());
} else {
// handle unknown error
error!("unknown error: {e} ({e:?})");
println!("{}", style("Unknown Error!").red().bold());
}
}
2025-05-17 23:57:52 +00:00
fn main() {
env_logger::init();
2025-06-05 17:37:35 +00:00
println!(
"{} to {}!",
style("Welcome").magenta().bold(),
style("ShrUpl").yellow().bold(),
);
let check_ctrlc = {
let stop = Arc::new(AtomicBool::new(false));
let stop_ctrlc = stop.clone();
ctrlc::set_handler(move || {
stop_ctrlc.store(true, Ordering::SeqCst);
info!("stopping as soon as possible ...");
})
.expect("Error setting Ctrl-C handler");
2025-06-05 01:34:12 +00:00
move || {
if stop.load(Ordering::SeqCst) {
process::exit(255);
}
}
};
2025-05-22 17:34:44 +00:00
2025-05-28 00:07:59 +00:00
let args = Cli::parse();
info!("args: {args:?}");
2025-05-22 17:34:44 +00:00
2025-06-05 11:20:27 +00:00
let mut state = AppState::try_resume(&args)
.and_then(|state| {
Confirm::with_theme(&ColorfulTheme::default())
2025-06-05 17:37:35 +00:00
.with_prompt("Continue previously stopped operation?")
2025-06-05 11:20:27 +00:00
.default(true)
.interact()
.map_or(None, |b| b.then_some(state))
})
2025-06-05 12:58:09 +00:00
.unwrap_or_else(|| {
check_ctrlc();
2025-06-05 12:58:09 +00:00
match AppState::from_args(&args) {
2025-06-05 12:58:09 +00:00
Ok(state) => {
2025-06-12 23:28:42 +00:00
state.save().unwrap_or_else(|e| {
eprintln!(
"{} Failed to save {} state: {e}",
style("Warning:").red().bold(),
style("ShrUpl").yellow().bold(),
);
2025-06-12 23:28:42 +00:00
});
2025-06-05 12:58:09 +00:00
state
}
2025-06-05 12:58:09 +00:00
Err(e) => {
print_error(&e);
process::exit(1);
2025-06-05 12:58:09 +00:00
}
2025-06-05 11:20:27 +00:00
}
});
2025-06-04 21:02:35 +00:00
info!("continuing with state: {state:?}");
2025-06-05 17:37:35 +00:00
println!(
"{} uploading: {}",
style("ShrUpl").yellow().bold(),
style(state.file_names().join(", ")).magenta(),
);
let mut buffer = vec![0; args.chunk_size * 1024 * 1024];
2025-06-05 01:13:54 +00:00
loop {
match state.upload_chunk(&mut buffer) {
Err(e) => {
2025-06-13 23:11:40 +00:00
// HACK handle errors better (this will just retry endlessly)
error!("error: {e:?}");
if let Some(s) = state.rewind() {
state = s;
} else {
eprintln!("{} Failed to retry chunk!", style("Error:").red().bold());
process::exit(1);
2025-06-13 23:11:40 +00:00
}
}
Ok(false) => {
trace!("chunk uploaded");
}
Ok(true) => {
2025-06-05 11:20:27 +00:00
info!("all uploads done");
break;
}
}
2025-06-05 01:13:54 +00:00
2025-06-12 23:28:42 +00:00
state.save().unwrap_or_else(|e| {
eprintln!(
"{} Failed to save {} state: {e}",
style("Warning:").red().bold(),
style("ShrUpl").yellow().bold(),
);
2025-06-12 23:28:42 +00:00
});
check_ctrlc();
2025-05-26 20:31:22 +00:00
}
2025-06-13 23:02:41 +00:00
state.clear().unwrap_or_else(|e| {
eprintln!(
"{} Failed to remove {} state: {e}",
style("Warning:").red().bold(),
style("ShrUpl").yellow().bold(),
);
});
println!(
"{} finished {}",
style("ShrUpl").yellow().bold(),
style("successfully!").green()
);
2025-05-17 23:57:52 +00:00
}