chore: 大幅缩减构建结果的二进制文件体积 (#356)

This commit is contained in:
ᴀᴍᴛᴏᴀᴇʀ
2025-06-06 23:34:46 +08:00
committed by GitHub
parent 65a047b0fa
commit 586d5ec4ee
11 changed files with 175 additions and 74 deletions

View File

@@ -29,7 +29,6 @@ hex = { workspace = true }
leaky-bucket = { workspace = true }
md5 = { workspace = true }
memchr = { workspace = true }
mime_guess = { workspace = true }
once_cell = { workspace = true }
prost = { workspace = true }
quick-xml = { workspace = true }
@@ -37,7 +36,7 @@ rand = { workspace = true }
regex = { workspace = true }
reqwest = { workspace = true }
rsa = { workspace = true }
rust-embed = { workspace = true }
rust-embed-for-web = { workspace = true }
sea-orm = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }

View File

@@ -14,9 +14,9 @@ use utoipa::OpenApi;
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::{ResetVideoStatusRequest, VideosRequest};
use crate::api::request::{UpdateVideoStatusRequest, VideosRequest};
use crate::api::response::{
PageInfo, ResetAllVideosResponse, ResetVideoResponse, ResetVideoStatusResponse, VideoInfo, VideoResponse,
PageInfo, ResetAllVideosResponse, ResetVideoResponse, UpdateVideoStatusResponse, VideoInfo, VideoResponse,
VideoSource, VideoSourcesResponse, VideosResponse,
};
use crate::api::wrapper::{ApiError, ApiResponse, ValidatedJson};
@@ -24,7 +24,7 @@ use crate::utils::status::{PageStatus, VideoStatus};
#[derive(OpenApi)]
#[openapi(
paths(get_video_sources, get_videos, get_video, reset_video, reset_all_videos, reset_video_status),
paths(get_video_sources, get_videos, get_video, reset_video, reset_all_videos, update_video_status),
modifiers(&OpenAPIAuth),
security(
("Token" = []),
@@ -284,20 +284,20 @@ pub async fn reset_all_videos(
}))
}
/// 重置指定视频及其分页的指定状态位
/// 更新特定视频及其所含分页的状态位
#[utoipa::path(
post,
path = "/api/videos/{id}/reset-status",
request_body = ResetVideoStatusRequest,
path = "/api/videos/{id}/update-status",
request_body = UpdateVideoStatusRequest,
responses(
(status = 200, body = ApiResponse<ResetVideoStatusResponse>),
(status = 200, body = ApiResponse<UpdateVideoStatusResponse>),
)
)]
pub async fn reset_video_status(
pub async fn update_video_status(
Path(id): Path<i32>,
Extension(db): Extension<Arc<DatabaseConnection>>,
ValidatedJson(request): ValidatedJson<ResetVideoStatusRequest>,
) -> Result<ApiResponse<ResetVideoStatusResponse>, ApiError> {
ValidatedJson(request): ValidatedJson<UpdateVideoStatusRequest>,
) -> Result<ApiResponse<UpdateVideoStatusResponse>, ApiError> {
let (video_info, mut pages_info) = tokio::try_join!(
video::Entity::find_by_id(id)
.into_partial_model::<VideoInfo>()
@@ -343,7 +343,7 @@ pub async fn reset_video_status(
}
txn.commit().await?;
}
Ok(ApiResponse::ok(ResetVideoStatusResponse {
Ok(ApiResponse::ok(UpdateVideoStatusResponse {
success: has_video_updates || has_page_updates,
video: video_info,
pages: pages_info,

View File

@@ -28,7 +28,7 @@ pub struct PageStatusUpdate {
}
#[derive(Deserialize, ToSchema, Validate)]
pub struct ResetVideoStatusRequest {
pub struct UpdateVideoStatusRequest {
#[serde(default)]
#[validate(nested)]
pub video_updates: Vec<StatusUpdate>,

View File

@@ -40,7 +40,7 @@ pub struct ResetAllVideosResponse {
}
#[derive(Serialize, ToSchema)]
pub struct ResetVideoStatusResponse {
pub struct UpdateVideoStatusResponse {
pub success: bool,
pub video: VideoInfo,
pub pages: Vec<PageInfo>,
@@ -58,6 +58,7 @@ 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,
}
@@ -69,6 +70,7 @@ pub struct PageInfo {
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,
}

View File

@@ -1,24 +1,27 @@
use std::sync::Arc;
use anyhow::{Context, Result};
use axum::body::Body;
use axum::extract::Request;
use axum::http::{Uri, header};
use axum::http::{Response, Uri, header};
use axum::response::IntoResponse;
use axum::routing::{get, post};
use axum::{Extension, Router, ServiceExt, middleware};
use reqwest::StatusCode;
use rust_embed::Embed;
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, get_video, get_video_sources, get_videos, reset_all_videos, reset_video, reset_video_status,
ApiDoc, get_video, get_video_sources, get_videos, reset_all_videos, reset_video, update_video_status,
};
use crate::config::CONFIG;
#[derive(Embed)]
#[derive(RustEmbed)]
#[preserve_source = false]
#[gzip = false]
#[folder = "../../web/build"]
struct Asset;
@@ -28,7 +31,7 @@ pub async fn http_server(database_connection: Arc<DatabaseConnection>) -> Result
.route("/api/videos", get(get_videos))
.route("/api/videos/{id}", get(get_video))
.route("/api/videos/{id}/reset", post(reset_video))
.route("/api/videos/{id}/reset-status", post(reset_video_status))
.route("/api/videos/{id}/update-status", post(update_video_status))
.route("/api/videos/reset-all", post(reset_all_videos))
.merge(
SwaggerUi::new("/swagger-ui/")
@@ -55,11 +58,19 @@ async fn frontend_files(uri: Uri) -> impl IntoResponse {
if path.is_empty() || Asset::get(path).is_none() {
path = "index.html";
}
match Asset::get(path) {
Some(content) => {
let mime = mime_guess::from_path(path).first_or_octet_stream();
([(header::CONTENT_TYPE, mime.as_ref())], content.data).into_response()
}
None => (StatusCode::NOT_FOUND, "404 Not Found").into_response(),
}
let Some(content) = Asset::get(path) else {
return (StatusCode::NOT_FOUND, "404 Not Found").into_response();
};
Response::builder()
.status(StatusCode::OK)
.header(
header::CONTENT_TYPE,
content.mime_type().as_deref().unwrap_or("application/octet-stream"),
)
.header(header::CONTENT_ENCODING, "br")
// safety: `RustEmbed` will always generate br-compressed files if the feature is enabled
.body(Body::from(content.data_br().unwrap()))
.unwrap_or_else(|_| {
return (StatusCode::INTERNAL_SERVER_ERROR, "500 Internal Server Error").into_response();
})
}