2021-02-13 08:01:33 +00:00
|
|
|
use crate::utils;
|
|
|
|
|
2022-04-30 13:07:56 +00:00
|
|
|
use clap::ArgMatches;
|
|
|
|
use std::fs::{create_dir, rename};
|
2021-02-13 08:01:33 +00:00
|
|
|
use std::io;
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::process::{exit, Command};
|
|
|
|
|
|
|
|
const MAX_DOWNLOAD_ATTEMPTS: i32 = 5;
|
|
|
|
|
2022-04-30 13:07:56 +00:00
|
|
|
pub async fn download(arg_m: &ArgMatches) {
|
2021-02-13 08:01:33 +00:00
|
|
|
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;
|
|
|
|
}
|
2022-04-30 13:07:56 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
};
|
2021-02-13 08:01:33 +00:00
|
|
|
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");
|
2022-04-30 13:07:56 +00:00
|
|
|
let command =
|
|
|
|
command.args(&["-v", "warning", "-stats", "-nostdin", "-y", "-i"]);
|
2021-02-13 08:01:33 +00:00
|
|
|
let mut command = command.arg(&download_url.video);
|
|
|
|
if let Some(ref captions) = download_url.captions {
|
|
|
|
command = command.args(&["-i", &captions]);
|
|
|
|
}
|
2022-04-30 13:07:56 +00:00
|
|
|
match command
|
|
|
|
.args(&["-c", "copy", "-f", "matroska"])
|
|
|
|
.arg(&tmp_filename)
|
|
|
|
.spawn()
|
|
|
|
{
|
2021-02-13 08:01:33 +00:00
|
|
|
Ok(mut child) => {
|
|
|
|
match child.wait() {
|
|
|
|
Ok(exit_status) => {
|
|
|
|
if exit_status.success() {
|
|
|
|
fail_dl = false;
|
|
|
|
match rename(&tmp_filename, &filename) {
|
|
|
|
Ok(_) => (),
|
2022-04-30 13:07:56 +00:00
|
|
|
Err(err) => eprintln!(
|
|
|
|
"Failed to rename {} to {} due to {}",
|
|
|
|
tmp_filename.display(),
|
|
|
|
filename.display(),
|
|
|
|
err
|
|
|
|
),
|
2021-02-13 08:01:33 +00:00
|
|
|
};
|
|
|
|
break;
|
|
|
|
}
|
2022-04-30 13:07:56 +00:00
|
|
|
eprintln!(
|
|
|
|
"ffmpeg exited with {:?}",
|
|
|
|
exit_status.code()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
Err(err) => eprintln!(
|
|
|
|
"Failed to wait on ffmpeg process due to {}",
|
|
|
|
err
|
|
|
|
),
|
2021-02-13 08:01:33 +00:00
|
|
|
};
|
2022-04-30 13:07:56 +00:00
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
eprintln!("Failed to spawn ffmpeg process due to {}", err)
|
|
|
|
}
|
2021-02-13 08:01:33 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
if fail_dl {
|
|
|
|
eprintln!("Failed to download {}", filename.display());
|
|
|
|
return_fail = true;
|
|
|
|
}
|
|
|
|
}
|
2022-04-30 13:07:56 +00:00
|
|
|
}
|
2021-02-13 08:01:33 +00:00
|
|
|
None => {
|
|
|
|
eprintln!("Failed to get {}: does not exist", id);
|
|
|
|
return_fail = true;
|
|
|
|
}
|
|
|
|
};
|
2022-04-30 13:07:56 +00:00
|
|
|
}
|
2021-02-13 08:01:33 +00:00
|
|
|
Err(err) => {
|
|
|
|
eprintln!("Failed to get {}: {}", id, err);
|
|
|
|
return_fail = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
if return_fail {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|