refactor: 继续调整优化部分代码,移除主体代码的所有 unwrap
This commit is contained in:
@@ -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()),
|
||||
))
|
||||
|
||||
@@ -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()),
|
||||
))
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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()),
|
||||
))
|
||||
|
||||
@@ -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()),
|
||||
))
|
||||
|
||||
@@ -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!(),
|
||||
}),
|
||||
|
||||
@@ -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"),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(¶ms).unwrap().replace('+', "%20");
|
||||
let query = serde_urlencoded::to_string(¶ms)
|
||||
.expect("fail to encode query")
|
||||
.replace('+', "%20");
|
||||
params.push(("w_rid", format!("{:x}", md5::compute(query.clone() + mixin_key)).into()));
|
||||
params
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
|
||||
@@ -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"))
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user