refactor: 继续调整优化部分代码,移除主体代码的所有 unwrap

This commit is contained in:
amtoaer
2025-01-21 17:17:14 +08:00
parent cdc30e1b32
commit 0f25923c52
14 changed files with 101 additions and 67 deletions

View File

@@ -2,7 +2,7 @@ use std::collections::HashSet;
use std::path::Path;
use std::pin::Pin;
use anyhow::Result;
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use bili_sync_entity::*;
use futures::Stream;
@@ -90,7 +90,7 @@ impl VideoListModel for collection::Model {
// 将页标记和 tag 写入数据库
let mut video_active_model = self.video_model_by_info(&view_info, Some(video_model));
video_active_model.single_page = Set(Some(pages.len() == 1));
video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap()));
video_active_model.tags = Set(Some(serde_json::to_value(tags)?));
video_active_model.save(&txn).await?;
txn.commit().await?;
}
@@ -196,7 +196,7 @@ pub(super) async fn collection_from<'a>(
)
.one(connection)
.await?
.unwrap(),
.ok_or(anyhow!("collection not found"))?,
),
Box::pin(collection.into_simple_video_stream()),
))

View File

@@ -2,7 +2,7 @@ use std::collections::HashSet;
use std::path::Path;
use std::pin::Pin;
use anyhow::Result;
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use bili_sync_entity::*;
use futures::Stream;
@@ -87,7 +87,7 @@ impl VideoListModel for favorite::Model {
// 将页标记和 tag 写入数据库
let mut video_active_model: video::ActiveModel = video_model.into();
video_active_model.single_page = Set(Some(pages_info.len() == 1));
video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap()));
video_active_model.tags = Set(Some(serde_json::to_value(tags)?));
video_active_model.save(&txn).await?;
txn.commit().await?;
}
@@ -153,7 +153,7 @@ pub(super) async fn favorite_from<'a>(
.filter(favorite::Column::FId.eq(favorite_info.id))
.one(connection)
.await?
.unwrap(),
.ok_or(anyhow!("favorite not found"))?,
),
Box::pin(favorite.into_video_stream()),
))

View File

@@ -65,7 +65,11 @@ pub(super) fn video_with_path(
) -> video::ActiveModel {
if let Some(fmt_args) = &video_info.to_fmt_args() {
video_model.path = Set(Path::new(base_path)
.join(TEMPLATE.path_safe_render("video", fmt_args).unwrap())
.join(
TEMPLATE
.path_safe_render("video", fmt_args)
.expect("template render failed"),
)
.to_string_lossy()
.to_string());
}

View File

@@ -2,7 +2,7 @@ use std::collections::HashSet;
use std::path::Path;
use std::pin::Pin;
use anyhow::Result;
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use bili_sync_entity::*;
use futures::Stream;
@@ -91,7 +91,7 @@ impl VideoListModel for submission::Model {
// 将页标记和 tag 写入数据库
let mut video_active_model = self.video_model_by_info(&view_info, Some(video_model));
video_active_model.single_page = Set(Some(pages.len() == 1));
video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap()));
video_active_model.tags = Set(Some(serde_json::to_value(tags)?));
video_active_model.save(&txn).await?;
txn.commit().await?;
}
@@ -169,7 +169,7 @@ pub(super) async fn submission_from<'a>(
.filter(submission::Column::UpperId.eq(upper.mid))
.one(connection)
.await?
.unwrap(),
.ok_or(anyhow!("submission not found"))?,
),
Box::pin(submission.into_video_stream()),
))

View File

@@ -2,7 +2,7 @@ use std::collections::HashSet;
use std::path::Path;
use std::pin::Pin;
use anyhow::Result;
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use bili_sync_entity::*;
use futures::Stream;
@@ -88,7 +88,7 @@ impl VideoListModel for watch_later::Model {
// 将页标记和 tag 写入数据库
let mut video_active_model: video::ActiveModel = video_model.into();
video_active_model.single_page = Set(Some(pages_info.len() == 1));
video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap()));
video_active_model.tags = Set(Some(serde_json::to_value(tags)?));
video_active_model.save(&txn).await?;
txn.commit().await?;
}
@@ -151,7 +151,7 @@ pub(super) async fn watch_later_from<'a>(
.filter(watch_later::Column::Id.eq(1))
.one(connection)
.await?
.unwrap(),
.ok_or(anyhow!("watch_later not found"))?,
),
Box::pin(watch_later.into_video_stream()),
))

View File

