This commit is contained in:
2022-06-13 12:21:36 +00:00
committed by GitHub
parent dd73b28a81
commit f3b702eb4e
3 changed files with 42 additions and 7 deletions

View File

@@ -36,9 +36,20 @@ use std::sync::atomic::AtomicBool;
use tokio::task::JoinHandle;
use url::Url;
/// Get the target file name
pub trait GetTargetFileName {
/// Get the target file name.
/// The target file name just used in the message in progress bar.
///
/// If is unknown, return [None] is fine.
fn get_target_file_name(&self) -> Option<String> {
None
}
}
#[derive(Debug)]
/// A file downloader
pub struct DownloaderInternal<T: Write + Seek + Send + Sync + ClearFile> {
pub struct DownloaderInternal<T: Write + Seek + Send + Sync + ClearFile + GetTargetFileName> {
/// The webclient
pub client: Arc<WebClient>,
/// The download status
@@ -131,7 +142,7 @@ impl DownloaderInternal<LocalFile> {
}
}
impl <T: Write + Seek + Send + Sync + ClearFile> DownloaderInternal<T> {
impl <T: Write + Seek + Send + Sync + ClearFile + GetTargetFileName> DownloaderInternal<T> {
/// Add a new task to tasks
/// * `task` - Task
pub fn add_task(&self, task: JoinHandle<Result<(), DownloaderError>>) {
@@ -196,6 +207,15 @@ impl <T: Write + Seek + Send + Sync + ClearFile> DownloaderInternal<T> {
self.status.get_ref().clone()
}
#[inline]
/// Get the target file name
pub fn get_target_file_name(&self) -> Option<String> {
match self.file.get_ref().deref() {
Some(f) => { f.get_target_file_name() }
None => { None }
}
}
#[inline]
/// Advances the position of the progress bar by `delta`
pub fn inc_progress_bar(&self, delta: u64) {
@@ -293,7 +313,7 @@ impl <T: Write + Seek + Send + Sync + ClearFile> DownloaderInternal<T> {
}
/// A file downloader
pub struct Downloader<T: Write + Seek + Send + Sync + ClearFile> {
pub struct Downloader<T: Write + Seek + Send + Sync + ClearFile + GetTargetFileName> {
/// internal type
downloader: Arc<DownloaderInternal<T>>,
/// The task to check status.
@@ -327,7 +347,7 @@ macro_rules! define_downloader_fn {
}
}
impl <T: Write + Seek + Send + Sync + ClearFile + 'static> Downloader<T> {
impl <T: Write + Seek + Send + Sync + ClearFile + GetTargetFileName + 'static> Downloader<T> {
/// Start download if download not started.
///
/// Returns the status of the Downloader

View File

@@ -1,4 +1,5 @@
use crate::ext::io::ClearFile;
use super::downloader::GetTargetFileName;
use std::fs::File;
use std::fs::remove_file;
use std::io::Seek;
@@ -55,6 +56,16 @@ impl Deref for LocalFile {
}
}
impl GetTargetFileName for LocalFile {
#[inline]
fn get_target_file_name(&self) -> Option<String> {
match self.path.to_str() {
Some(s) => { Some(String::from(s)) }
None => { None }
}
}
}
impl Seek for LocalFile {
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
self.file.as_ref().unwrap().seek(pos)

View File

@@ -2,6 +2,7 @@ use crate::ext::io::ClearFile;
use crate::ext::rw_lock::GetRwLock;
use crate::ext::try_err::TryErr;
use crate::gettext;
use super::downloader::GetTargetFileName;
use super::error::DownloaderError;
use super::downloader::DownloaderInternal;
use futures_util::StreamExt;
@@ -16,7 +17,7 @@ use std::sync::Arc;
use std::time::Duration;
/// Create a download tasks in simple thread mode.
pub async fn create_download_tasks_simple<T: Seek + Write + Send + Sync + ClearFile>(d: Arc<DownloaderInternal<T>>) -> Result<(), DownloaderError> {
pub async fn create_download_tasks_simple<T: Seek + Write + Send + Sync + ClearFile + GetTargetFileName>(d: Arc<DownloaderInternal<T>>) -> Result<(), DownloaderError> {
let mut start = if d.pd.is_downloading() {
d.pd.get_downloaded_file_size()
} else {
@@ -104,7 +105,7 @@ pub async fn create_download_tasks_simple<T: Seek + Write + Send + Sync + ClearF
}
/// Handle download process
pub async fn handle_download<T: Seek + Write + Send + Sync + ClearFile>(d: Arc<DownloaderInternal<T>>, re: Response) -> Result<(), DownloaderError> {
pub async fn handle_download<T: Seek + Write + Send + Sync + ClearFile + GetTargetFileName>(d: Arc<DownloaderInternal<T>>, re: Response) -> Result<(), DownloaderError> {
let mut stream = re.bytes_stream();
let is_multi = d.is_multi_threads();
loop {
@@ -139,6 +140,9 @@ pub async fn handle_download<T: Seek + Write + Send + Sync + ClearFile>(d: Arc<D
None => {
if !is_multi {
d.pd.complete()?;
if d.enabled_progress_bar() {
d.set_progress_bar_message(format!("{} {}", gettext("Downloaded file:"), d.get_target_file_name().unwrap_or(String::from("(unknown)"))));
}
}
break;
}
@@ -159,7 +163,7 @@ pub async fn handle_download<T: Seek + Write + Send + Sync + ClearFile>(d: Arc<D
}
/// Check tasks are completed or not. And create new tasks if needed.
pub async fn check_tasks<T: Seek + Write + Send + Sync + ClearFile + 'static>(d: Arc<DownloaderInternal<T>>) -> Result<(), DownloaderError> {
pub async fn check_tasks<T: Seek + Write + Send + Sync + ClearFile + GetTargetFileName + 'static>(d: Arc<DownloaderInternal<T>>) -> Result<(), DownloaderError> {
if !d.is_multi_threads() {
let task = tokio::spawn(create_download_tasks_simple(Arc::clone(&d)));
d.add_task(task);