From fbb7623ee1a1916411ec352aae92e3547b047b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=B4=80=E1=B4=8D=E1=B4=9B=E1=B4=8F=E1=B4=80=E1=B4=87?= =?UTF-8?q?=CA=80?= Date: Tue, 8 Jul 2025 14:37:31 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B0=9D=E8=AF=95=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E9=94=99=E8=AF=AF=20(#379)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 133 ++++---------------- Cargo.toml | 3 +- crates/bili_sync/Cargo.toml | 3 +- crates/bili_sync/src/adapter/collection.rs | 38 +++--- crates/bili_sync/src/adapter/favorite.rs | 25 ++-- crates/bili_sync/src/adapter/submission.rs | 25 ++-- crates/bili_sync/src/bilibili/collection.rs | 2 +- crates/bili_sync/src/bilibili/submission.rs | 2 +- crates/bili_sync/src/task/http_server.rs | 25 +--- 9 files changed, 78 insertions(+), 178 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f53458..a1fb247 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,21 +43,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "allocator-api2" version = "0.2.16" @@ -444,12 +429,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "base85rs" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87678d33a2af71f019ed11f52db246ca6c5557edee2cccbe689676d1ad9c6b5a" - [[package]] name = "bigdecimal" version = "0.4.7" @@ -490,6 +469,7 @@ dependencies = [ "leaky-bucket", "md5", "memchr", + "mime_guess", "once_cell", "parking_lot", "prost", @@ -498,7 +478,7 @@ dependencies = [ "regex", "reqwest", "rsa", - "rust-embed-for-web", + "rust-embed", "sea-orm", "serde", "serde_json", @@ -609,37 +589,6 @@ dependencies = [ "syn_derive", ] -[[package]] -name = "brotli" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a334ef7c9e23abf0ce748e8cd309037da93e606ad52eb372e4ce327a0dcfbdfd" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bstr" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "built" version = "0.7.7" @@ -1354,19 +1303,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "globset" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - [[package]] name = "gloo-timers" version = "0.3.0" @@ -1975,6 +1911,16 @@ 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" @@ -1996,16 +1942,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "new_mime_guess" -version = "4.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a2dfb3559d53e90b709376af1c379462f7fb3085a0177deb73e6ea0d99eff4" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "ntapi" version = "0.4.1" @@ -2803,41 +2739,35 @@ dependencies = [ ] [[package]] -name = "rust-embed-for-web" -version = "11.2.1" -source = "git+https://github.com/amtoaer/rust-embed-for-web?tag=v1.0.0#b6eeb475cbe1ad5cae02d5373a1bba12ea58a869" +name = "rust-embed" +version = "8.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a" dependencies = [ - "rust-embed-for-web-impl", - "rust-embed-for-web-utils", + "rust-embed-impl", + "rust-embed-utils", "walkdir", ] [[package]] -name = "rust-embed-for-web-impl" -version = "11.2.1" -source = "git+https://github.com/amtoaer/rust-embed-for-web?tag=v1.0.0#b6eeb475cbe1ad5cae02d5373a1bba12ea58a869" +name = "rust-embed-impl" +version = "8.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c" dependencies = [ - "brotli", - "flate2", - "globset", "proc-macro2", "quote", - "rust-embed-for-web-utils", - "shellexpand", + "rust-embed-utils", "syn 2.0.96", "walkdir", ] [[package]] -name = "rust-embed-for-web-utils" -version = "11.2.1" -source = "git+https://github.com/amtoaer/rust-embed-for-web?tag=v1.0.0#b6eeb475cbe1ad5cae02d5373a1bba12ea58a869" +name = "rust-embed-utils" +version = "8.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594" dependencies = [ - "base85rs", - "chrono", - "enum_dispatch", - "globset", - "new_mime_guess", "sha2", "walkdir", ] @@ -3210,15 +3140,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shellexpand" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb" -dependencies = [ - "dirs", -] - [[package]] name = "shlex" version = "1.3.0" diff --git a/Cargo.toml b/Cargo.toml index 52ca798..79b8de4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ hex = "0.4.3" leaky-bucket = "1.1.2" md5 = "0.7.0" memchr = "2.7.4" +mime_guess = "2.0.5" once_cell = "1.21.3" parking_lot = "0.12.4" prost = "0.13.5" @@ -53,7 +54,7 @@ reqwest = { version = "0.12.15", features = [ "stream", ], default-features = false } rsa = { version = "0.9.8", features = ["sha2"] } -rust-embed-for-web = { git = "https://github.com/amtoaer/rust-embed-for-web", tag = "v1.0.0" } +rust-embed = "8.7.2" sea-orm = { version = "1.1.11", features = [ "macros", "runtime-tokio-rustls", diff --git a/crates/bili_sync/Cargo.toml b/crates/bili_sync/Cargo.toml index 62e11d1..16b8c09 100644 --- a/crates/bili_sync/Cargo.toml +++ b/crates/bili_sync/Cargo.toml @@ -29,6 +29,7 @@ hex = { workspace = true } leaky-bucket = { workspace = true } md5 = { workspace = true } memchr = { workspace = true } +mime_guess = { workspace = true } once_cell = { workspace = true } parking_lot = { workspace = true } prost = { workspace = true } @@ -37,7 +38,7 @@ rand = { workspace = true } regex = { workspace = true } reqwest = { workspace = true } rsa = { workspace = true } -rust-embed-for-web = { workspace = true } +rust-embed = { workspace = true } sea-orm = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/crates/bili_sync/src/adapter/collection.rs b/crates/bili_sync/src/adapter/collection.rs index 3d22727..f2269ab 100644 --- a/crates/bili_sync/src/adapter/collection.rs +++ b/crates/bili_sync/src/adapter/collection.rs @@ -1,13 +1,13 @@ use std::path::Path; use std::pin::Pin; -use anyhow::{Context, Result}; +use anyhow::{Context, Result, ensure}; use bili_sync_entity::*; use chrono::Utc; use futures::Stream; use sea_orm::ActiveValue::Set; use sea_orm::entity::prelude::*; -use sea_orm::sea_query::{OnConflict, SimpleExpr}; +use sea_orm::sea_query::SimpleExpr; use sea_orm::{DatabaseConnection, Unchanged}; use crate::adapter::{_ActiveModel, VideoSource, VideoSourceEnum}; @@ -108,32 +108,24 @@ impl VideoSource for collection::Model { }, ); let collection_info = collection.get_info().await?; - collection::Entity::insert(collection::ActiveModel { - s_id: Set(collection_info.sid), - m_id: Set(collection_info.mid), - r#type: Set(collection_info.collection_type.into()), + ensure!( + collection_info.sid == self.s_id + && collection_info.mid == self.m_id + && collection_info.collection_type == CollectionType::from(self.r#type), + "collection info mismatch: {:?} != {:?}", + collection_info, + collection.collection + ); + collection::ActiveModel { + id: Unchanged(self.id), name: Set(collection_info.name.clone()), ..Default::default() - }) - .on_conflict( - OnConflict::columns([ - collection::Column::SId, - collection::Column::MId, - collection::Column::Type, - ]) - .update_column(collection::Column::Name) - .to_owned(), - ) - .exec(connection) + } + .save(connection) .await?; Ok(( collection::Entity::find() - .filter( - collection::Column::SId - .eq(self.s_id) - .and(collection::Column::MId.eq(self.m_id)) - .and(collection::Column::Type.eq(self.r#type)), - ) + .filter(collection::Column::Id.eq(self.id)) .one(connection) .await? .context("collection not found")? diff --git a/crates/bili_sync/src/adapter/favorite.rs b/crates/bili_sync/src/adapter/favorite.rs index 3ce8403..866f5fa 100644 --- a/crates/bili_sync/src/adapter/favorite.rs +++ b/crates/bili_sync/src/adapter/favorite.rs @@ -1,12 +1,12 @@ use std::path::Path; use std::pin::Pin; -use anyhow::{Context, Result}; +use anyhow::{Context, Result, ensure}; use bili_sync_entity::*; use futures::Stream; use sea_orm::ActiveValue::Set; use sea_orm::entity::prelude::*; -use sea_orm::sea_query::{OnConflict, SimpleExpr}; +use sea_orm::sea_query::SimpleExpr; use sea_orm::{DatabaseConnection, Unchanged}; use crate::adapter::{_ActiveModel, VideoSource, VideoSourceEnum}; @@ -71,21 +71,22 @@ impl VideoSource for favorite::Model { )> { let favorite = FavoriteList::new(bili_client, self.f_id.to_string()); let favorite_info = favorite.get_info().await?; - favorite::Entity::insert(favorite::ActiveModel { - f_id: Set(favorite_info.id), + ensure!( + favorite_info.id == self.f_id, + "favorite id mismatch: {} != {}", + favorite_info.id, + self.f_id + ); + favorite::ActiveModel { + id: Unchanged(self.id), name: Set(favorite_info.title.clone()), ..Default::default() - }) - .on_conflict( - OnConflict::column(favorite::Column::FId) - .update_column(favorite::Column::Name) - .to_owned(), - ) - .exec(connection) + } + .save(connection) .await?; Ok(( favorite::Entity::find() - .filter(favorite::Column::FId.eq(favorite_info.id)) + .filter(favorite::Column::Id.eq(self.id)) .one(connection) .await? .context("favorite not found")? diff --git a/crates/bili_sync/src/adapter/submission.rs b/crates/bili_sync/src/adapter/submission.rs index 4f9906f..c588307 100644 --- a/crates/bili_sync/src/adapter/submission.rs +++ b/crates/bili_sync/src/adapter/submission.rs @@ -1,12 +1,12 @@ use std::path::Path; use std::pin::Pin; -use anyhow::{Context, Result}; +use anyhow::{Context, Result, ensure}; use bili_sync_entity::*; use futures::Stream; use sea_orm::ActiveValue::Set; use sea_orm::entity::prelude::*; -use sea_orm::sea_query::{OnConflict, SimpleExpr}; +use sea_orm::sea_query::SimpleExpr; use sea_orm::{DatabaseConnection, Unchanged}; use crate::adapter::{_ActiveModel, VideoSource, VideoSourceEnum}; @@ -71,21 +71,22 @@ impl VideoSource for submission::Model { )> { let submission = Submission::new(bili_client, self.upper_id.to_string()); let upper = submission.get_info().await?; - submission::Entity::insert(submission::ActiveModel { - upper_id: Set(upper.mid.parse()?), + ensure!( + upper.mid == submission.upper_id, + "submission upper id mismatch: {} != {}", + upper.mid, + submission.upper_id + ); + submission::ActiveModel { + id: Unchanged(self.id), upper_name: Set(upper.name), ..Default::default() - }) - .on_conflict( - OnConflict::column(submission::Column::UpperId) - .update_column(submission::Column::UpperName) - .to_owned(), - ) - .exec(connection) + } + .save(connection) .await?; Ok(( submission::Entity::find() - .filter(submission::Column::UpperId.eq(upper.mid)) + .filter(submission::Column::Id.eq(self.id)) .one(connection) .await? .context("submission not found")? diff --git a/crates/bili_sync/src/bilibili/collection.rs b/crates/bili_sync/src/bilibili/collection.rs index 10cb06e..b8e6c93 100644 --- a/crates/bili_sync/src/bilibili/collection.rs +++ b/crates/bili_sync/src/bilibili/collection.rs @@ -55,7 +55,7 @@ pub struct CollectionItem { pub struct Collection<'a> { client: &'a BiliClient, - collection: CollectionItem, + pub collection: CollectionItem, } #[derive(Debug, PartialEq)] diff --git a/crates/bili_sync/src/bilibili/submission.rs b/crates/bili_sync/src/bilibili/submission.rs index e01fd3a..d3c5ff7 100644 --- a/crates/bili_sync/src/bilibili/submission.rs +++ b/crates/bili_sync/src/bilibili/submission.rs @@ -9,7 +9,7 @@ use crate::bilibili::favorite_list::Upper; use crate::bilibili::{BiliClient, MIXIN_KEY, Validate, VideoInfo}; pub struct Submission<'a> { client: &'a BiliClient, - upper_id: String, + pub upper_id: String, } impl<'a> Submission<'a> { diff --git a/crates/bili_sync/src/task/http_server.rs b/crates/bili_sync/src/task/http_server.rs index efe231a..8f92114 100644 --- a/crates/bili_sync/src/task/http_server.rs +++ b/crates/bili_sync/src/task/http_server.rs @@ -7,16 +7,14 @@ use axum::response::IntoResponse; use axum::routing::get; use axum::{Extension, ServiceExt}; use reqwest::StatusCode; -use rust_embed_for_web::{EmbedableFile, RustEmbed}; +use rust_embed::Embed; use sea_orm::DatabaseConnection; use crate::api::{MpscWriter, router}; use crate::bilibili::BiliClient; use crate::config::VersionedConfig; -#[derive(RustEmbed)] -#[preserve_source = false] -#[gzip = false] +#[derive(Embed)] #[folder = "../../web/build"] struct Asset; @@ -46,21 +44,6 @@ async fn frontend_files(uri: Uri) -> impl IntoResponse { let Some(content) = Asset::get(path) else { return (StatusCode::NOT_FOUND, "404 Not Found").into_response(); }; - let mime_type = content.mime_type(); - let content_type = mime_type.as_deref().unwrap_or("application/octet-stream"); - if cfg!(debug_assertions) { - ( - [(header::CONTENT_TYPE, content_type)], - // safety: `RustEmbed` returns uncompressed files directly from the filesystem in debug mode - content.data().unwrap(), - ) - .into_response() - } else { - ( - [(header::CONTENT_TYPE, content_type), (header::CONTENT_ENCODING, "br")], - // safety: `RustEmbed` will always generate br-compressed files if the feature is enabled - content.data_br().unwrap(), - ) - .into_response() - } + let mime = mime_guess::from_path(path).first_or_octet_stream(); + ([(header::CONTENT_TYPE, mime.as_ref())], content.data).into_response() }