Files
bili-sync-ai/src/bilibili/client.rs
idlercloud 4ba23ce8fc refactor: 用更 idiomatic 的方式改写一些代码 (#54)
* refactor: Config 采用 arc_swap 而非锁

* refactor: 改进 config 的检查,及其他一些细微优化

* refactor: 不再拆分 lib.rs 和 main.rs
2024-04-04 18:39:41 +08:00

86 lines
2.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use std::sync::Arc;
use anyhow::Result;
use reqwest::{header, Method};
use crate::bilibili::Credential;
use crate::config::CONFIG;
// 一个对 reqwest::Client 的简单封装,用于 Bilibili 请求
pub struct Client(reqwest::Client);
impl Client {
pub fn new() -> Self {
// 正常访问 api 所必须的 header作为默认 header 添加到每个请求中
let mut headers = header::HeaderMap::new();
headers.insert(
header::USER_AGENT,
header::HeaderValue::from_static(
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
),
);
headers.insert(
header::REFERER,
header::HeaderValue::from_static("https://www.bilibili.com"),
);
Self(
reqwest::Client::builder()
.default_headers(headers)
.gzip(true)
.build()
.unwrap(),
)
}
// a wrapper of reqwest::Client::request to add credential to the request
pub fn request(&self, method: Method, url: &str, credential: Option<&Credential>) -> reqwest::RequestBuilder {
let mut req = self.0.request(method, url);
// 如果有 credential会将其转换成 cookie 添加到请求的 header 中
if let Some(credential) = credential {
req = req
.header(header::COOKIE, format!("SESSDATA={}", credential.sessdata))
.header(header::COOKIE, format!("bili_jct={}", credential.bili_jct))
.header(header::COOKIE, format!("buvid3={}", credential.buvid3))
.header(header::COOKIE, format!("DedeUserID={}", credential.dedeuserid))
.header(header::COOKIE, format!("ac_time_value={}", credential.ac_time_value));
}
req
}
}
// clippy 建议实现 Default trait
impl Default for Client {
fn default() -> Self {
Self::new()
}
}
pub struct BiliClient {
client: Client,
}
impl BiliClient {
pub fn new() -> Self {
let client = Client::new();
Self { client }
}
pub fn request(&self, method: Method, url: &str) -> reqwest::RequestBuilder {
let credential = CONFIG.credential.load();
self.client.request(method, url, credential.as_deref())
}
pub async fn check_refresh(&self) -> Result<()> {
let credential = CONFIG.credential.load();
let Some(credential) = credential.as_deref() else {
return Ok(());
};
if !credential.need_refresh(&self.client).await? {
return Ok(());
}
let new_credential = credential.refresh(&self.client).await?;
CONFIG.credential.store(Some(Arc::new(new_credential)));
CONFIG.save()
}
}