Compare commits

...

5 Commits

Author SHA1 Message Date
amtoaer
c7978e20da chore: 发布 bili-sync 2.6.2 2025-07-23 22:48:30 +08:00
ᴀᴍᴛᴏᴀᴇʀ
6e4af47bda fix: 修复 collection_type 反序列化错误 (#403) 2025-07-23 22:46:39 +08:00
ᴀᴍᴛᴏᴀᴇʀ
791e4997a0 docs: 修复配置项描述 (#396) 2025-07-13 16:59:06 +08:00
amtoaer
05ab83fc93 chore: 发布 bili-sync 2.6.1 2025-07-13 00:29:52 +08:00
ᴀᴍᴛᴏᴀᴇʀ
18ed9e09b1 fix: 修复 chromium 系浏览器创建 WebSocket 失败的问题 (#395) 2025-07-13 00:28:24 +08:00
9 changed files with 58 additions and 25 deletions

6
Cargo.lock generated
View File

@@ -475,7 +475,7 @@ dependencies = [
[[package]]
name = "bili_sync"
version = "2.6.0"
version = "2.6.2"
dependencies = [
"anyhow",
"arc-swap",
@@ -530,7 +530,7 @@ dependencies = [
[[package]]
name = "bili_sync_entity"
version = "2.6.0"
version = "2.6.2"
dependencies = [
"sea-orm",
"serde_json",
@@ -538,7 +538,7 @@ dependencies = [
[[package]]
name = "bili_sync_migration"
version = "2.6.0"
version = "2.6.2"
dependencies = [
"async-std",
"sea-orm-migration",

View File

@@ -4,7 +4,7 @@ default-members = ["crates/bili_sync"]
resolver = "2"
[workspace.package]
version = "2.6.0"
version = "2.6.2"
authors = ["amtoaer <amtoaer@gmail.com>"]
license = "MIT"
description = "由 Rust & Tokio 驱动的哔哩哔哩同步工具"

View File

@@ -16,7 +16,7 @@ use crate::bilibili::{BiliClient, Collection, CollectionItem, CollectionType, Vi
impl VideoSource for collection::Model {
fn display_name(&self) -> Cow<'static, str> {
format!("{}{}", CollectionType::from(self.r#type), self.name).into()
format!("{}{}", CollectionType::from_expected(self.r#type), self.name).into()
}
fn filter_expr(&self) -> SimpleExpr {
@@ -76,14 +76,14 @@ impl VideoSource for collection::Model {
CollectionItem {
sid: self.s_id.to_string(),
mid: self.m_id.to_string(),
collection_type: CollectionType::from(self.r#type),
collection_type: CollectionType::from_expected(self.r#type),
},
);
let collection_info = collection.get_info().await?;
ensure!(
collection_info.sid == self.s_id
&& collection_info.mid == self.m_id
&& collection_info.collection_type == CollectionType::from(self.r#type),
&& collection_info.collection_type == CollectionType::from_expected(self.r#type),
"collection info mismatch: {:?} != {:?}",
collection_info,
collection.collection

View File

@@ -39,22 +39,29 @@ pub fn router() -> Router {
)
}
/// 中间件:验证请求头中的 Authorization 是否与配置中的 auth_token 匹配
pub async fn auth(headers: HeaderMap, request: Request, next: Next) -> Result<Response, StatusCode> {
/// 中间件:使用 auth token 对请求进行身份验证
pub async fn auth(mut headers: HeaderMap, request: Request, next: Next) -> Result<Response, StatusCode> {
let config = VersionedConfig::get().load();
let token = config.auth_token.as_str();
if headers
.get("Authorization")
.and_then(|v| v.to_str().ok())
.is_some_and(|s| s == token)
|| headers
.get("Sec-WebSocket-Protocol")
.and_then(|v| v.to_str().ok())
.and_then(|s| BASE64_URL_SAFE_NO_PAD.decode(s).ok())
.is_some_and(|s| s == token.as_bytes())
{
return Ok(next.run(request).await);
}
if let Some(protocol) = headers.remove("Sec-WebSocket-Protocol") {
if protocol
.to_str()
.ok()
.and_then(|s| BASE64_URL_SAFE_NO_PAD.decode(s).ok())
.is_some_and(|s| s == token.as_bytes())
{
let mut resp = next.run(request).await;
resp.headers_mut().insert("Sec-WebSocket-Protocol", protocol);
return Ok(resp);
}
}
Ok(ApiResponse::<()>::unauthorized("auth token does not match").into_response())
}

View File

@@ -10,13 +10,23 @@ use serde_json::Value;
use crate::bilibili::credential::encoded_query;
use crate::bilibili::{BiliClient, MIXIN_KEY, Validate, VideoInfo};
#[derive(PartialEq, Eq, Hash, Clone, Debug, Deserialize, Default, Copy)]
#[derive(PartialEq, Eq, Hash, Clone, Debug, Default, Copy)]
pub enum CollectionType {
Series,
#[default]
Season,
}
impl<'de> serde::Deserialize<'de> for CollectionType {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let v = i32::deserialize(deserializer)?;
CollectionType::try_from(v).map_err(serde::de::Error::custom)
}
}
impl From<CollectionType> for i32 {
fn from(v: CollectionType) -> Self {
match v {
@@ -26,16 +36,24 @@ impl From<CollectionType> for i32 {
}
}
impl From<i32> for CollectionType {
fn from(v: i32) -> Self {
impl TryFrom<i32> for CollectionType {
type Error = anyhow::Error;
fn try_from(v: i32) -> Result<Self, Self::Error> {
match v {
1 => CollectionType::Series,
2 => CollectionType::Season,
_ => panic!("invalid collection type"),
1 => Ok(CollectionType::Series),
2 => Ok(CollectionType::Season),
v => Err(anyhow!("got invalid collection type {}", v)),
}
}
}
impl CollectionType {
pub fn from_expected(v: i32) -> Self {
Self::try_from(v).expect("invalid collection type")
}
}
impl Display for CollectionType {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let s = match self {

View File

@@ -21,7 +21,7 @@ export default defineConfig({
nav: [
{ text: "主页", link: "/" },
{
text: "v2.6.0",
text: "v2.6.2",
items: [
{
text: "程序更新",

View File

@@ -73,10 +73,18 @@ UP 主头像和信息的保存位置。对于使用 Emby、Jellyfin 媒体服务
在修改该 Token 后需要对应修改前端保存的 Token才能正常访问管理页面。
### 启动 CDN 排序
表示程序每次执行扫描下载的间隔时间,单位为秒
一般情况下b 站会为视频、音频流提供一个 baseUrl 与多个 backupUrl程序默认会按照 baseUrl -> backupUrl 的顺序请求,依次尝试下载
如果启用 CDN 排序,那么程序不再使用默认顺序,而是将所有 url 放到一起统一排序来决定请求顺序。排序优先级从高到低为:
1. 服务商 CDN`upos-sz-mirrorxxxx.bilivideo.com`
2. 自建 CDN`cn-xxxx-dx-v-xxxx.bilivideo.com`
3. MCDN`xxxx.mcdn.bilivideo.com`
4. PCDN`xxxx.v1d.szbdyd.com`
这会让程序优先请求质量更高的 CDN可能会提高下载速度并增加成功率但效果因地区、网络环境而异。
## B 站认证

View File

@@ -1,7 +1,7 @@
# bili-sync 是什么?
> [!TIP]
> 当前最新程序版本为 v2.6.0,文档将始终与最新程序版本保持一致。
> 当前最新程序版本为 v2.6.2,文档将始终与最新程序版本保持一致。
bili-sync 是一款专为 NAS 用户编写的哔哩哔哩同步工具。

View File

@@ -1,6 +1,6 @@
{
"name": "bili-sync-web",
"version": "2.6.0",
"version": "2.6.2",
"devDependencies": {
"@eslint/compat": "^1.2.5",
"@eslint/js": "^9.18.0",