From 52f8b2708f796afb0503141c527ea03f75fe92d9 Mon Sep 17 00:00:00 2001 From: amtoaer Date: Sun, 31 Mar 2024 14:00:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E4=BB=8E=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=AD=E8=AF=BB=E5=8F=96=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bilibili/analyzer.rs | 9 ++-- src/config.rs | 96 ++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 3 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/config.rs diff --git a/src/bilibili/analyzer.rs b/src/bilibili/analyzer.rs index 26b6a22..b6051f2 100644 --- a/src/bilibili/analyzer.rs +++ b/src/bilibili/analyzer.rs @@ -1,12 +1,14 @@ use std::sync::Arc; +use serde::{Deserialize, Serialize}; + use crate::Result; pub struct PageAnalyzer { info: serde_json::Value, } -#[derive(Debug, strum::FromRepr, PartialEq, PartialOrd)] +#[derive(Debug, strum::FromRepr, PartialEq, PartialOrd, Serialize, Deserialize)] pub enum VideoQuality { Quality360p = 16, Quality480p = 32, @@ -19,7 +21,7 @@ pub enum VideoQuality { QualityDolby = 126, Quality8k = 127, } -#[derive(Debug, strum::FromRepr, PartialEq, PartialOrd)] +#[derive(Debug, strum::FromRepr, PartialEq, PartialOrd, Serialize, Deserialize)] pub enum AudioQuality { Quality64k = 30216, Quality132k = 30232, @@ -28,7 +30,7 @@ pub enum AudioQuality { Quality192k = 30280, } -#[derive(Debug, strum::EnumString, strum::Display, PartialEq, PartialOrd)] +#[derive(Debug, strum::EnumString, strum::Display, PartialEq, PartialOrd, Serialize, Deserialize)] pub enum VideoCodecs { #[strum(serialize = "hev")] HEV, @@ -39,6 +41,7 @@ pub enum VideoCodecs { } // 视频流的筛选偏好 +#[derive(Serialize, Deserialize)] pub struct FilterOption { pub video_max_quality: VideoQuality, pub video_min_quality: VideoQuality, diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..01e3232 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,96 @@ +use std::collections::HashMap; +use std::path::Path; +use std::sync::Mutex; + +use log::warn; +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; + +use crate::bilibili::{Credential, FilterOption}; +use crate::Result; + +pub static CONFIG: Lazy> = Lazy::new(|| { + let config = Config::new(); + // 保存一次,确保配置文件存在 + config.save().unwrap(); + // 检查配置文件内容 + config.check(); + Mutex::new(Config::new()) +}); + +#[derive(Serialize, Deserialize)] +pub struct Config { + pub credential: Option, + pub filter_option: FilterOption, + pub favorite_list: HashMap, + pub video_name: String, + pub page_name: String, + pub interval: u64, +} + +impl Default for Config { + fn default() -> Self { + Self { + credential: Some(Credential::default()), + filter_option: FilterOption::default(), + favorite_list: HashMap::new(), + video_name: "{{bvid}}".to_string(), + page_name: "{{bvid}}".to_string(), + interval: 1200, + } + } +} +impl Config { + fn new() -> Self { + Config::load().unwrap_or_default() + } + + /// 简单的预检查 + pub fn check(&self) { + assert!( + !self.favorite_list.is_empty(), + "No favorite list found, program won't do anything" + ); + for path in self.favorite_list.values() { + assert!(Path::new(path).is_absolute(), "Path in favorite list must be absolute"); + } + assert!(!self.video_name.is_empty(), "No video name template found"); + assert!(!self.page_name.is_empty(), "No page name template found"); + match self.credential { + Some(ref credential) => { + assert!( + !(credential.sessdata.is_empty() + || credential.bili_jct.is_empty() + || credential.buvid3.is_empty() + || credential.dedeuserid.is_empty() + || credential.ac_time_value.is_empty()), + "Credential is incomplete" + ) + } + None => { + warn!("No credential found, can't access high quality video"); + } + } + } + + fn load() -> Result { + let config_path = dirs::config_dir() + .ok_or("No config path found")? + .join("bili-sync") + .join("config.toml"); + let config_content = std::fs::read_to_string(config_path)?; + Ok(toml::from_str(&config_content)?) + } + + pub fn save(&self) -> Result<()> { + let config_path = dirs::config_dir() + .ok_or("No config path found")? + .join("bili-sync") + .join("config.toml"); + if let Some(parent) = config_path.parent() { + std::fs::create_dir_all(parent)?; + } + std::fs::write(config_path, toml::to_string_pretty(self)?)?; + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index ccc2d9d..de27b31 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ use std::error; pub mod bilibili; +pub mod config; pub mod core; pub mod database; pub mod downloader;