hentaihavenrs/src/commands/download.rs

127 lines
5.9 KiB
Rust

use crate::utils;
use clap::ArgMatches;
use std::fs::{create_dir, rename};
use std::io;
use std::path::PathBuf;
use std::process::{exit, Command};
const MAX_DOWNLOAD_ATTEMPTS: i32 = 5;
pub async fn download(arg_m: &ArgMatches) {
let print_only = arg_m.is_present("print");
let id = arg_m.value_of("id").unwrap();
let client = utils::create_client();
let mut return_fail = false;
let hentai_info = utils::get_hentai(client.clone(), id).await;
match hentai_info {
Ok(hentai_info) => {
match hentai_info {
Some(hentai_info) => {
let tcloned_client = client.clone();
let iter = (1..=hentai_info.episode_urls.len()).zip(hentai_info.episode_urls);
for (episode_number, episode_url) in iter {
let mut filename = PathBuf::from(&hentai_info.slug);
filename.push(&format!("{}.mkv", episode_number));
if filename.exists() {
continue;
}
let download_url =
match utils::get_url(tcloned_client.clone(), &episode_url).await {
Ok(Some(i)) => i,
Ok(None) => {
eprintln!(
"Failed to get {}: get_url returned None",
filename.display()
);
continue;
}
Err(err) => {
eprintln!("Failed to get {}: {}", filename.display(), err);
continue;
}
};
if print_only {
println!("{}", download_url);
continue;
}
match create_dir(&hentai_info.slug) {
Ok(_) => (),
Err(err) => {
if err.kind() != io::ErrorKind::AlreadyExists {
eprintln!("Failed to create parent directory due to {}", err);
exit(1);
}
}
};
let mut tmp_filename = filename.clone();
tmp_filename.set_extension("tmp");
let mut fail_dl = true;
for i in 0..MAX_DOWNLOAD_ATTEMPTS {
eprintln!("Downloading {} (attempt {})", filename.display(), i);
let mut command = Command::new("ffmpeg");
let command =
command.args(&["-v", "warning", "-stats", "-nostdin", "-y", "-i"]);
let mut command = command.arg(&download_url.video);
if let Some(ref captions) = download_url.captions {
command = command.args(&["-i", &captions]);
}
match command
.args(&["-c", "copy", "-f", "matroska"])
.arg(&tmp_filename)
.spawn()
{
Ok(mut child) => {
match child.wait() {
Ok(exit_status) => {
if exit_status.success() {
fail_dl = false;
match rename(&tmp_filename, &filename) {
Ok(_) => (),
Err(err) => eprintln!(
"Failed to rename {} to {} due to {}",
tmp_filename.display(),
filename.display(),
err
),
};
break;
}
eprintln!(
"ffmpeg exited with {:?}",
exit_status.code()
);
}
Err(err) => eprintln!(
"Failed to wait on ffmpeg process due to {}",
err
),
};
}
Err(err) => {
eprintln!("Failed to spawn ffmpeg process due to {}", err)
}
};
}
if fail_dl {
eprintln!("Failed to download {}", filename.display());
return_fail = true;
}
}
}
None => {
eprintln!("Failed to get {}: does not exist", id);
return_fail = true;
}
};
}
Err(err) => {
eprintln!("Failed to get {}: {}", id, err);
return_fail = true;
}
};
if return_fail {
exit(1);
}
}