mirror of
https://github.com/amtoaer/bili-sync.git
synced 2026-05-08 01:02:49 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7978e20da | ||
|
|
6e4af47bda | ||
|
|
791e4997a0 | ||
|
|
05ab83fc93 | ||
|
|
18ed9e09b1 |
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -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",
|
||||
|
||||
@@ -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 驱动的哔哩哔哩同步工具"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -21,7 +21,7 @@ export default defineConfig({
|
||||
nav: [
|
||||
{ text: "主页", link: "/" },
|
||||
{
|
||||
text: "v2.6.0",
|
||||
text: "v2.6.2",
|
||||
items: [
|
||||
{
|
||||
text: "程序更新",
|
||||
|
||||
@@ -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 站认证
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# bili-sync 是什么?
|
||||
|
||||
> [!TIP]
|
||||
> 当前最新程序版本为 v2.6.0,文档将始终与最新程序版本保持一致。
|
||||
> 当前最新程序版本为 v2.6.2,文档将始终与最新程序版本保持一致。
|
||||
|
||||
bili-sync 是一款专为 NAS 用户编写的哔哩哔哩同步工具。
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user