@@ -7,7 +7,7 @@ pub struct PageAnalyzer {
info: serde_json::Value,
}
#[derive(Debug, strum::FromRepr, PartialEq, PartialOrd, Serialize, Deserialize)]
#[derive(Debug, strum::FromRepr, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum VideoQuality {
Quality360p = 16,
Quality480p = 32,
@@ -21,7 +21,7 @@ pub enum VideoQuality {
Quality8k = 127,
}
#[derive(Debug, Clone, Copy, strum::FromRepr, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, strum::FromRepr, PartialEq, Eq, Serialize, Deserialize)]
pub enum AudioQuality {
Quality64k = 30216,
Quality132k = 30232,
@@ -30,6 +30,18 @@ pub enum AudioQuality {
Quality192k = 30280,
}
impl Ord for AudioQuality {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_sort_key().cmp(&other.as_sort_key())
}
}
impl PartialOrd for AudioQuality {
fn partial_cmp(&self, other: &AudioQuality) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl AudioQuality {
#[inline]
pub fn as_sort_key(&self) -> isize {
@@ -41,12 +53,6 @@ impl AudioQuality {
}
}
impl PartialOrd<AudioQuality> for AudioQuality {
fn partial_cmp(&self, other: &AudioQuality) -> Option<std::cmp::Ordering> {
self.as_sort_key().partial_cmp(&other.as_sort_key())
}
}
#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, strum::EnumString, strum::Display, strum::AsRefStr, PartialEq, PartialOrd, Serialize, Deserialize)]
pub enum VideoCodecs {
@@ -281,7 +287,7 @@ impl PageAnalyzer {
},
) => {
if a_quality != b_quality {
return a_quality.partial_cmp(b_quality).unwrap();
return a_quality.cmp(b_quality);
};
filter_option
.codecs
@@ -294,7 +300,7 @@ impl PageAnalyzer {
.ok_or(anyhow!("no video stream found"))?,
audio: Iterator::max_by(audios.into_iter(), |a, b| match (a, b) {
(Stream::DashAudio { quality: a_quality, .. }, Stream::DashAudio { quality: b_quality, .. }) => {
a_quality.partial_cmp(b_quality).unwrap()
a_quality.cmp(b_quality)
}
_ => unreachable!(),
}),

View File

@@ -34,7 +34,7 @@ impl Client {
.connect_timeout(std::time::Duration::from_secs(10))
.read_timeout(std::time::Duration::from_secs(10))
.build()
.unwrap(),
.expect("failed to build reqwest client"),
)
}

View File

@@ -169,37 +169,49 @@ impl<'a> Collection<'a> {
let mut videos = match self.get_videos(page).await {
Ok(v) => v,
Err(e) => {
error!("failed to get videos of collection {:?} page {}: {}", self.collection, page, e);
error!(
"failed to get videos of collection {:?} page {}: {}",
self.collection, page, e
);
break;
},
}
};
if !videos["data"]["archives"].is_array() {
warn!("no videos found in collection {:?} page {}", self.collection, page);
let archives = &mut videos["data"]["archives"];
if archives.as_array().is_none_or(|v| v.is_empty()) {
error!("no videos found in collection {:?} page {}", self.collection, page);
break;
}
let videos_info = match serde_json::from_value::<Vec<VideoInfo>>(videos["data"]["archives"].take()) {
let videos_info: Vec<VideoInfo> = match serde_json::from_value(archives.take()) {
Ok(v) => v,
Err(e) => {
error!("failed to parse videos of collection {:?} page {}: {}", self.collection, page, e);
error!(
"failed to parse videos of collection {:?} page {}: {}",
self.collection, page, e
);
break;
},
}
};
for video_info in videos_info{
for video_info in videos_info {
yield video_info;
}
let fields = match self.collection.collection_type{
let page_info = &videos["data"]["page"];
let fields = match self.collection.collection_type {
CollectionType::Series => ["num", "size", "total"],
CollectionType::Season => ["page_num", "page_size", "total"],
};
let fields = fields.into_iter().map(|f| videos["data"]["page"][f].as_i64()).collect::<Option<Vec<i64>>>().map(|v| (v[0], v[1], v[2]));
let Some((num, size, total)) = fields else {
error!("failed to get pages of collection {:?} page {}: {:?}", self.collection, page, fields);
break;
};
if num * size >= total {
break;
let values = fields.iter().map(|f| page_info[f].as_i64()).collect::<Vec<Option<i64>>>();
if let [Some(num), Some(size), Some(total)] = values[..] {
if num * size < total {
page += 1;
continue;
}
} else {
error!(
"invalid page info of collection {:?} page {}: read {:?} from {}",
self.collection, page, fields, page_info
);
}
page += 1;
break;
}
}
}

View File

@@ -95,11 +95,13 @@ nzPjfdTcqMz7djHum0qSZA0AyCBDABUqCrfNgCiJ00Ra7GmRj+YCK1NJEuewlb40
JNrRuoEUXpabUzGB8QIDAQAB
-----END PUBLIC KEY-----",
)
.unwrap();
.expect("fail to decode public key");
let ts = chrono::Local::now().timestamp_millis();
let data = format!("refresh_{}", ts).into_bytes();
let mut rng = rand::rngs::OsRng;
let encrypted = key.encrypt(&mut rng, Oaep::new::<Sha256>(), &data).unwrap();
let encrypted = key
.encrypt(&mut rng, Oaep::new::<Sha256>(), &data)
.expect("fail to encrypt");
hex::encode(encrypted)
}
@@ -161,10 +163,10 @@ JNrRuoEUXpabUzGB8QIDAQAB
_ => unreachable!(),
}
}
if !res["data"]["refresh_token"].is_string() {
bail!("refresh_token not found");
match res["data"]["refresh_token"].as_str() {
Some(token) => credential.ac_time_value = token.to_string(),
None => bail!("refresh_token not found"),
}
credential.ac_time_value = res["data"]["refresh_token"].as_str().unwrap().to_string();
Ok(credential)
}
@@ -195,9 +197,9 @@ fn regex_find(pattern: &str, doc: &str) -> Result<String> {
let re = Regex::new(pattern)?;
Ok(re
.captures(doc)
.ok_or(anyhow!("pattern not match"))?
.ok_or_else(|| anyhow!("no match found"))?
.get(1)
.unwrap()
.ok_or_else(|| anyhow!("no capture found"))?
.as_str()
.to_string())
}
@@ -240,7 +242,9 @@ fn _encoded_query<'a>(
.collect();
params.push(("wts", timestamp.into()));
params.sort_by(|a, b| a.0.cmp(b.0));
let query = serde_urlencoded::to_string(&params).unwrap().replace('+', "%20");
let query = serde_urlencoded::to_string(&params)
.expect("fail to encode query")
.replace('+', "%20");
params.push(("w_rid", format!("{:x}", md5::compute(query.clone() + mixin_key)).into()));
params
}

