From 8d9266b2ee9fe0c503f50938e7d3293ef2c51f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=B4=80=E1=B4=8D=E1=B4=9B=E1=B4=8F=E1=B4=80=E1=B4=87?= =?UTF-8?q?=CA=80?= Date: Sun, 28 Apr 2024 22:13:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8B=B7=E8=B4=9D=E4=B8=80=E4=BB=BD=20?= =?UTF-8?q?poster=20=E4=BD=9C=E4=B8=BA=20fanart=20=E4=BD=BF=E7=94=A8=20(#8?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 拷贝一份 poster 作为 fanart 使用 * feat: 添加对于现有视频的迁移脚本 --- scripts/2.0.3_add_fanart.py | 37 +++++++++++++++++++++++++++++++++++++ src/core/command.rs | 19 ++++++++++++++++--- 2 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 scripts/2.0.3_add_fanart.py diff --git a/scripts/2.0.3_add_fanart.py b/scripts/2.0.3_add_fanart.py new file mode 100644 index 0000000..d32360a --- /dev/null +++ b/scripts/2.0.3_add_fanart.py @@ -0,0 +1,37 @@ +""" +2.0.2 -> 2.0.3 时添加了将 poster 拷贝为 fanart 的行为 +该行为对已存在的视频不会生效,所以可以手动执行该脚本 +具体来说,该脚本会: +1. 遍历命令行参数中所有存在的路径 +2. 找到路径中所有以 poster.jpg 结尾的文件 +3. 将 poster.jpg 替换为 fanart.jpg,拷贝到同一目录 +""" + +import os +import sys +import shutil +from pathlib import Path + + +def main(): + if len(sys.argv) <= 1: + print("用法: python 2.0.3_add_fanart.py ...") + exit(1) + paths = [Path(path) for path in sys.argv[1:]] + for path in paths: + if not path.exists(): + print(f"路径 {path} 不存在,跳过..") + continue + for root, _, files in os.walk(path): + for file in files: + if file.endswith("poster.jpg"): + poster_path = Path(root) / file + print(f"已找到 poster: {poster_path}") + fanart_path = Path(root) / file.replace("poster.jpg", "fanart.jpg") + shutil.copyfile(poster_path, fanart_path) + print(f"已将 {poster_path} 拷贝至 {fanart_path}") + print("操作完成") + + +if __name__ == "__main__": + main() diff --git a/src/core/command.rs b/src/core/command.rs index f6cd6f3..0e9d379 100644 --- a/src/core/command.rs +++ b/src/core/command.rs @@ -241,6 +241,7 @@ pub async fn download_video_pages( &video_model, downloader, base_path.join("poster.jpg"), + base_path.join("fanart.jpg"), )), // 生成视频信息的 nfo Box::pin(generate_video_nfo( @@ -390,12 +391,13 @@ pub async fn download_page( "pid": page_model.pid, }), )?); - let (poster_path, video_path, nfo_path, danmaku_path) = if is_single_page { + let (poster_path, video_path, nfo_path, danmaku_path, fanart_path) = if is_single_page { ( base_path.join(format!("{}-poster.jpg", &base_name)), base_path.join(format!("{}.mp4", &base_name)), base_path.join(format!("{}.nfo", &base_name)), base_path.join(format!("{}.zh-CN.default.ass", &base_name)), + Some(base_path.join(format!("{}-fanart.jpg", &base_name))), ) } else { ( @@ -411,6 +413,8 @@ pub async fn download_page( base_path .join("Season 1") .join(format!("{} - S01E{:0>2}.zh-CN.default.ass", &base_name, page_model.pid)), + // 对于多页视频,会在上一步 fetch_video_poster 中获取剧集的 fanart,无需在此处下载单集的 + None, ) }; let dimension = if page_model.width.is_some() && page_model.height.is_some() { @@ -435,6 +439,7 @@ pub async fn download_page( &page_model, downloader, poster_path, + fanart_path, )), Box::pin(fetch_page_video( seprate_status[1], @@ -487,6 +492,7 @@ pub async fn fetch_page_poster( page_model: &page::Model, downloader: &Downloader, poster_path: PathBuf, + fanart_path: Option, ) -> Result<()> { if !should_run { return Ok(()); @@ -502,7 +508,11 @@ pub async fn fetch_page_poster( None => video_model.cover.as_str(), } }; - downloader.fetch(url, &poster_path).await + downloader.fetch(url, &poster_path).await?; + if let Some(fanart_path) = fanart_path { + fs::copy(&poster_path, &fanart_path).await?; + } + Ok(()) } pub async fn fetch_page_video( @@ -589,11 +599,14 @@ pub async fn fetch_video_poster( video_model: &video::Model, downloader: &Downloader, poster_path: PathBuf, + fanart_path: PathBuf, ) -> Result<()> { if !should_run { return Ok(()); } - downloader.fetch(&video_model.cover, &poster_path).await + downloader.fetch(&video_model.cover, &poster_path).await?; + fs::copy(&poster_path, &fanart_path).await?; + Ok(()) } pub async fn fetch_upper_face(