diff --git a/src-tauri/src/downloader/download_progress.rs b/src-tauri/src/downloader/download_progress.rs index 7b17899..587a52a 100644 --- a/src-tauri/src/downloader/download_progress.rs +++ b/src-tauri/src/downloader/download_progress.rs @@ -1,5 +1,6 @@ use std::{ path::PathBuf, + sync::Arc, time::{SystemTime, UNIX_EPOCH}, }; @@ -7,15 +8,20 @@ use anyhow::{anyhow, Context}; use serde::{Deserialize, Serialize}; use specta::Type; use tauri::{AppHandle, Manager}; +use tauri_specta::Event; use uuid::Uuid; use crate::{ config::Config, - downloader::tasks::{ - audio_task::AudioTask, cover_task::CoverTask, danmaku_task::DanmakuTask, - json_task::JsonTask, nfo_task::NfoTask, subtitle_task::SubtitleTask, - video_process_task::VideoProcessTask, video_task::VideoTask, + downloader::{ + download_task::DownloadTask, + tasks::{ + audio_task::AudioTask, cover_task::CoverTask, danmaku_task::DanmakuTask, + json_task::JsonTask, nfo_task::NfoTask, subtitle_task::SubtitleTask, + video_process_task::VideoProcessTask, video_task::VideoTask, + }, }, + events::DownloadEvent, extensions::AppHandleExt, types::{ audio_quality::AudioQuality, @@ -184,7 +190,116 @@ impl DownloadProgress { Ok(progress) } - pub async fn prepare(&mut self, app: &AppHandle) -> anyhow::Result<()> { + pub async fn process(&mut self, download_task: &Arc) -> anyhow::Result<()> { + let ids_string = self.get_ids_string(); + + let _ = DownloadEvent::ProgressPreparing { + task_id: self.task_id.clone(), + } + .emit(&download_task.app); + + self.prepare(&download_task.app) + .await + .context("准备下载失败")?; + + self.completed_ts = None; // 重置完成时间戳 + download_task.update_progress(|p| *p = self.clone()); + + let (episode_dir, filename) = (&self.episode_dir, &self.filename); + + std::fs::create_dir_all(episode_dir).context(format!( + "{ids_string} 创建目录`{}`失败", + episode_dir.display() + ))?; + + let video_task = &self.video_task; + let audio_task = &self.audio_task; + let video_process_task = &self.video_process_task; + let danmaku_task = &self.danmaku_task; + let subtitle_task = &self.subtitle_task; + let cover_task = &self.cover_task; + let nfo_task = &self.nfo_task; + let json_task = &self.json_task; + + let mut player_info = None; + let mut episode_info = None; + + if !video_task.is_completed() && video_task.content_length != 0 { + video_task + .process(download_task, self) + .await + .context(format!("{ids_string} `{filename}`下载视频文件失败"))?; + tracing::debug!("{ids_string} `{filename}`视频下载任务完成"); + } + + if !audio_task.is_completed() && audio_task.content_length != 0 { + audio_task + .process(download_task, self) + .await + .context(format!("{ids_string} `{filename}`下载音频文件失败"))?; + tracing::debug!("{ids_string} `{filename}`音频下载任务完成"); + } + + if !video_process_task.is_completed() { + video_process_task + .process(download_task, self, &mut player_info) + .await + .context(format!("{ids_string} `{filename}`视频处理失败"))?; + tracing::debug!("{ids_string} `{filename}`视频处理任务完成"); + } + + if !danmaku_task.is_completed() { + danmaku_task + .process(download_task, self) + .await + .context(format!("{ids_string} `{filename}`下载弹幕失败"))?; + tracing::debug!("{ids_string} `{filename}`弹幕下载任务完成"); + } + + if !subtitle_task.is_completed() { + subtitle_task + .process(download_task, self, &mut player_info) + .await + .context(format!("{ids_string} `{filename}`下载字幕失败"))?; + tracing::debug!("{ids_string} `{filename}`字幕下载任务完成"); + } + + if !cover_task.is_completed() { + cover_task + .process(download_task, self) + .await + .context(format!("{ids_string} `{filename}`下载封面失败"))?; + tracing::debug!("{ids_string} `{filename}`封面下载任务完成"); + } + + if !nfo_task.is_completed() { + nfo_task + .process(download_task, self, &mut episode_info) + .await + .context(format!("{ids_string} `{filename}`下载NFO失败"))?; + tracing::debug!("{ids_string} `{filename}`NFO下载任务完成"); + } + + if !json_task.is_completed() { + json_task + .process(download_task, self, &mut episode_info) + .await + .context(format!("{ids_string} `{filename}`下载JSON元数据失败"))?; + tracing::debug!("{ids_string} `{filename}`JSON元数据下载任务完成"); + } + + let completed_ts = SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|d| d.as_secs()) + .ok(); + if completed_ts.is_some() { + download_task.update_progress(|p| p.completed_ts = completed_ts); + } + + Ok(()) + } + + async fn prepare(&mut self, app: &AppHandle) -> anyhow::Result<()> { let video_selected = self.video_task.selected; let video_completed = self.video_task.completed; let audio_selected = self.audio_task.selected; diff --git a/src-tauri/src/downloader/download_task.rs b/src-tauri/src/downloader/download_task.rs index 794babf..5bb7f6e 100644 --- a/src-tauri/src/downloader/download_task.rs +++ b/src-tauri/src/downloader/download_task.rs @@ -1,7 +1,4 @@ -use std::{ - sync::Arc, - time::{Duration, SystemTime, UNIX_EPOCH}, -}; +use std::{sync::Arc, time::Duration}; use anyhow::Context; use parking_lot::RwLock; @@ -233,28 +230,9 @@ impl DownloadTask { return; } - tracing::debug!("{ids_string} 开始准备`{episode_title}`的下载"); - let _ = DownloadEvent::ProgressPreparing { - task_id: self.task_id.clone(), - } - .emit(&self.app); - - if let Err(err) = progress.prepare(&self.app).await { - let err_title = format!("{ids_string} `{episode_title}`准备下载失败"); - let string_chain = err.to_string_chain(); - tracing::error!(err_title, message = string_chain); - - self.set_state(DownloadTaskState::Failed); - - return; - } - - progress.completed_ts = None; // 重置完成时间戳 - self.update_progress(|p| *p = progress.clone()); - tracing::debug!("{ids_string} 开始下载`{episode_title}`"); - if let Err(err) = self - .handle_progress(progress) + if let Err(err) = progress + .process(self) .await .context("[继续]失败的任务可以断点续传") { @@ -273,102 +251,6 @@ impl DownloadTask { tracing::info!("{ids_string} `{episode_title}`下载完成"); } - async fn handle_progress(self: &Arc, progress: DownloadProgress) -> anyhow::Result<()> { - let ids_string = progress.get_ids_string(); - let (episode_dir, filename) = (&progress.episode_dir, &progress.filename); - - std::fs::create_dir_all(episode_dir).context(format!( - "{ids_string} 创建目录`{}`失败", - episode_dir.display() - ))?; - - let video_task = &progress.video_task; - let audio_task = &progress.audio_task; - let video_process_task = &progress.video_process_task; - let danmaku_task = &progress.danmaku_task; - let subtitle_task = &progress.subtitle_task; - let cover_task = &progress.cover_task; - let nfo_task = &progress.nfo_task; - let json_task = &progress.json_task; - - let mut player_info = None; - let mut episode_info = None; - - if !video_task.is_completed() && video_task.content_length != 0 { - video_task - .process(self, &progress) - .await - .context(format!("{ids_string} `{filename}`下载视频文件失败"))?; - tracing::debug!("{ids_string} `{filename}`视频下载任务完成"); - } - - if !audio_task.is_completed() && audio_task.content_length != 0 { - audio_task - .process(self, &progress) - .await - .context(format!("{ids_string} `{filename}`下载音频文件失败"))?; - tracing::debug!("{ids_string} `{filename}`音频下载任务完成"); - } - - if !video_process_task.is_completed() { - video_process_task - .process(self, &progress, &mut player_info) - .await - .context(format!("{ids_string} `{filename}`视频处理失败"))?; - tracing::debug!("{ids_string} `{filename}`视频处理任务完成"); - } - - if !danmaku_task.is_completed() { - danmaku_task - .process(self, &progress) - .await - .context(format!("{ids_string} `{filename}`下载弹幕失败"))?; - tracing::debug!("{ids_string} `{filename}`弹幕下载任务完成"); - } - - if !subtitle_task.is_completed() { - subtitle_task - .process(self, &progress, &mut player_info) - .await - .context(format!("{ids_string} `{filename}`下载字幕失败"))?; - tracing::debug!("{ids_string} `{filename}`字幕下载任务完成"); - } - - if !cover_task.is_completed() { - cover_task - .process(self, &progress) - .await - .context(format!("{ids_string} `{filename}`下载封面失败"))?; - tracing::debug!("{ids_string} `{filename}`封面下载任务完成"); - } - - if !nfo_task.is_completed() { - nfo_task - .process(self, &progress, &mut episode_info) - .await - .context(format!("{ids_string} `{filename}`下载NFO失败"))?; - tracing::debug!("{ids_string} `{filename}`NFO下载任务完成"); - } - - if !json_task.is_completed() { - json_task - .process(self, &progress, &mut episode_info) - .await - .context(format!("{ids_string} `{filename}`下载JSON元数据失败"))?; - tracing::debug!("{ids_string} `{filename}`JSON元数据下载任务完成"); - } - - let completed_ts = SystemTime::now() - .duration_since(UNIX_EPOCH) - .map(|d| d.as_secs()) - .ok(); - if completed_ts.is_some() { - self.update_progress(|p| p.completed_ts = completed_ts); - } - - Ok(()) - } - async fn sleep_between_task(&self) { let task_id = &self.task_id; let mut remaining_sec = self.app.get_config().read().task_download_interval_sec;