93 lines
2.5 KiB
Rust
93 lines
2.5 KiB
Rust
mod appstate;
|
||
mod cli;
|
||
mod sharry;
|
||
|
||
use std::{
|
||
process::exit,
|
||
sync::{
|
||
Arc,
|
||
atomic::{AtomicBool, Ordering},
|
||
},
|
||
};
|
||
|
||
use clap::Parser;
|
||
use console::style;
|
||
use dialoguer::{Confirm, theme::ColorfulTheme};
|
||
use log::{error, info};
|
||
use ureq::Agent;
|
||
|
||
use appstate::AppState;
|
||
use cli::Cli;
|
||
|
||
fn main() {
|
||
let stop = Arc::new(AtomicBool::new(false));
|
||
|
||
let stop_ctrlc = stop.clone();
|
||
ctrlc::set_handler(move || {
|
||
stop_ctrlc.store(true, Ordering::SeqCst);
|
||
info!("stopping after chunk ...");
|
||
})
|
||
.expect("Error setting Ctrl-C handler");
|
||
|
||
env_logger::init();
|
||
|
||
let args = Cli::parse();
|
||
info!("args: {args:?}");
|
||
info!("timeout: {:?}", args.get_timeout());
|
||
|
||
let agent: Agent = Agent::config_builder()
|
||
.timeout_global(args.get_timeout())
|
||
.build()
|
||
.into();
|
||
|
||
let mut state = AppState::try_resume(&args)
|
||
.and_then(|state| {
|
||
Confirm::with_theme(&ColorfulTheme::default())
|
||
.with_prompt("Previous operation found. Continue?")
|
||
.default(true)
|
||
.interact()
|
||
.map_or(None, |b| b.then_some(state))
|
||
})
|
||
.unwrap_or_else(|| match AppState::from_args(&args, &agent) {
|
||
Ok(state) => {
|
||
state.save().unwrap();
|
||
state
|
||
}
|
||
Err(e) => {
|
||
if let Some(cause) = match e {
|
||
ureq::Error::StatusCode(403) => Some("Alias ID"),
|
||
ureq::Error::Io(_) => Some("URL"),
|
||
_ => None,
|
||
} {
|
||
println!(
|
||
"{} probably wrong: {} – {:?}",
|
||
style("Error!").red(),
|
||
style(cause).cyan(),
|
||
style(e.to_string()).yellow()
|
||
);
|
||
} else {
|
||
error!("unknown error: {e}");
|
||
println!("{}", style("Unknown Error!").red());
|
||
}
|
||
|
||
exit(1);
|
||
}
|
||
});
|
||
|
||
info!("continuing with state: {state:?}");
|
||
|
||
loop {
|
||
match state.upload_chunk(&agent, args.chunk_size * 1024 * 1024) {
|
||
Err(e) => error!("error: {e:?}"),
|
||
Ok(None) => {
|
||
info!("all uploads done");
|
||
state.clear().unwrap();
|
||
break;
|
||
}
|
||
_ => (),
|
||
}
|
||
|
||
state.save().unwrap();
|
||
stop.load(Ordering::SeqCst).then(|| exit(0));
|
||
}
|
||
}
|