From 17ac499fb770b41ca88e71c5720f74a7f20a6bea Mon Sep 17 00:00:00 2001 From: blank X Date: Fri, 5 Feb 2021 12:29:34 +0700 Subject: [PATCH] some things idk --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/commands/download.rs | 34 ++++++++++++++++++++-------------- src/structs.rs | 20 ++++++++++++++++++++ src/utils.rs | 10 +++++----- 5 files changed, 47 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9b6dd2..440b0ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,7 +330,7 @@ dependencies = [ [[package]] name = "mangafetchi" -version = "0.1.7" +version = "0.1.8" dependencies = [ "quick-xml", "reqwest", diff --git a/Cargo.toml b/Cargo.toml index 844c4ea..0c4c50c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mangafetchi" -version = "0.1.7" +version = "0.1.8" authors = ["blank X "] edition = "2018" diff --git a/src/commands/download.rs b/src/commands/download.rs index f5491db..0b045c6 100644 --- a/src/commands/download.rs +++ b/src/commands/download.rs @@ -5,6 +5,7 @@ use std::env; use std::sync::Arc; use std::process::exit; use std::path::{Path, PathBuf}; +use std::collections::VecDeque; use url::Url; use tokio::sync::Mutex; use tokio::task::JoinHandle; @@ -53,7 +54,7 @@ pub async fn run(mut args: env::Args) { exit(1); } }; - let mutex = Arc::new(Mutex::new(DownloadData { data: Vec::new(), is_done: false })); + let mutex = Arc::new(Mutex::new(DownloadData { data: VecDeque::new(), is_done: false })); let handles: Vec> = summon_handles(client.clone(), Arc::clone(&mutex)).await; for chapter in chapters { loop { @@ -99,21 +100,26 @@ async fn summon_handles(client: reqwest::Client, mutex: Arc> let cloned_mutex = Arc::clone(&tcloned_mutex); let cloned_client = tcloned_client.clone(); let mut download_data = cloned_mutex.lock().await; - if download_data.data.is_empty() { - if download_data.is_done { - break; - } - drop(download_data); - sleep(Duration::from_millis(NO_ITEM_WAIT_TIME)).await; - continue; - } - let (url, file_name, referer) = download_data.data.remove(0); + let data = download_data.data.pop_front(); + let is_done = download_data.is_done; drop(download_data); + let (url, file_name, referer) = match data { + Some(data) => data, + None => { + if is_done { + break; + } + sleep(Duration::from_millis(NO_ITEM_WAIT_TIME)).await; + continue; + } + }; eprintln!("[DW{}] Downloading {} to {}", worker_id, &url, file_name.display()); loop { - if utils::download_file(cloned_client.clone(), &url, &file_name, &referer).await.unwrap() { - break; - } + match utils::download_file(cloned_client.clone(), &url, &file_name, &referer).await { + Ok(result) if result => break, + Ok(_) => (), + Err(err) => eprintln!("[DW{}] Error while downloading {}: {}", worker_id, file_name.display(), err) + }; sleep(Duration::from_millis(NON_IMAGE_WAIT_TIME)).await; } eprintln!("[DW{}] Downloaded {} to {}", worker_id, &url, file_name.display()); @@ -125,6 +131,6 @@ async fn summon_handles(client: reqwest::Client, mutex: Arc> } struct DownloadData { - pub data: Vec<(String, PathBuf, String)>, + pub data: VecDeque<(String, PathBuf, String)>, pub is_done: bool } diff --git a/src/structs.rs b/src/structs.rs index f827179..31de8fa 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -1,3 +1,4 @@ +use std::io; use std::fmt; use serde::Deserialize; extern crate url; @@ -88,6 +89,7 @@ pub enum Error { Reqwest(reqwest::Error), URL(url::ParseError), SerdeJSON(serde_json::Error), + IO(io::Error) } impl From for Error { @@ -110,3 +112,21 @@ impl From for Error { Error::SerdeJSON(error) } } + +impl From for Error { + #[inline] + fn from(error: io::Error) -> Error { + Error::IO(error) + } +} + +impl fmt::Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str(&match self { + Error::Reqwest(err) => format!("reqwest: {}", err), + Error::URL(err) => format!("url: {}", err), + Error::SerdeJSON(err) => format!("serde_json: {}", err), + Error::IO(err) => format!("io: {}", err) + }) + } +} diff --git a/src/utils.rs b/src/utils.rs index 5cc990b..2793e34 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -722,20 +722,20 @@ fn parse_manganelo_pages(text: &str) -> Vec { pages } -pub async fn download_file(client: reqwest::Client, url: &str, file_name: &PathBuf, referer: &str) -> Result { +pub async fn download_file(client: reqwest::Client, url: &str, file_name: &PathBuf, referer: &str) -> Result { let resp = client.get(url) .header("Referer", referer) .send() .await?; match resp.headers().get("Content-Type") { Some(header_value) => { - if header_value.to_str().unwrap().starts_with("image/") { + if header_value.to_str().unwrap_or_default().starts_with("image/") { let bytes = resp.bytes().await?; if !file_name.parent().unwrap().is_dir() { - create_dir(file_name.parent().unwrap()).unwrap(); + create_dir(file_name.parent().unwrap())?; } - let mut file = File::create(&file_name).unwrap(); - file.write_all(&bytes).unwrap(); + let mut file = File::create(&file_name)?; + file.write_all(&bytes)?; return Ok(true); } return Ok(false);