chore: 全盘使用 anyhow::Result
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use log::error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
pub struct PageAnalyzer {
|
||||
info: serde_json::Value,
|
||||
}
|
||||
@@ -161,14 +160,14 @@ impl PageAnalyzer {
|
||||
.as_array()
|
||||
.ok_or_else(|| -> Result<serde_json::Value> {
|
||||
error!("video data is not an array: {:?}", self.info);
|
||||
Err("invalid video data".into())
|
||||
Err(anyhow!("invalid video data"))
|
||||
})
|
||||
.unwrap_or(&Vec::new())
|
||||
.iter()
|
||||
{
|
||||
let video_stream_url = video_data["baseUrl"].as_str().unwrap().to_string();
|
||||
let video_stream_quality = VideoQuality::from_repr(video_data["id"].as_u64().unwrap() as usize)
|
||||
.ok_or("invalid video stream quality")?;
|
||||
.ok_or(anyhow!("invalid video stream quality"))?;
|
||||
if (video_stream_quality == VideoQuality::QualityHdr && filter_option.no_hdr)
|
||||
|| (video_stream_quality == VideoQuality::QualityDolby && filter_option.no_dolby_video)
|
||||
|| (video_stream_quality != VideoQuality::QualityDolby
|
||||
@@ -306,7 +305,7 @@ impl PageAnalyzer {
|
||||
_ => unreachable!(),
|
||||
});
|
||||
if video_streams.is_empty() {
|
||||
return Err("no stream found".into());
|
||||
bail!("no video stream found");
|
||||
}
|
||||
Ok(BestStream::VideoAudio {
|
||||
video: video_streams.remove(video_streams.len() - 1),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use anyhow::Result;
|
||||
use reqwest::{header, Method};
|
||||
|
||||
use crate::bilibili::Credential;
|
||||
use crate::config::CONFIG;
|
||||
use crate::Result;
|
||||
|
||||
// 一个对 reqwest::Client 的简单封装,用于 Bilibili 请求
|
||||
pub struct Client(reqwest::Client);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use cookie::Cookie;
|
||||
use regex::Regex;
|
||||
use reqwest::{header, Method};
|
||||
@@ -9,7 +10,6 @@ use rsa::{Oaep, RsaPublicKey};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::bilibili::Client;
|
||||
use crate::Result;
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Credential {
|
||||
@@ -43,7 +43,7 @@ impl Credential {
|
||||
.await?
|
||||
.json::<serde_json::Value>()
|
||||
.await?;
|
||||
res["data"]["refresh"].as_bool().ok_or("check refresh failed".into())
|
||||
res["data"]["refresh"].as_bool().ok_or(anyhow!("check refresh failed"))
|
||||
}
|
||||
|
||||
pub async fn refresh(&mut self, client: &Client) -> Result<()> {
|
||||
@@ -85,8 +85,8 @@ JNrRuoEUXpabUzGB8QIDAQAB
|
||||
.await?;
|
||||
if !res.status().is_success() {
|
||||
return match res.status().as_u16() {
|
||||
404 => Err("correspond path is wrong or expired".into()),
|
||||
_ => Err("get csrf failed".into()),
|
||||
404 => Err(anyhow!("correspond path is wrong or expired")),
|
||||
_ => Err(anyhow!("get csrf failed")),
|
||||
};
|
||||
}
|
||||
regex_find(r#"<div id="1-name">(.+?)</div>"#, res.text().await?.as_str())
|
||||
@@ -122,7 +122,7 @@ JNrRuoEUXpabUzGB8QIDAQAB
|
||||
.filter(|x| required_cookies.contains(x.name()))
|
||||
.collect();
|
||||
if cookies.len() != required_cookies.len() {
|
||||
return Err("not all required cookies found".into());
|
||||
bail!("not all required cookies found");
|
||||
}
|
||||
for cookie in cookies {
|
||||
match cookie.name() {
|
||||
@@ -134,7 +134,7 @@ JNrRuoEUXpabUzGB8QIDAQAB
|
||||
}
|
||||
let json = res.json::<serde_json::Value>().await?;
|
||||
if !json["data"]["refresh_token"].is_string() {
|
||||
return Err("refresh_token not found".into());
|
||||
bail!("refresh_token not found");
|
||||
}
|
||||
credential.ac_time_value = json["data"]["refresh_token"].as_str().unwrap().to_string();
|
||||
Ok(credential)
|
||||
@@ -157,7 +157,7 @@ JNrRuoEUXpabUzGB8QIDAQAB
|
||||
.json::<serde_json::Value>()
|
||||
.await?;
|
||||
if res["code"] != 0 {
|
||||
return Err(format!("confirm refresh failed: {}", res["message"]).into());
|
||||
bail!("confirm refresh failed: {}", res["message"]);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -168,7 +168,7 @@ fn regex_find(pattern: &str, doc: &str) -> Result<String> {
|
||||
let re = Regex::new(pattern)?;
|
||||
Ok(re
|
||||
.captures(doc)
|
||||
.ok_or("pattern not match")?
|
||||
.ok_or(anyhow!("pattern not match"))?
|
||||
.get(1)
|
||||
.unwrap()
|
||||
.as_str()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use anyhow::{bail, Result};
|
||||
use async_stream::stream;
|
||||
use chrono::serde::ts_seconds;
|
||||
use chrono::{DateTime, Utc};
|
||||
@@ -5,7 +6,6 @@ use futures_core::stream::Stream;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::bilibili::BiliClient;
|
||||
use crate::Result;
|
||||
pub struct FavoriteList<'a> {
|
||||
client: &'a BiliClient,
|
||||
fid: String,
|
||||
@@ -75,7 +75,7 @@ impl<'a> FavoriteList<'a> {
|
||||
.json::<serde_json::Value>()
|
||||
.await?;
|
||||
if res["code"] != 0 {
|
||||
return Err(format!("get favorite videos failed: {}", res["message"]).into());
|
||||
bail!("get favorite videos failed: {}", res["message"]);
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use anyhow::{bail, Result};
|
||||
use reqwest::Method;
|
||||
|
||||
use crate::bilibili::analyzer::PageAnalyzer;
|
||||
use crate::bilibili::client::BiliClient;
|
||||
use crate::Result;
|
||||
|
||||
static MASK_CODE: u64 = 2251799813685247;
|
||||
static XOR_CODE: u64 = 23442827791579;
|
||||
@@ -89,7 +89,7 @@ impl<'a> Video<'a> {
|
||||
.json::<serde_json::Value>()
|
||||
.await?;
|
||||
if res["code"] != 0 {
|
||||
return Err(format!("get page analyzer failed: {}", res["message"]).into());
|
||||
bail!("get page analyzer failed: {}", res["message"]);
|
||||
}
|
||||
Ok(PageAnalyzer::new(res["data"].take()))
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@ use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use log::warn;
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::bilibili::{Credential, FilterOption};
|
||||
use crate::Result;
|
||||
|
||||
pub static CONFIG: Lazy<Mutex<Config>> = Lazy::new(|| {
|
||||
let config = Config::new();
|
||||
@@ -75,7 +75,7 @@ impl Config {
|
||||
|
||||
fn load() -> Result<Self> {
|
||||
let config_path = dirs::config_dir()
|
||||
.ok_or("No config path found")?
|
||||
.ok_or(anyhow!("No config path found"))?
|
||||
.join("bili-sync")
|
||||
.join("config.toml");
|
||||
let config_content = std::fs::read_to_string(config_path)?;
|
||||
@@ -84,7 +84,7 @@ impl Config {
|
||||
|
||||
pub fn save(&self) -> Result<()> {
|
||||
let config_path = dirs::config_dir()
|
||||
.ok_or("No config path found")?
|
||||
.ok_or(anyhow!("No config path found"))?
|
||||
.join("bili-sync")
|
||||
.join("config.toml");
|
||||
if let Some(parent) = config_path.parent() {
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::pin::Pin;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use dirs::config_dir;
|
||||
use entity::{favorite, page, video};
|
||||
use filenamify::filenamify;
|
||||
@@ -21,7 +22,6 @@ use super::utils::{unhandled_videos_pages, ModelWrapper, NFOMode, NFOSerializer,
|
||||
use crate::bilibili::{BestStream, BiliClient, FavoriteList, FilterOption, PageInfo, Video};
|
||||
use crate::core::utils::{create_video_pages, create_videos, exist_labels, filter_videos, handle_favorite_info};
|
||||
use crate::downloader::Downloader;
|
||||
use crate::Result;
|
||||
|
||||
/// 处理某个收藏夹,首先刷新收藏夹信息,然后下载收藏夹中未下载成功的视频
|
||||
pub async fn process_favorite(
|
||||
@@ -234,7 +234,7 @@ pub async fn dispatch_download_page(
|
||||
&video_model.bvid, page_model.pid, &page_status
|
||||
);
|
||||
if final_result.is_ok() && page_status.should_run().iter().any(|x| *x) {
|
||||
final_result = Err("Some page item download failed".into());
|
||||
final_result = Err(anyhow!("Some page item download failed"));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use core::fmt;
|
||||
|
||||
use crate::Result;
|
||||
use anyhow::Result;
|
||||
|
||||
static STATUS_MAX_RETRY: u32 = 0b100;
|
||||
static STATUS_OK: u32 = 0b111;
|
||||
@@ -203,6 +203,8 @@ impl From<PageStatus> for u32 {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use anyhow::anyhow;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
@@ -210,11 +212,11 @@ mod test {
|
||||
let mut status = Status::new(0);
|
||||
assert_eq!(status.should_run(3), vec![true, true, true]);
|
||||
for count in 1..=3 {
|
||||
status.update_status(&[Err("".into()), Ok(()), Ok(())]);
|
||||
status.update_status(&[Err(anyhow!("")), Ok(()), Ok(())]);
|
||||
assert_eq!(status.should_run(3), vec![true, false, false]);
|
||||
assert_eq!(u32::from(status.clone()), 0b111_111_000 + count);
|
||||
}
|
||||
status.update_status(&[Err("".into()), Ok(()), Ok(())]);
|
||||
status.update_status(&[Err(anyhow!("")), Ok(()), Ok(())]);
|
||||
assert_eq!(status.should_run(3), vec![false, false, false]);
|
||||
assert_eq!(u32::from(status), 0b111_111_100 | Status::handled());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::collections::HashSet;
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use entity::*;
|
||||
use filenamify::filenamify;
|
||||
use migration::OnConflict;
|
||||
@@ -17,7 +18,6 @@ use tokio::io::AsyncWriteExt;
|
||||
use super::status::Status;
|
||||
use crate::bilibili::{FavoriteListInfo, PageInfo, VideoInfo};
|
||||
use crate::config::CONFIG;
|
||||
use crate::Result;
|
||||
|
||||
pub static TEMPLATE: Lazy<handlebars::Handlebars> = Lazy::new(|| {
|
||||
let mut handlebars = handlebars::Handlebars::new();
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use migration::{Migrator, MigratorTrait};
|
||||
use sea_orm::{Database, DatabaseConnection};
|
||||
use tokio::fs;
|
||||
|
||||
use crate::Result;
|
||||
pub async fn database_connection() -> Result<DatabaseConnection> {
|
||||
let config_dir = dirs::config_dir().ok_or("No config path found")?;
|
||||
let config_dir = dirs::config_dir().ok_or(anyhow!("No config path found"))?;
|
||||
let target = config_dir.join("bili-sync").join("data.sqlite");
|
||||
if let Some(parent) = target.parent() {
|
||||
fs::create_dir_all(parent).await?;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use futures_util::StreamExt;
|
||||
use reqwest::Method;
|
||||
use tokio::fs::{self, File};
|
||||
use tokio::io;
|
||||
|
||||
use crate::bilibili::Client;
|
||||
use crate::Result;
|
||||
pub struct Downloader {
|
||||
client: Client,
|
||||
}
|
||||
@@ -46,8 +46,8 @@ impl Downloader {
|
||||
.await?;
|
||||
if !output.status.success() {
|
||||
return match String::from_utf8(output.stderr) {
|
||||
Ok(err) => Err(err.into()),
|
||||
_ => Err("ffmpeg error".into()),
|
||||
Ok(err) => Err(anyhow!(err)),
|
||||
_ => Err(anyhow!("ffmpeg error")),
|
||||
};
|
||||
}
|
||||
let _ = fs::remove_file(video_path).await;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
use std::error;
|
||||
|
||||
pub mod bilibili;
|
||||
pub mod config;
|
||||
pub mod core;
|
||||
pub mod database;
|
||||
pub mod downloader;
|
||||
|
||||
type Result<T> = std::result::Result<T, Box<dyn error::Error>>;
|
||||
|
||||
Reference in New Issue
Block a user