130 lines
4.2 KiB
Rust
130 lines
4.2 KiB
Rust
use std::path::PathBuf;
|
|
use std::sync::LazyLock;
|
|
|
|
use anyhow::{Result, bail};
|
|
use sea_orm::DatabaseConnection;
|
|
use serde::{Deserialize, Serialize};
|
|
use validator::Validate;
|
|
|
|
use crate::bilibili::{Credential, DanmakuOption, FilterOption};
|
|
use crate::config::LegacyConfig;
|
|
use crate::config::default::{default_auth_token, default_bind_address, default_time_format};
|
|
use crate::config::item::{ConcurrentLimit, NFOTimeType};
|
|
use crate::utils::model::{load_db_config, save_db_config};
|
|
|
|
pub static CONFIG_DIR: LazyLock<PathBuf> =
|
|
LazyLock::new(|| dirs::config_dir().expect("No config path found").join("bili-sync"));
|
|
|
|
#[derive(Serialize, Deserialize, Validate, Clone)]
|
|
pub struct Config {
|
|
pub auth_token: String,
|
|
pub bind_address: String,
|
|
pub credential: Credential,
|
|
pub filter_option: FilterOption,
|
|
pub danmaku_option: DanmakuOption,
|
|
pub video_name: String,
|
|
pub page_name: String,
|
|
pub interval: u64,
|
|
pub upper_path: PathBuf,
|
|
pub nfo_time_type: NFOTimeType,
|
|
pub concurrent_limit: ConcurrentLimit,
|
|
pub time_format: String,
|
|
pub cdn_sorting: bool,
|
|
pub version: u64,
|
|
}
|
|
|
|
impl Config {
|
|
pub async fn load_from_database(connection: &DatabaseConnection) -> Result<Option<Result<Self>>> {
|
|
load_db_config(connection).await
|
|
}
|
|
|
|
pub async fn save_to_database(&self, connection: &DatabaseConnection) -> Result<()> {
|
|
save_db_config(self, connection).await
|
|
}
|
|
|
|
pub fn check(&self) -> Result<()> {
|
|
let mut errors = Vec::new();
|
|
if !self.upper_path.is_absolute() {
|
|
errors.push("up 主头像保存的路径应为绝对路径");
|
|
}
|
|
if self.video_name.is_empty() {
|
|
errors.push("未设置 video_name 模板");
|
|
}
|
|
if self.page_name.is_empty() {
|
|
errors.push("未设置 page_name 模板");
|
|
}
|
|
let credential = &self.credential;
|
|
if credential.sessdata.is_empty()
|
|
|| credential.bili_jct.is_empty()
|
|
|| credential.buvid3.is_empty()
|
|
|| credential.dedeuserid.is_empty()
|
|
|| credential.ac_time_value.is_empty()
|
|
{
|
|
errors.push("Credential 信息不完整,请确保填写完整");
|
|
}
|
|
if !(self.concurrent_limit.video > 0 && self.concurrent_limit.page > 0) {
|
|
errors.push("video 和 page 允许的并发数必须大于 0");
|
|
}
|
|
if !errors.is_empty() {
|
|
bail!(
|
|
errors
|
|
.into_iter()
|
|
.map(|e| format!("- {}", e))
|
|
.collect::<Vec<_>>()
|
|
.join("\n")
|
|
);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub(super) fn test_default() -> Self {
|
|
Self {
|
|
cdn_sorting: true,
|
|
..Default::default()
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for Config {
|
|
fn default() -> Self {
|
|
Self {
|
|
auth_token: default_auth_token(),
|
|
bind_address: default_bind_address(),
|
|
credential: Credential::default(),
|
|
filter_option: FilterOption::default(),
|
|
danmaku_option: DanmakuOption::default(),
|
|
video_name: "{{title}}".to_owned(),
|
|
page_name: "{{bvid}}".to_owned(),
|
|
interval: 1200,
|
|
upper_path: CONFIG_DIR.join("upper_face"),
|
|
nfo_time_type: NFOTimeType::FavTime,
|
|
concurrent_limit: ConcurrentLimit::default(),
|
|
time_format: default_time_format(),
|
|
cdn_sorting: false,
|
|
version: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<LegacyConfig> for Config {
|
|
fn from(legacy: LegacyConfig) -> Self {
|
|
Self {
|
|
auth_token: legacy.auth_token,
|
|
bind_address: legacy.bind_address,
|
|
credential: legacy.credential,
|
|
filter_option: legacy.filter_option,
|
|
danmaku_option: legacy.danmaku_option,
|
|
video_name: legacy.video_name,
|
|
page_name: legacy.page_name,
|
|
interval: legacy.interval,
|
|
upper_path: legacy.upper_path,
|
|
nfo_time_type: legacy.nfo_time_type,
|
|
concurrent_limit: legacy.concurrent_limit,
|
|
time_format: legacy.time_format,
|
|
cdn_sorting: legacy.cdn_sorting,
|
|
version: 0,
|
|
}
|
|
}
|
|
}
|