feat: 支持自定义 NFO 文件中的视频时间,可选加入收藏夹的时间、视频发布的时间 (#114)

* feat: 支持自定义 NFO 文件中的视频时间,可选加入收藏夹的时间、视频发布的时间

* chore: 使用小写
This commit is contained in:
ᴀᴍᴛᴏᴀᴇʀ
2024-06-01 03:01:39 +08:00
committed by GitHub
parent 67de151234
commit 2ef99a20c9
3 changed files with 42 additions and 23 deletions
+14 -7
View File
@@ -19,7 +19,7 @@ pub static CONFIG: Lazy<Config> = Lazy::new(|| {
panic!("加载配置文件失败,错误为: {err}"); panic!("加载配置文件失败,错误为: {err}");
} }
warn!("配置文件不存在,使用默认配置..."); warn!("配置文件不存在,使用默认配置...");
Config::new() Config::default()
}); });
// 放到外面,确保新的配置项被保存 // 放到外面,确保新的配置项被保存
info!("配置加载完毕,覆盖刷新原有配置"); info!("配置加载完毕,覆盖刷新原有配置");
@@ -44,16 +44,20 @@ pub struct Config {
pub page_name: Cow<'static, str>, pub page_name: Cow<'static, str>,
pub interval: u64, pub interval: u64,
pub upper_path: PathBuf, pub upper_path: PathBuf,
#[serde(default)]
pub nfo_time_type: NFOTimeType,
}
#[derive(Serialize, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum NFOTimeType {
#[default]
FavTime,
PubTime,
} }
impl Default for Config { impl Default for Config {
fn default() -> Self { fn default() -> Self {
Self::new()
}
}
impl Config {
fn new() -> Self {
Self { Self {
credential: ArcSwapOption::from(Some(Arc::new(Credential::default()))), credential: ArcSwapOption::from(Some(Arc::new(Credential::default()))),
filter_option: FilterOption::default(), filter_option: FilterOption::default(),
@@ -63,9 +67,12 @@ impl Config {
page_name: Cow::Borrowed("{{bvid}}"), page_name: Cow::Borrowed("{{bvid}}"),
interval: 1200, interval: 1200,
upper_path: CONFIG_DIR.join("upper_face"), upper_path: CONFIG_DIR.join("upper_face"),
nfo_time_type: NFOTimeType::FavTime,
} }
} }
}
impl Config {
/// 简单的预检查 /// 简单的预检查
pub fn check(&self) { pub fn check(&self) {
let mut ok = true; let mut ok = true;
+5 -1
View File
@@ -657,7 +657,11 @@ async fn generate_nfo(serializer: NFOSerializer<'_>, nfo_path: PathBuf) -> Resul
if let Some(parent) = nfo_path.parent() { if let Some(parent) = nfo_path.parent() {
fs::create_dir_all(parent).await?; fs::create_dir_all(parent).await?;
} }
fs::write(nfo_path, serializer.generate_nfo().await?.as_bytes()).await?; fs::write(
nfo_path,
serializer.generate_nfo(&CONFIG.nfo_time_type).await?.as_bytes(),
)
.await?;
Ok(()) Ok(())
} }
+23 -15
View File
@@ -17,7 +17,7 @@ use serde_json::json;
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use crate::bilibili::{FavoriteListInfo, PageInfo, VideoInfo}; use crate::bilibili::{FavoriteListInfo, PageInfo, VideoInfo};
use crate::config::CONFIG; use crate::config::{NFOTimeType, CONFIG};
use crate::core::status::Status; use crate::core::status::Status;
pub static TEMPLATE: Lazy<handlebars::Handlebars> = Lazy::new(|| { pub static TEMPLATE: Lazy<handlebars::Handlebars> = Lazy::new(|| {
@@ -274,7 +274,7 @@ pub async fn update_pages_model(pages: Vec<page::ActiveModel>, connection: &Data
/// serde xml 似乎不太好用,先这么裸着写 /// serde xml 似乎不太好用,先这么裸着写
/// (真是又臭又长啊 /// (真是又臭又长啊
impl<'a> NFOSerializer<'a> { impl<'a> NFOSerializer<'a> {
pub async fn generate_nfo(self) -> Result<String> { pub async fn generate_nfo(self, nfo_time_type: &NFOTimeType) -> Result<String> {
let mut buffer = r#"<?xml version="1.0" encoding="utf-8" standalone="yes"?> let mut buffer = r#"<?xml version="1.0" encoding="utf-8" standalone="yes"?>
"# "#
.as_bytes() .as_bytes()
@@ -283,6 +283,10 @@ impl<'a> NFOSerializer<'a> {
let mut writer = Writer::new_with_indent(&mut tokio_buffer, b' ', 4); let mut writer = Writer::new_with_indent(&mut tokio_buffer, b' ', 4);
match self { match self {
NFOSerializer(ModelWrapper::Video(v), NFOMode::MOVIE) => { NFOSerializer(ModelWrapper::Video(v), NFOMode::MOVIE) => {
let nfo_time = match nfo_time_type {
NFOTimeType::FavTime => v.favtime,
NFOTimeType::PubTime => v.pubtime,
};
writer writer
.create_element("movie") .create_element("movie")
.write_inner_content_async::<_, _, Error>(|writer| async move { .write_inner_content_async::<_, _, Error>(|writer| async move {
@@ -316,7 +320,7 @@ impl<'a> NFOSerializer<'a> {
.unwrap(); .unwrap();
writer writer
.create_element("year") .create_element("year")
.write_text_content_async(BytesText::new(&v.favtime.format("%Y").to_string())) .write_text_content_async(BytesText::new(&nfo_time.format("%Y").to_string()))
.await .await
.unwrap(); .unwrap();
if let Some(tags) = &v.tags { if let Some(tags) = &v.tags {
@@ -337,7 +341,7 @@ impl<'a> NFOSerializer<'a> {
.unwrap(); .unwrap();
writer writer
.create_element("aired") .create_element("aired")
.write_text_content_async(BytesText::new(&v.favtime.format("%Y-%m-%d").to_string())) .write_text_content_async(BytesText::new(&nfo_time.format("%Y-%m-%d").to_string()))
.await .await
.unwrap(); .unwrap();
Ok(writer) Ok(writer)
@@ -346,6 +350,10 @@ impl<'a> NFOSerializer<'a> {
.unwrap(); .unwrap();
} }
NFOSerializer(ModelWrapper::Video(v), NFOMode::TVSHOW) => { NFOSerializer(ModelWrapper::Video(v), NFOMode::TVSHOW) => {
let nfo_time = match nfo_time_type {
NFOTimeType::FavTime => v.favtime,
NFOTimeType::PubTime => v.pubtime,
};
writer writer
.create_element("tvshow") .create_element("tvshow")
.write_inner_content_async::<_, _, Error>(|writer| async move { .write_inner_content_async::<_, _, Error>(|writer| async move {
@@ -379,7 +387,7 @@ impl<'a> NFOSerializer<'a> {
.unwrap(); .unwrap();
writer writer
.create_element("year") .create_element("year")
.write_text_content_async(BytesText::new(&v.favtime.format("%Y").to_string())) .write_text_content_async(BytesText::new(&nfo_time.format("%Y").to_string()))
.await .await
.unwrap(); .unwrap();
if let Some(tags) = &v.tags { if let Some(tags) = &v.tags {
@@ -400,7 +408,7 @@ impl<'a> NFOSerializer<'a> {
.unwrap(); .unwrap();
writer writer
.create_element("aired") .create_element("aired")
.write_text_content_async(BytesText::new(&v.favtime.format("%Y-%m-%d").to_string())) .write_text_content_async(BytesText::new(&nfo_time.format("%Y-%m-%d").to_string()))
.await .await
.unwrap(); .unwrap();
Ok(writer) Ok(writer)
@@ -490,8 +498,8 @@ mod tests {
chrono::NaiveTime::from_hms_opt(2, 2, 2).unwrap(), chrono::NaiveTime::from_hms_opt(2, 2, 2).unwrap(),
), ),
pubtime: chrono::NaiveDateTime::new( pubtime: chrono::NaiveDateTime::new(
chrono::NaiveDate::from_ymd_opt(2022, 2, 2).unwrap(), chrono::NaiveDate::from_ymd_opt(2033, 3, 3).unwrap(),
chrono::NaiveTime::from_hms_opt(2, 2, 2).unwrap(), chrono::NaiveTime::from_hms_opt(3, 3, 3).unwrap(),
), ),
bvid: "bvid".to_string(), bvid: "bvid".to_string(),
tags: Some(serde_json::json!(["tag1", "tag2"])), tags: Some(serde_json::json!(["tag1", "tag2"])),
@@ -499,7 +507,7 @@ mod tests {
}; };
assert_eq!( assert_eq!(
NFOSerializer(ModelWrapper::Video(&video), NFOMode::MOVIE) NFOSerializer(ModelWrapper::Video(&video), NFOMode::MOVIE)
.generate_nfo() .generate_nfo(&NFOTimeType::PubTime)
.await .await
.unwrap(), .unwrap(),
r#"<?xml version="1.0" encoding="utf-8" standalone="yes"?> r#"<?xml version="1.0" encoding="utf-8" standalone="yes"?>
@@ -511,16 +519,16 @@ mod tests {
<name>1</name> <name>1</name>
<role>upper_name</role> <role>upper_name</role>
</actor> </actor>
<year>2022</year> <year>2033</year>
<genre>tag1</genre> <genre>tag1</genre>
<genre>tag2</genre> <genre>tag2</genre>
<uniqueid type="bilibili">bvid</uniqueid> <uniqueid type="bilibili">bvid</uniqueid>
<aired>2022-02-02</aired> <aired>2033-03-03</aired>
</movie>"#, </movie>"#,
); );
assert_eq!( assert_eq!(
NFOSerializer(ModelWrapper::Video(&video), NFOMode::TVSHOW) NFOSerializer(ModelWrapper::Video(&video), NFOMode::TVSHOW)
.generate_nfo() .generate_nfo(&NFOTimeType::FavTime)
.await .await
.unwrap(), .unwrap(),
r#"<?xml version="1.0" encoding="utf-8" standalone="yes"?> r#"<?xml version="1.0" encoding="utf-8" standalone="yes"?>
@@ -541,7 +549,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
NFOSerializer(ModelWrapper::Video(&video), NFOMode::UPPER) NFOSerializer(ModelWrapper::Video(&video), NFOMode::UPPER)
.generate_nfo() .generate_nfo(&NFOTimeType::FavTime)
.await .await
.unwrap(), .unwrap(),
r#"<?xml version="1.0" encoding="utf-8" standalone="yes"?> r#"<?xml version="1.0" encoding="utf-8" standalone="yes"?>
@@ -549,7 +557,7 @@ mod tests {
<plot/> <plot/>
<outline/> <outline/>
<lockdata>false</lockdata> <lockdata>false</lockdata>
<dateadded>2022-02-02 02:02:02</dateadded> <dateadded>2033-03-03 03:03:03</dateadded>
<title>1</title> <title>1</title>
<sorttitle>1</sorttitle> <sorttitle>1</sorttitle>
</person>"#, </person>"#,
@@ -561,7 +569,7 @@ mod tests {
}; };
assert_eq!( assert_eq!(
NFOSerializer(ModelWrapper::Page(&page), NFOMode::EPOSODE) NFOSerializer(ModelWrapper::Page(&page), NFOMode::EPOSODE)
.generate_nfo() .generate_nfo(&NFOTimeType::FavTime)
.await .await
.unwrap(), .unwrap(),
r#"<?xml version="1.0" encoding="utf-8" standalone="yes"?> r#"<?xml version="1.0" encoding="utf-8" standalone="yes"?>