feat: 每次执行前检查登录状态,避免凭据失效导致的非预期行为 (#112)

* feat: 每次执行前检查登录状态,避免凭据失效导致的非预期行为

* refactor: 减少代码长度
This commit is contained in:
ᴀᴍᴛᴏᴀᴇʀ
2024-06-01 01:46:15 +08:00
committed by GitHub
parent 8fee6fb97a
commit 73f97f937f
3 changed files with 38 additions and 3 deletions
+10 -1
View File
@@ -1,6 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use anyhow::Result; use anyhow::{bail, Result};
use reqwest::{header, Method}; use reqwest::{header, Method};
use crate::bilibili::Credential; use crate::bilibili::Credential;
@@ -85,4 +85,13 @@ impl BiliClient {
CONFIG.credential.store(Some(Arc::new(new_credential))); CONFIG.credential.store(Some(Arc::new(new_credential)));
CONFIG.save() CONFIG.save()
} }
/// 检查凭据是否已设置且有效
pub async fn is_login(&self) -> Result<()> {
let credential = CONFIG.credential.load();
let Some(credential) = credential.as_deref() else {
bail!("no credential found");
};
credential.is_login(&self.client).await
}
} }
+18
View File
@@ -38,6 +38,24 @@ impl Credential {
res["data"]["refresh"].as_bool().ok_or(anyhow!("check refresh failed")) res["data"]["refresh"].as_bool().ok_or(anyhow!("check refresh failed"))
} }
/// 需要使用一个需要鉴权的接口来检查是否登录
/// 此处使用查看用户状态数的接口,该接口返回内容少,请求成本低
pub async fn is_login(&self, client: &Client) -> Result<()> {
client
.request(
Method::GET,
"https://api.bilibili.com/x/web-interface/nav/stat",
Some(self),
)
.send()
.await?
.error_for_status()?
.json::<serde_json::Value>()
.await?
.validate()?;
Ok(())
}
pub async fn refresh(&self, client: &Client) -> Result<Self> { pub async fn refresh(&self, client: &Client) -> Result<Self> {
let correspond_path = Self::get_correspond_path(); let correspond_path = Self::get_correspond_path();
let csrf = self.get_refresh_csrf(client, correspond_path).await?; let csrf = self.get_refresh_csrf(client, correspond_path).await?;
+10 -2
View File
@@ -8,7 +8,10 @@ mod database;
mod downloader; mod downloader;
mod error; mod error;
use std::time::Duration;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use tokio::time;
use tracing_subscriber::util::SubscriberInitExt; use tracing_subscriber::util::SubscriberInitExt;
use crate::bilibili::BiliClient; use crate::bilibili::BiliClient;
@@ -34,10 +37,15 @@ async fn main() -> ! {
let connection = database_connection().await.unwrap(); let connection = database_connection().await.unwrap();
migrate_database(&connection).await.unwrap(); migrate_database(&connection).await.unwrap();
loop { loop {
if let Err(e) = bili_client.is_login().await {
error!("检查登录状态时遇到错误:{e},等待下一轮执行");
time::sleep(Duration::from_secs(CONFIG.interval)).await;
continue;
}
if anchor != chrono::Local::now().date_naive() { if anchor != chrono::Local::now().date_naive() {
if let Err(e) = bili_client.check_refresh().await { if let Err(e) = bili_client.check_refresh().await {
error!("检查刷新 Credential 遇到错误:{e},等待下一轮执行"); error!("检查刷新 Credential 遇到错误:{e},等待下一轮执行");
tokio::time::sleep(std::time::Duration::from_secs(CONFIG.interval)).await; time::sleep(Duration::from_secs(CONFIG.interval)).await;
continue; continue;
} }
anchor = chrono::Local::now().date_naive(); anchor = chrono::Local::now().date_naive();
@@ -49,6 +57,6 @@ async fn main() -> ! {
} }
} }
info!("所有收藏夹处理完毕,等待下一轮执行"); info!("所有收藏夹处理完毕,等待下一轮执行");
tokio::time::sleep(std::time::Duration::from_secs(CONFIG.interval)).await; time::sleep(Duration::from_secs(CONFIG.interval)).await;
} }
} }