feat: 后端支持json元数据下载

This commit is contained in:
lanyeeee
2025-07-29 06:36:43 +08:00
parent 72d8c32617
commit c97fe48012
6 changed files with 80 additions and 3 deletions
+2
View File
@@ -26,6 +26,7 @@ pub struct Config {
pub download_subtitle: bool,
pub download_cover: bool,
pub download_nfo: bool,
pub download_json: bool,
pub dir_fmt: String,
pub dir_fmt_for_part: String,
pub time_fmt: String,
@@ -106,6 +107,7 @@ impl Config {
download_subtitle: true,
download_cover: true,
download_nfo: true,
download_json: true,
dir_fmt: "{collection_title}/{episode_title}".to_string(),
dir_fmt_for_part: DEFAULT_FMT_FOR_PART.to_string(),
time_fmt: "%Y-%m-%d_%H-%M-%S".to_string(),
+19 -1
View File
@@ -13,7 +13,7 @@ use crate::{
config::Config,
downloader::tasks::{
audio_task::AudioTask, cover_task::CoverTask, danmaku_task::DanmakuTask,
merge_task::MergeTask, nfo_task::NfoTask, subtitle_task::SubtitleTask,
json_task::JsonTask, merge_task::MergeTask, nfo_task::NfoTask, subtitle_task::SubtitleTask,
video_task::VideoTask,
},
extensions::AppHandleExt,
@@ -57,6 +57,7 @@ pub struct DownloadProgress {
pub danmaku_task: DanmakuTask,
pub cover_task: CoverTask,
pub nfo_task: NfoTask,
pub json_task: JsonTask,
pub create_ts: u64,
pub completed_ts: Option<u64>,
}
@@ -128,6 +129,7 @@ impl DownloadProgress {
subtitle_task: tasks.subtitle,
cover_task: tasks.cover,
nfo_task: tasks.nfo,
json_task: tasks.json,
create_ts,
completed_ts: None,
};
@@ -178,6 +180,7 @@ impl DownloadProgress {
subtitle_task: tasks.subtitle,
cover_task: tasks.cover,
nfo_task: tasks.nfo,
json_task: tasks.json,
create_ts,
completed_ts: None,
};
@@ -317,6 +320,7 @@ impl DownloadProgress {
&& self.subtitle_task.is_completed()
&& self.cover_task.is_completed()
&& self.nfo_task.is_completed()
&& self.json_task.is_completed()
}
pub fn mark_uncompleted(&mut self) {
@@ -327,6 +331,7 @@ impl DownloadProgress {
self.subtitle_task.completed = false;
self.cover_task.completed = false;
self.nfo_task.completed = false;
self.json_task.completed = false;
}
pub fn get_ids_string(&self) -> String {
@@ -379,6 +384,7 @@ fn create_normal_progresses_for_single(
subtitle_task: tasks.subtitle,
cover_task: tasks.cover,
nfo_task: tasks.nfo,
json_task: tasks.json,
create_ts,
completed_ts: None,
};
@@ -418,6 +424,7 @@ fn create_normal_progresses_for_single(
subtitle_task: tasks.subtitle,
cover_task: tasks.cover,
nfo_task: tasks.nfo,
json_task: tasks.json,
create_ts,
completed_ts: None,
};
@@ -457,6 +464,7 @@ fn create_normal_progresses_for_single(
subtitle_task: tasks.subtitle.clone(),
cover_task: tasks.cover.clone(),
nfo_task: tasks.nfo.clone(),
json_task: tasks.json.clone(),
create_ts,
completed_ts: None,
};
@@ -528,6 +536,7 @@ fn create_normal_progresses_for_season(
subtitle_task: tasks.subtitle,
cover_task: tasks.cover,
nfo_task: tasks.nfo,
json_task: tasks.json,
create_ts,
completed_ts: None,
};
@@ -567,6 +576,7 @@ fn create_normal_progresses_for_season(
subtitle_task: tasks.subtitle,
cover_task: tasks.cover,
nfo_task: tasks.nfo,
json_task: tasks.json,
create_ts,
completed_ts: None,
};
@@ -607,6 +617,7 @@ fn create_normal_progresses_for_season(
subtitle_task: tasks.subtitle.clone(),
cover_task: tasks.cover.clone(),
nfo_task: tasks.nfo.clone(),
json_task: tasks.json.clone(),
create_ts,
completed_ts: None,
};
@@ -628,6 +639,7 @@ struct Tasks {
subtitle: SubtitleTask,
cover: CoverTask,
nfo: NfoTask,
json: JsonTask,
}
impl Tasks {
@@ -679,6 +691,11 @@ impl Tasks {
completed: false,
};
let json = JsonTask {
selected: config.download_json,
completed: false,
};
Self {
video,
audio,
@@ -687,6 +704,7 @@ impl Tasks {
subtitle,
cover,
nfo,
json,
}
}
}
+41
View File
@@ -341,6 +341,13 @@ impl DownloadTask {
tracing::debug!("{ids_string} `{filename}`NFO下载完成");
}
if !progress.json_task.is_completed() {
self.download_json(&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())
@@ -872,6 +879,40 @@ impl DownloadTask {
Ok(())
}
async fn download_json(
&self,
progress: &DownloadProgress,
episode_info: &mut Option<EpisodeInfo>,
) -> anyhow::Result<()> {
let (episode_dir, filename) = (&progress.episode_dir, &progress.filename);
let (aid, ep_id, episode_type) = (progress.aid, progress.ep_id, progress.episode_type);
let bili_client = self.app.get_bili_client();
let episode_info = episode_info
.get_or_init(&bili_client, aid, ep_id, episode_type)
.await?;
let json_path = episode_dir.join(format!("{filename}-元数据.json"));
let json_string = match episode_info {
EpisodeInfo::Normal(info) => {
serde_json::to_string(&info).context("将普通视频信息转换为JSON失败")?
}
EpisodeInfo::Bangumi(info, _ep_id) => {
serde_json::to_string(&info).context("将番剧信息转换为JSON失败")?
}
EpisodeInfo::Cheese(info, _ep_id) => {
serde_json::to_string(&info).context("将课程信息转换为JSON失败")?
}
};
std::fs::write(&json_path, json_string)
.context(format!("保存JSON到`{}`失败", json_path.display()))?;
self.update_progress(|p| p.json_task.completed = true);
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;
@@ -0,0 +1,14 @@
use serde::{Deserialize, Serialize};
use specta::Type;
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct JsonTask {
pub selected: bool,
pub completed: bool,
}
impl JsonTask {
pub fn is_completed(&self) -> bool {
!self.selected || self.completed
}
}
+1
View File
@@ -1,6 +1,7 @@
pub mod audio_task;
pub mod cover_task;
pub mod danmaku_task;
pub mod json_task;
pub mod merge_task;
pub mod nfo_task;
pub mod subtitle_task;