refactor: 用更 idiomatic 的方式改写一些代码 (#54)
* refactor: Config 采用 arc_swap 而非锁 * refactor: 改进 config 的检查,及其他一些细微优化 * refactor: 不再拆分 lib.rs 和 main.rs
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use reqwest::{header, Method};
|
||||
|
||||
@@ -54,31 +56,30 @@ impl Default for Client {
|
||||
}
|
||||
|
||||
pub struct BiliClient {
|
||||
credential: Option<Credential>,
|
||||
client: Client,
|
||||
}
|
||||
|
||||
impl BiliClient {
|
||||
pub fn new(credential: Option<Credential>) -> Self {
|
||||
pub fn new() -> Self {
|
||||
let client = Client::new();
|
||||
Self { credential, client }
|
||||
Self { client }
|
||||
}
|
||||
|
||||
pub fn request(&self, method: Method, url: &str) -> reqwest::RequestBuilder {
|
||||
self.client.request(method, url, self.credential.as_ref())
|
||||
let credential = CONFIG.credential.load();
|
||||
self.client.request(method, url, credential.as_deref())
|
||||
}
|
||||
|
||||
pub async fn check_refresh(&mut self) -> Result<()> {
|
||||
let Some(credential) = self.credential.as_mut() else {
|
||||
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(());
|
||||
}
|
||||
credential.refresh(&self.client).await?;
|
||||
|
||||
let mut config = CONFIG.lock().unwrap();
|
||||
config.credential = Some(credential.clone());
|
||||
config.save()
|
||||
let new_credential = credential.refresh(&self.client).await?;
|
||||
CONFIG.credential.store(Some(Arc::new(new_credential)));
|
||||
CONFIG.save()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
|
||||
use super::error::BiliError;
|
||||
use crate::bilibili::Client;
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Credential {
|
||||
pub sessdata: String,
|
||||
pub bili_jct: String,
|
||||
@@ -32,6 +32,16 @@ impl Credential {
|
||||
}
|
||||
}
|
||||
|
||||
const fn empty() -> Self {
|
||||
Self {
|
||||
sessdata: String::new(),
|
||||
bili_jct: String::new(),
|
||||
buvid3: String::new(),
|
||||
dedeuserid: String::new(),
|
||||
ac_time_value: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查凭据是否有效
|
||||
pub async fn need_refresh(&self, client: &Client) -> Result<bool> {
|
||||
let res = client
|
||||
@@ -55,13 +65,12 @@ impl Credential {
|
||||
res["data"]["refresh"].as_bool().ok_or(anyhow!("check refresh failed"))
|
||||
}
|
||||
|
||||
pub async fn refresh(&mut self, client: &Client) -> Result<()> {
|
||||
pub async fn refresh(&self, client: &Client) -> Result<Self> {
|
||||
let correspond_path = Self::get_correspond_path();
|
||||
let csrf = self.get_refresh_csrf(client, correspond_path).await?;
|
||||
let new_credential = self.get_new_credential(client, &csrf).await?;
|
||||
self.confirm_refresh(client, &new_credential).await?;
|
||||
*self = new_credential;
|
||||
Ok(())
|
||||
Ok(new_credential)
|
||||
}
|
||||
|
||||
fn get_correspond_path() -> String {
|
||||
@@ -125,9 +134,9 @@ JNrRuoEUXpabUzGB8QIDAQAB
|
||||
bail!(BiliError::RequestFailed(code, msg.to_owned()));
|
||||
}
|
||||
let set_cookies = headers.get_all(header::SET_COOKIE);
|
||||
let mut credential = Credential {
|
||||
let mut credential = Self {
|
||||
buvid3: self.buvid3.clone(),
|
||||
..Default::default()
|
||||
..Self::empty()
|
||||
};
|
||||
let required_cookies = HashSet::from(["SESSDATA", "bili_jct", "DedeUserID"]);
|
||||
let cookies: Vec<Cookie> = set_cookies
|
||||
|
||||
@@ -3,7 +3,6 @@ use async_stream::stream;
|
||||
use chrono::serde::ts_seconds;
|
||||
use chrono::{DateTime, Utc};
|
||||
use futures::Stream;
|
||||
use log::error;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::bilibili::error::BiliError;
|
||||
|
||||
Reference in New Issue
Block a user