View File

@@ -71,23 +71,25 @@ impl<'a> FavoriteList<'a> {
Err(e) => {
error!("failed to get videos of favorite {} page {}: {}", self.fid, page, e);
break;
},
}
};
if !videos["data"]["medias"].is_array() {
warn!("no medias found in favorite {} page {}", self.fid, page);
let medias = &mut videos["data"]["medias"];
if medias.as_array().is_none_or(|v| v.is_empty()) {
error!("no medias found in favorite {} page {}", self.fid, page);
break;
}
let videos_info = match serde_json::from_value::<Vec<VideoInfo>>(videos["data"]["medias"].take()) {
let videos_info: Vec<VideoInfo> = match serde_json::from_value(medias.take()) {
Ok(v) => v,
Err(e) => {
error!("failed to parse videos of favorite {} page {}: {}", self.fid, page, e);
break;
},
}
};
for video_info in videos_info{
for video_info in videos_info {
yield video_info;
}
if videos["data"]["has_more"].is_boolean() && videos["data"]["has_more"].as_bool().unwrap(){
let has_more = &videos["data"]["has_more"];
if has_more.as_bool().is_some_and(|v| v) {
page += 1;
continue;
}

View File

@@ -66,23 +66,25 @@ impl<'a> Submission<'a> {
Err(e) => {
error!("failed to get videos of upper {} page {}: {}", self.upper_id, page, e);
break;
},
}
};
if !videos["data"]["list"]["vlist"].is_array() {
warn!("no medias found in upper {} page {}", self.upper_id, page);
let vlist = &mut videos["data"]["list"]["vlist"];
if vlist.as_array().is_none_or(|v| v.is_empty()) {
error!("no medias found in upper {} page {}", self.upper_id, page);
break;
}
let videos_info = match serde_json::from_value::<Vec<VideoInfo>>(videos["data"]["list"]["vlist"].take()) {
let videos_info: Vec<VideoInfo> = match serde_json::from_value(vlist.take()) {
Ok(v) => v,
Err(e) => {
error!("failed to parse videos of upper {} page {}: {}", self.upper_id, page, e);
break;
},
}
};
for video_info in videos_info{
for video_info in videos_info {
yield video_info;
}
if videos["data"]["page"]["count"].is_i64() && videos["data"]["page"]["count"].as_i64().unwrap() > (page * 30) as i64 {
let count = &videos["data"]["page"]["count"];
if count.as_i64().is_some_and(|v| v > (page * 30) as i64) {
page += 1;
continue;
}

View File

@@ -172,7 +172,7 @@ fn bvid_to_aid(bvid: &str) -> u64 {
(bvid[4], bvid[7]) = (bvid[7], bvid[4]);
let mut tmp = 0u64;
for char in bvid.into_iter().skip(3) {
let idx = DATA.iter().position(|&x| x == char).unwrap();
let idx = DATA.iter().position(|&x| x == char).expect("invalid bvid");
tmp = tmp * BASE + idx as u64;
}
(tmp & MASK_CODE) ^ XOR_CODE

View File

@@ -22,8 +22,12 @@ pub static TEMPLATE: Lazy<handlebars::Handlebars> = Lazy::new(|| {
}
});
handlebars.register_helper("truncate", Box::new(truncate));
handlebars.path_safe_register("video", &CONFIG.video_name).unwrap();
handlebars.path_safe_register("page", &CONFIG.page_name).unwrap();
handlebars
.path_safe_register("video", &CONFIG.video_name)
.expect("failed to register video template");
handlebars
.path_safe_register("page", &CONFIG.page_name)
.expect("failed to register page template");
handlebars
});

View File

@@ -1,7 +1,7 @@
macro_rules! regex {
($re:literal $(,)?) => {{
static RE: once_cell::sync::OnceCell<regex::Regex> = once_cell::sync::OnceCell::new();
RE.get_or_init(|| regex::Regex::new($re).unwrap())
RE.get_or_init(|| regex::Regex::new($re).expect("invalid regex"))
}};
}