feat: 支持设置快捷订阅的路径默认值 (#502)

This commit is contained in:
ᴀᴍᴛᴏᴀᴇʀ
2025-10-14 18:44:33 +08:00
committed by GitHub
parent c7e0d31811
commit 84d353365a
13 changed files with 153 additions and 80 deletions
+6 -1
View File
@@ -1,5 +1,5 @@
use bili_sync_entity::rule::Rule;
use serde::Deserialize;
use serde::{Deserialize, Serialize};
use validator::Validate;
use crate::bilibili::CollectionType;
@@ -91,3 +91,8 @@ pub struct UpdateVideoSourceRequest {
pub rule: Option<Rule>,
pub use_dynamic_api: Option<bool>,
}
#[derive(Serialize, Deserialize)]
pub struct DefaultPathRequest {
pub name: String,
}
@@ -2,7 +2,7 @@ use std::sync::Arc;
use anyhow::Result;
use axum::Router;
use axum::extract::{Extension, Path};
use axum::extract::{Extension, Path, Query};
use axum::routing::{get, post, put};
use bili_sync_entity::rule::Rule;
use bili_sync_entity::*;
@@ -14,19 +14,25 @@ use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, QuerySelect, Transac
use crate::adapter::_ActiveModel;
use crate::api::error::InnerApiError;
use crate::api::request::{
InsertCollectionRequest, InsertFavoriteRequest, InsertSubmissionRequest, UpdateVideoSourceRequest,
DefaultPathRequest, InsertCollectionRequest, InsertFavoriteRequest, InsertSubmissionRequest,
UpdateVideoSourceRequest,
};
use crate::api::response::{
UpdateVideoSourceResponse, VideoSource, VideoSourceDetail, VideoSourcesDetailsResponse, VideoSourcesResponse,
};
use crate::api::wrapper::{ApiError, ApiResponse, ValidatedJson};
use crate::bilibili::{BiliClient, Collection, CollectionItem, FavoriteList, Submission};
use crate::config::{PathSafeTemplate, TEMPLATE};
use crate::utils::rule::FieldEvaluatable;
pub(super) fn router() -> Router {
Router::new()
.route("/video-sources", get(get_video_sources))
.route("/video-sources/details", get(get_video_sources_details))
.route(
"/video-sources/{type}/default-path",
get(get_video_sources_default_path),
) // 仅用于前端获取默认路径
.route("/video-sources/{type}/{id}", put(update_video_source))
.route("/video-sources/{type}/{id}/evaluate", post(evaluate_video_source))
.route("/video-sources/favorites", post(insert_favorite))
@@ -154,6 +160,20 @@ pub async fn get_video_sources_details(
}))
}
pub async fn get_video_sources_default_path(
Path(source_type): Path<String>,
Query(params): Query<DefaultPathRequest>,
) -> Result<ApiResponse<String>, ApiError> {
let template_name = match source_type.as_str() {
"favorites" => "favorite_default_path",
"collections" => "collection_default_path",
"submissions" => "submission_default_path",
_ => return Err(InnerApiError::BadRequest("Invalid video source type".to_string()).into()),
};
let (template, params) = (TEMPLATE.load(), serde_json::to_value(params)?);
Ok(ApiResponse::ok(template.path_safe_render(template_name, &params)?))
}
/// 更新视频来源
pub async fn update_video_source(
Path((source_type, id)): Path<(String, i32)>,
+12 -1
View File
@@ -8,7 +8,9 @@ use validator::Validate;
use crate::bilibili::{Credential, DanmakuOption, FilterOption};
use crate::config::default::{default_auth_token, default_bind_address, default_time_format};
use crate::config::item::{ConcurrentLimit, NFOTimeType, SkipOption};
use crate::config::item::{
ConcurrentLimit, NFOTimeType, SkipOption, default_collection_path, default_favorite_path, default_submission_path,
};
use crate::utils::model::{load_db_config, save_db_config};
pub static CONFIG_DIR: LazyLock<PathBuf> =
@@ -25,6 +27,12 @@ pub struct Config {
pub skip_option: SkipOption,
pub video_name: String,
pub page_name: String,
#[serde(default = "default_favorite_path")]
pub favorite_default_path: String,
#[serde(default = "default_collection_path")]
pub collection_default_path: String,
#[serde(default = "default_submission_path")]
pub submission_default_path: String,
pub interval: u64,
pub upper_path: PathBuf,
pub nfo_time_type: NFOTimeType,
@@ -98,6 +106,9 @@ impl Default for Config {
skip_option: SkipOption::default(),
video_name: "{{title}}".to_owned(),
page_name: "{{bvid}}".to_owned(),
favorite_default_path: default_favorite_path(),
collection_default_path: default_collection_path(),
submission_default_path: default_submission_path(),
interval: 1200,
upper_path: CONFIG_DIR.join("upper_face"),
nfo_time_type: NFOTimeType::FavTime,
+5 -2
View File
@@ -12,8 +12,11 @@ pub static TEMPLATE: LazyLock<VersionedCache<handlebars::Handlebars<'static>>> =
fn create_template(config: &Config) -> Result<handlebars::Handlebars<'static>> {
let mut handlebars = handlebars::Handlebars::new();
handlebars.register_helper("truncate", Box::new(truncate));
handlebars.path_safe_register("video", config.video_name.to_owned())?;
handlebars.path_safe_register("page", config.page_name.to_owned())?;
handlebars.path_safe_register("video", config.video_name.clone())?;
handlebars.path_safe_register("page", config.page_name.clone())?;
handlebars.path_safe_register("favorite_default_path", config.favorite_default_path.clone())?;
handlebars.path_safe_register("collection_default_path", config.collection_default_path.clone())?;
handlebars.path_safe_register("submission_default_path", config.submission_default_path.clone())?;
Ok(handlebars)
}
+12
View File
@@ -85,3 +85,15 @@ impl PathSafeTemplate for handlebars::Handlebars<'_> {
Ok(filenamify(&self.render(name, data)?).replace("__SEP__", std::path::MAIN_SEPARATOR_STR))
}
}
pub fn default_favorite_path() -> String {
"收藏夹/{{name}}".to_owned()
}
pub fn default_collection_path() -> String {
"合集/{{name}}".to_owned()
}
pub fn default_submission_path() -> String {
"投稿/{{name}}".to_owned()
}