chore: 移除 utoipa (#375)
This commit is contained in:
121
Cargo.lock
generated
121
Cargo.lock
generated
@@ -136,15 +136,6 @@ dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
|
||||
dependencies = [
|
||||
"derive_arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.7.1"
|
||||
@@ -520,8 +511,6 @@ dependencies = [
|
||||
"tower",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"utoipa",
|
||||
"utoipa-swagger-ui",
|
||||
"validator",
|
||||
]
|
||||
|
||||
@@ -951,17 +940,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_arbitrary"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder"
|
||||
version = "0.20.2"
|
||||
@@ -1781,7 +1759,6 @@ checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.2",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1943,12 +1920,6 @@ dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lockfree-object-pool"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
@@ -2001,16 +1972,6 @@ version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.2"
|
||||
@@ -3252,12 +3213,6 @@ dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "simdutf8"
|
||||
version = "0.1.4"
|
||||
@@ -4045,51 +4000,6 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "utoipa"
|
||||
version = "5.3.1"
|
||||
source = "git+https://github.com/amtoaer/utoipa.git?tag=v1.0.1#6d66603333218fe4d0f36e40fc662628c6682a79"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"utoipa-gen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utoipa-gen"
|
||||
version = "5.3.1"
|
||||
source = "git+https://github.com/amtoaer/utoipa.git?tag=v1.0.1#6d66603333218fe4d0f36e40fc662628c6682a79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utoipa-swagger-ui"
|
||||
version = "9.0.0"
|
||||
source = "git+https://github.com/amtoaer/utoipa.git?tag=v1.0.1#6d66603333218fe4d0f36e40fc662628c6682a79"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"base64",
|
||||
"mime_guess",
|
||||
"regex",
|
||||
"rust-embed-for-web",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
"utoipa",
|
||||
"utoipa-swagger-ui-vendored",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utoipa-swagger-ui-vendored"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/amtoaer/utoipa.git?tag=v1.0.1#6d66603333218fe4d0f36e40fc662628c6682a79"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.8.0"
|
||||
@@ -4705,34 +4615,3 @@ dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd56a4d5921bc2f99947ac5b3abe5f510b1be7376fdc5e9fce4a23c6a93e87c"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"crc32fast",
|
||||
"crossbeam-utils",
|
||||
"displaydoc",
|
||||
"flate2",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
"thiserror 1.0.63",
|
||||
"zopfli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zopfli"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"crc32fast",
|
||||
"lockfree-object-pool",
|
||||
"log",
|
||||
"once_cell",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
@@ -71,13 +71,6 @@ toml = "0.8.22"
|
||||
tower = "0.5.2"
|
||||
tracing = "0.1.41"
|
||||
tracing-subscriber = { version = "0.3.19", features = ["chrono"] }
|
||||
utoipa = { git = "https://github.com/amtoaer/utoipa.git", tag = "v1.0.1", features = [
|
||||
"axum_extras",
|
||||
] }
|
||||
utoipa-swagger-ui = { git = "https://github.com/amtoaer/utoipa.git", tag = "v1.0.1", features = [
|
||||
"axum",
|
||||
"vendored",
|
||||
] }
|
||||
validator = { version = "0.20.0", features = ["derive"] }
|
||||
|
||||
[workspace.metadata.release]
|
||||
|
||||
@@ -50,8 +50,6 @@ toml = { workspace = true }
|
||||
tower = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
utoipa = { workspace = true }
|
||||
utoipa-swagger-ui = { workspace = true }
|
||||
validator = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -3,8 +3,6 @@ use axum::http::HeaderMap;
|
||||
use axum::middleware::Next;
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use reqwest::StatusCode;
|
||||
use utoipa::Modify;
|
||||
use utoipa::openapi::security::{ApiKey, ApiKeyValue, SecurityScheme};
|
||||
|
||||
use crate::api::wrapper::ApiResponse;
|
||||
use crate::config::VersionedConfig;
|
||||
@@ -24,19 +22,3 @@ fn get_token(headers: &HeaderMap) -> Option<String> {
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
pub(super) struct OpenAPIAuth;
|
||||
|
||||
impl Modify for OpenAPIAuth {
|
||||
fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
|
||||
if let Some(schema) = openapi.components.as_mut() {
|
||||
schema.add_security_scheme(
|
||||
"Token",
|
||||
SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::with_description(
|
||||
"Authorization",
|
||||
"与配置文件中的 auth_token 相同",
|
||||
))),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,9 @@ use sea_orm::{
|
||||
ColumnTrait, DatabaseConnection, EntityTrait, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect,
|
||||
TransactionTrait,
|
||||
};
|
||||
use utoipa::OpenApi;
|
||||
|
||||
use super::request::ImageProxyParams;
|
||||
use crate::adapter::_ActiveModel;
|
||||
use crate::api::auth::OpenAPIAuth;
|
||||
use crate::api::error::InnerApiError;
|
||||
use crate::api::helper::{update_page_download_status, update_video_download_status};
|
||||
use crate::api::request::{
|
||||
@@ -38,20 +36,6 @@ use crate::config::{Config, VersionedConfig};
|
||||
use crate::task::DOWNLOADER_TASK_RUNNING;
|
||||
use crate::utils::status::{PageStatus, VideoStatus};
|
||||
|
||||
#[derive(OpenApi)]
|
||||
#[openapi(
|
||||
paths(
|
||||
get_video_sources, get_video_sources_details, update_video_source, get_videos, get_video, reset_video, reset_all_videos, update_video_status,
|
||||
get_created_favorites, get_followed_collections, get_followed_uppers,
|
||||
insert_favorite, insert_collection, insert_submission
|
||||
),
|
||||
modifiers(&OpenAPIAuth),
|
||||
security(
|
||||
("Token" = []),
|
||||
)
|
||||
)]
|
||||
pub struct ApiDoc;
|
||||
|
||||
pub fn api_router() -> Router {
|
||||
Router::new()
|
||||
.route("/api/video-sources", get(get_video_sources))
|
||||
@@ -74,13 +58,6 @@ pub fn api_router() -> Router {
|
||||
}
|
||||
|
||||
/// 列出所有视频来源
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/video-sources",
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<VideoSourcesResponse>),
|
||||
)
|
||||
)]
|
||||
pub async fn get_video_sources(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
) -> Result<ApiResponse<VideoSourcesResponse>, ApiError> {
|
||||
@@ -124,16 +101,6 @@ pub async fn get_video_sources(
|
||||
}
|
||||
|
||||
/// 列出视频的基本信息,支持根据视频来源筛选、名称查找和分页
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/videos",
|
||||
params(
|
||||
VideosRequest,
|
||||
),
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<VideosResponse>),
|
||||
)
|
||||
)]
|
||||
pub async fn get_videos(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
Query(params): Query<VideosRequest>,
|
||||
@@ -169,14 +136,6 @@ pub async fn get_videos(
|
||||
}))
|
||||
}
|
||||
|
||||
/// 获取视频详细信息,包括关联的所有 page
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/videos/{id}",
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<VideoResponse>),
|
||||
)
|
||||
)]
|
||||
pub async fn get_video(
|
||||
Path(id): Path<i32>,
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
@@ -200,14 +159,6 @@ pub async fn get_video(
|
||||
}))
|
||||
}
|
||||
|
||||
/// 将某个视频与其所有分页的失败状态清空为未下载状态,这样在下次下载任务中会触发重试
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/videos/{id}/reset",
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<ResetVideoResponse>),
|
||||
)
|
||||
)]
|
||||
pub async fn reset_video(
|
||||
Path(id): Path<i32>,
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
@@ -268,14 +219,6 @@ pub async fn reset_video(
|
||||
}))
|
||||
}
|
||||
|
||||
/// 重置所有视频和页面的失败状态为未下载状态,这样在下次下载任务中会触发重试
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/videos/reset-all",
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<ResetAllVideosResponse>),
|
||||
)
|
||||
)]
|
||||
pub async fn reset_all_videos(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
) -> Result<ApiResponse<ResetAllVideosResponse>, ApiError> {
|
||||
@@ -333,15 +276,6 @@ pub async fn reset_all_videos(
|
||||
}))
|
||||
}
|
||||
|
||||
/// 更新特定视频及其所含分页的状态位
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/video/{id}/update-status",
|
||||
request_body = UpdateVideoStatusRequest,
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<UpdateVideoStatusResponse>),
|
||||
)
|
||||
)]
|
||||
pub async fn update_video_status(
|
||||
Path(id): Path<i32>,
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
@@ -399,14 +333,6 @@ pub async fn update_video_status(
|
||||
}))
|
||||
}
|
||||
|
||||
/// 获取当前用户创建的收藏夹列表,包含订阅状态
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/me/favorites",
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<FavoritesResponse>),
|
||||
)
|
||||
)]
|
||||
pub async fn get_created_favorites(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
Extension(bili_client): Extension<Arc<BiliClient>>,
|
||||
@@ -445,17 +371,6 @@ pub async fn get_created_favorites(
|
||||
Ok(ApiResponse::ok(FavoritesResponse { favorites }))
|
||||
}
|
||||
|
||||
/// 获取当前用户关注的合集列表,包含订阅状态
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/me/collections",
|
||||
params(
|
||||
FollowedCollectionsRequest,
|
||||
),
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<CollectionsResponse>),
|
||||
)
|
||||
)]
|
||||
pub async fn get_followed_collections(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
Extension(bili_client): Extension<Arc<BiliClient>>,
|
||||
@@ -497,16 +412,6 @@ pub async fn get_followed_collections(
|
||||
}))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/me/uppers",
|
||||
params(
|
||||
FollowedUppersRequest,
|
||||
),
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<UppersResponse>),
|
||||
)
|
||||
)]
|
||||
pub async fn get_followed_uppers(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
Extension(bili_client): Extension<Arc<BiliClient>>,
|
||||
@@ -547,14 +452,6 @@ pub async fn get_followed_uppers(
|
||||
}))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/video-sources/favorites",
|
||||
request_body = InsertFavoriteRequest,
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<bool>),
|
||||
)
|
||||
)]
|
||||
pub async fn insert_favorite(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
Extension(bili_client): Extension<Arc<BiliClient>>,
|
||||
@@ -574,14 +471,6 @@ pub async fn insert_favorite(
|
||||
Ok(ApiResponse::ok(true))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/video-sources/collections",
|
||||
request_body = InsertCollectionRequest,
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<bool>),
|
||||
)
|
||||
)]
|
||||
pub async fn insert_collection(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
Extension(bili_client): Extension<Arc<BiliClient>>,
|
||||
@@ -611,15 +500,6 @@ pub async fn insert_collection(
|
||||
Ok(ApiResponse::ok(true))
|
||||
}
|
||||
|
||||
/// 订阅UP主投稿
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/video-sources/submissions",
|
||||
request_body = InsertSubmissionRequest,
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<bool>),
|
||||
)
|
||||
)]
|
||||
pub async fn insert_submission(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
Extension(bili_client): Extension<Arc<BiliClient>>,
|
||||
@@ -640,14 +520,6 @@ pub async fn insert_submission(
|
||||
Ok(ApiResponse::ok(true))
|
||||
}
|
||||
|
||||
/// 获取所有视频源的详细信息,包括 path 和 enabled 状态
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/video-sources/details",
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<VideoSourcesDetailsResponse>),
|
||||
)
|
||||
)]
|
||||
pub async fn get_video_sources_details(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
) -> Result<ApiResponse<VideoSourcesDetailsResponse>, ApiError> {
|
||||
@@ -703,15 +575,6 @@ pub async fn get_video_sources_details(
|
||||
}))
|
||||
}
|
||||
|
||||
/// 更新视频源的 path 和 enabled 状态
|
||||
#[utoipa::path(
|
||||
put,
|
||||
path = "/api/video-sources/{type}/{id}",
|
||||
request_body = UpdateVideoSourceRequest,
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<bool>),
|
||||
)
|
||||
)]
|
||||
pub async fn update_video_source(
|
||||
Path((source_type, id)): Path<(String, i32)>,
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
@@ -769,25 +632,10 @@ pub async fn update_video_source(
|
||||
Ok(ApiResponse::ok(true))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/config",
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<Config>),
|
||||
)
|
||||
)]
|
||||
pub async fn get_config() -> Result<ApiResponse<Arc<Config>>, ApiError> {
|
||||
Ok(ApiResponse::ok(VersionedConfig::get().load_full()))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
put,
|
||||
path = "/api/config",
|
||||
request_body = Config,
|
||||
responses(
|
||||
(status = 200, body = ApiResponse<Config>),
|
||||
)
|
||||
)]
|
||||
pub async fn update_config(
|
||||
Extension(db): Extension<Arc<DatabaseConnection>>,
|
||||
ValidatedJson(config): ValidatedJson<Config>,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use serde::Deserialize;
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
use validator::Validate;
|
||||
|
||||
use crate::bilibili::CollectionType;
|
||||
#[derive(Deserialize, IntoParams)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct VideosRequest {
|
||||
pub collection: Option<i32>,
|
||||
pub favorite: Option<i32>,
|
||||
@@ -14,7 +13,7 @@ pub struct VideosRequest {
|
||||
pub page_size: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Validate, ToSchema)]
|
||||
#[derive(Deserialize, Validate)]
|
||||
pub struct StatusUpdate {
|
||||
#[validate(range(min = 0, max = 4))]
|
||||
pub status_index: usize,
|
||||
@@ -22,14 +21,14 @@ pub struct StatusUpdate {
|
||||
pub status_value: u32,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, ToSchema, Validate)]
|
||||
#[derive(Deserialize, Validate)]
|
||||
pub struct PageStatusUpdate {
|
||||
pub page_id: i32,
|
||||
#[validate(nested)]
|
||||
pub updates: Vec<StatusUpdate>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, ToSchema, Validate)]
|
||||
#[derive(Deserialize, Validate)]
|
||||
pub struct UpdateVideoStatusRequest {
|
||||
#[serde(default)]
|
||||
#[validate(nested)]
|
||||
@@ -39,49 +38,48 @@ pub struct UpdateVideoStatusRequest {
|
||||
pub page_updates: Vec<PageStatusUpdate>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, IntoParams)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct FollowedCollectionsRequest {
|
||||
pub page_num: Option<i32>,
|
||||
pub page_size: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, IntoParams)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct FollowedUppersRequest {
|
||||
pub page_num: Option<i32>,
|
||||
pub page_size: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, ToSchema, Validate)]
|
||||
#[derive(Deserialize, Validate)]
|
||||
pub struct InsertFavoriteRequest {
|
||||
pub fid: i64,
|
||||
#[validate(custom(function = "crate::utils::validation::validate_path"))]
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, ToSchema, Validate)]
|
||||
#[derive(Deserialize, Validate)]
|
||||
pub struct InsertCollectionRequest {
|
||||
pub sid: i64,
|
||||
pub mid: i64,
|
||||
#[schema(value_type = i8)]
|
||||
#[serde(default)]
|
||||
pub collection_type: CollectionType,
|
||||
#[validate(custom(function = "crate::utils::validation::validate_path"))]
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, ToSchema, Validate)]
|
||||
#[derive(Deserialize, Validate)]
|
||||
pub struct InsertSubmissionRequest {
|
||||
pub upper_id: i64,
|
||||
#[validate(custom(function = "crate::utils::validation::validate_path"))]
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, IntoParams)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct ImageProxyParams {
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, ToSchema, Validate)]
|
||||
#[derive(Deserialize, Validate)]
|
||||
pub struct UpdateVideoSourceRequest {
|
||||
#[validate(custom(function = "crate::utils::validation::validate_path"))]
|
||||
pub path: String,
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use bili_sync_entity::*;
|
||||
use sea_orm::{DerivePartialModel, FromQueryResult};
|
||||
use serde::Serialize;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use crate::utils::status::{PageStatus, VideoStatus};
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct VideoSourcesResponse {
|
||||
pub collection: Vec<VideoSource>,
|
||||
pub favorite: Vec<VideoSource>,
|
||||
@@ -13,64 +12,62 @@ pub struct VideoSourcesResponse {
|
||||
pub watch_later: Vec<VideoSource>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct VideosResponse {
|
||||
pub videos: Vec<VideoInfo>,
|
||||
pub total_count: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct VideoResponse {
|
||||
pub video: VideoInfo,
|
||||
pub pages: Vec<PageInfo>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct ResetVideoResponse {
|
||||
pub resetted: bool,
|
||||
pub video: VideoInfo,
|
||||
pub pages: Vec<PageInfo>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct ResetAllVideosResponse {
|
||||
pub resetted: bool,
|
||||
pub resetted_videos_count: usize,
|
||||
pub resetted_pages_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct UpdateVideoStatusResponse {
|
||||
pub success: bool,
|
||||
pub video: VideoInfo,
|
||||
pub pages: Vec<PageInfo>,
|
||||
}
|
||||
|
||||
#[derive(FromQueryResult, Serialize, ToSchema)]
|
||||
#[derive(FromQueryResult, Serialize)]
|
||||
pub struct VideoSource {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema, DerivePartialModel, FromQueryResult)]
|
||||
#[derive(Serialize, DerivePartialModel, FromQueryResult)]
|
||||
#[sea_orm(entity = "video::Entity")]
|
||||
pub struct VideoInfo {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub upper_name: String,
|
||||
#[schema(value_type = [u32; 5])]
|
||||
#[serde(serialize_with = "serde_video_download_status")]
|
||||
pub download_status: u32,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema, DerivePartialModel, FromQueryResult)]
|
||||
#[derive(Serialize, DerivePartialModel, FromQueryResult)]
|
||||
#[sea_orm(entity = "page::Entity")]
|
||||
pub struct PageInfo {
|
||||
pub id: i32,
|
||||
pub video_id: i32,
|
||||
pub pid: i32,
|
||||
pub name: String,
|
||||
#[schema(value_type = [u32; 5])]
|
||||
#[serde(serialize_with = "serde_page_download_status")]
|
||||
pub download_status: u32,
|
||||
}
|
||||
@@ -91,7 +88,7 @@ where
|
||||
status.serialize(serializer)
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct FavoriteWithSubscriptionStatus {
|
||||
pub title: String,
|
||||
pub media_count: i64,
|
||||
@@ -100,7 +97,7 @@ pub struct FavoriteWithSubscriptionStatus {
|
||||
pub subscribed: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct CollectionWithSubscriptionStatus {
|
||||
pub title: String,
|
||||
pub sid: i64,
|
||||
@@ -109,7 +106,7 @@ pub struct CollectionWithSubscriptionStatus {
|
||||
pub subscribed: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct UpperWithSubscriptionStatus {
|
||||
pub mid: i64,
|
||||
pub uname: String,
|
||||
@@ -119,24 +116,24 @@ pub struct UpperWithSubscriptionStatus {
|
||||
pub subscribed: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct FavoritesResponse {
|
||||
pub favorites: Vec<FavoriteWithSubscriptionStatus>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct CollectionsResponse {
|
||||
pub collections: Vec<CollectionWithSubscriptionStatus>,
|
||||
pub total: i64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct UppersResponse {
|
||||
pub uppers: Vec<UpperWithSubscriptionStatus>,
|
||||
pub total: i64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize)]
|
||||
pub struct VideoSourcesDetailsResponse {
|
||||
pub collections: Vec<VideoSourceDetail>,
|
||||
pub favorites: Vec<VideoSourceDetail>,
|
||||
@@ -144,7 +141,7 @@ pub struct VideoSourcesDetailsResponse {
|
||||
pub watch_later: Vec<VideoSourceDetail>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema, FromQueryResult)]
|
||||
#[derive(Serialize, FromQueryResult)]
|
||||
pub struct VideoSourceDetail {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
|
||||
@@ -8,12 +8,11 @@ use axum::response::IntoResponse;
|
||||
use reqwest::StatusCode;
|
||||
use serde::Serialize;
|
||||
use serde::de::DeserializeOwned;
|
||||
use utoipa::ToSchema;
|
||||
use validator::Validate;
|
||||
|
||||
use crate::api::error::InnerApiError;
|
||||
|
||||
#[derive(ToSchema, Serialize)]
|
||||
#[derive(Serialize)]
|
||||
pub struct ApiResponse<T: Serialize> {
|
||||
status_code: u16,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use anyhow::{Context, Result, bail};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use crate::bilibili::error::BiliError;
|
||||
use crate::config::VersionedConfig;
|
||||
@@ -9,7 +8,7 @@ pub struct PageAnalyzer {
|
||||
info: serde_json::Value,
|
||||
}
|
||||
|
||||
#[derive(Debug, strum::FromRepr, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, ToSchema, Clone)]
|
||||
#[derive(Debug, strum::FromRepr, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Clone)]
|
||||
pub enum VideoQuality {
|
||||
Quality360p = 16,
|
||||
Quality480p = 32,
|
||||
@@ -23,7 +22,7 @@ pub enum VideoQuality {
|
||||
Quality8k = 127,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, strum::FromRepr, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Copy, strum::FromRepr, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum AudioQuality {
|
||||
Quality64k = 30216,
|
||||
Quality132k = 30232,
|
||||
@@ -56,16 +55,7 @@ impl AudioQuality {
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[derive(
|
||||
Debug,
|
||||
strum::EnumString,
|
||||
strum::Display,
|
||||
strum::AsRefStr,
|
||||
PartialEq,
|
||||
PartialOrd,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
ToSchema,
|
||||
Clone,
|
||||
Debug, strum::EnumString, strum::Display, strum::AsRefStr, PartialEq, PartialOrd, Serialize, Deserialize, Clone,
|
||||
)]
|
||||
pub enum VideoCodecs {
|
||||
#[strum(serialize = "hev")]
|
||||
@@ -91,7 +81,7 @@ impl TryFrom<u64> for VideoCodecs {
|
||||
}
|
||||
|
||||
// 视频流的筛选偏好
|
||||
#[derive(Serialize, Deserialize, ToSchema, Clone)]
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct FilterOption {
|
||||
pub video_max_quality: VideoQuality,
|
||||
pub video_min_quality: VideoQuality,
|
||||
|
||||
@@ -10,7 +10,6 @@ use rsa::pkcs8::DecodePublicKey;
|
||||
use rsa::sha2::Sha256;
|
||||
use rsa::{Oaep, RsaPublicKey};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use crate::bilibili::{Client, Validate};
|
||||
|
||||
@@ -20,7 +19,7 @@ const MIXIN_KEY_ENC_TAB: [usize; 64] = [
|
||||
20, 34, 44, 52,
|
||||
];
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Credential {
|
||||
pub sessdata: String,
|
||||
pub bili_jct: String,
|
||||
|
||||
@@ -4,14 +4,13 @@ mod lane;
|
||||
use anyhow::Result;
|
||||
use float_ord::FloatOrd;
|
||||
use lane::Lane;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use crate::bilibili::PageInfo;
|
||||
use crate::bilibili::danmaku::canvas::lane::Collision;
|
||||
use crate::bilibili::danmaku::danmu::DanmuType;
|
||||
use crate::bilibili::danmaku::{Danmu, DrawEffect, Drawable};
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, ToSchema)]
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct DanmakuOption {
|
||||
pub duration: f64,
|
||||
pub font: String,
|
||||
|
||||
@@ -4,7 +4,6 @@ use std::sync::LazyLock;
|
||||
use anyhow::{Result, bail};
|
||||
use sea_orm::DatabaseConnection;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
use validator::Validate;
|
||||
|
||||
use crate::bilibili::{Credential, DanmakuOption, FilterOption};
|
||||
@@ -16,7 +15,7 @@ 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, ToSchema, Validate, Clone)]
|
||||
#[derive(Serialize, Deserialize, Validate, Clone)]
|
||||
pub struct Config {
|
||||
pub auth_token: String,
|
||||
pub bind_address: String,
|
||||
@@ -26,7 +25,6 @@ pub struct Config {
|
||||
pub video_name: String,
|
||||
pub page_name: String,
|
||||
pub interval: u64,
|
||||
#[schema(value_type = String)]
|
||||
pub upper_path: PathBuf,
|
||||
pub nfo_time_type: NFOTimeType,
|
||||
pub concurrent_limit: ConcurrentLimit,
|
||||
|
||||
@@ -2,7 +2,6 @@ use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use crate::utils::filenamify::filenamify;
|
||||
|
||||
@@ -14,7 +13,7 @@ pub struct WatchLaterConfig {
|
||||
}
|
||||
|
||||
/// NFO 文件使用的时间类型
|
||||
#[derive(Serialize, Deserialize, Default, ToSchema, Clone)]
|
||||
#[derive(Serialize, Deserialize, Default, Clone)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum NFOTimeType {
|
||||
#[default]
|
||||
@@ -23,7 +22,7 @@ pub enum NFOTimeType {
|
||||
}
|
||||
|
||||
/// 并发下载相关的配置
|
||||
#[derive(Serialize, Deserialize, ToSchema, Clone)]
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct ConcurrentLimit {
|
||||
pub video: usize,
|
||||
pub page: usize,
|
||||
@@ -32,7 +31,7 @@ pub struct ConcurrentLimit {
|
||||
pub download: ConcurrentDownloadLimit,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema, Clone)]
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct ConcurrentDownloadLimit {
|
||||
pub enable: bool,
|
||||
pub concurrency: usize,
|
||||
@@ -49,7 +48,7 @@ impl Default for ConcurrentDownloadLimit {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema, Clone)]
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct RateLimit {
|
||||
pub limit: usize,
|
||||
pub duration: u64,
|
||||
|
||||
@@ -9,11 +9,9 @@ use axum::{Extension, Router, ServiceExt, middleware};
|
||||
use reqwest::StatusCode;
|
||||
use rust_embed_for_web::{EmbedableFile, RustEmbed};
|
||||
use sea_orm::DatabaseConnection;
|
||||
use utoipa::OpenApi;
|
||||
use utoipa_swagger_ui::{Config, SwaggerUi};
|
||||
|
||||
use crate::api::auth;
|
||||
use crate::api::handler::{ApiDoc, api_router};
|
||||
use crate::api::handler::api_router;
|
||||
use crate::bilibili::BiliClient;
|
||||
use crate::config::VersionedConfig;
|
||||
|
||||
@@ -26,16 +24,6 @@ struct Asset;
|
||||
pub async fn http_server(database_connection: Arc<DatabaseConnection>, bili_client: Arc<BiliClient>) -> Result<()> {
|
||||
let app = Router::new()
|
||||
.merge(api_router())
|
||||
.merge(
|
||||
SwaggerUi::new("/swagger-ui/")
|
||||
.url("/api-docs/openapi.json", ApiDoc::openapi())
|
||||
.config(
|
||||
Config::default()
|
||||
.try_it_out_enabled(true)
|
||||
.persist_authorization(true)
|
||||
.validator_url("none"),
|
||||
),
|
||||
)
|
||||
.fallback_service(get(frontend_files))
|
||||
.layer(Extension(database_connection))
|
||||
.layer(Extension(bili_client))
|
||||
|
||||
Reference in New Issue
Block a user