chore: 修复新的 clippy warnings (#467)

This commit is contained in:
ᴀᴍᴛᴏᴀᴇʀ
2025-09-24 17:36:20 +08:00
committed by GitHub
parent 4db7e6763a
commit b441f04cdf
12 changed files with 87 additions and 100 deletions
+5 -4
View File
@@ -56,11 +56,12 @@ impl VideoSource for collection::Model {
latest_row_at: &chrono::DateTime<Utc>, latest_row_at: &chrono::DateTime<Utc>,
) -> Option<VideoInfo> { ) -> Option<VideoInfo> {
// 由于 collection 的视频无固定时间顺序,should_take 无法提前中断拉取,因此 should_filter 环节需要进行额外过滤 // 由于 collection 的视频无固定时间顺序,should_take 无法提前中断拉取,因此 should_filter 环节需要进行额外过滤
if let Ok(video_info) = video_info { if let Ok(video_info) = video_info
if video_info.release_datetime() > latest_row_at { && video_info.release_datetime() > latest_row_at
return Some(video_info); {
} return Some(video_info);
} }
None None
} }
@@ -55,11 +55,11 @@ ORDER BY
)) ))
.all(&db), .all(&db),
)?; )?;
return Ok(ApiResponse::ok(DashBoardResponse { Ok(ApiResponse::ok(DashBoardResponse {
enabled_favorites, enabled_favorites,
enabled_collections, enabled_collections,
enabled_submissions, enabled_submissions,
enable_watch_later: enabled_watch_later > 0, enable_watch_later: enabled_watch_later > 0,
videos_by_day, videos_by_day,
})); }))
} }
+6 -7
View File
@@ -43,17 +43,16 @@ pub async fn auth(mut headers: HeaderMap, request: Request, next: Next) -> Resul
{ {
return Ok(next.run(request).await); return Ok(next.run(request).await);
} }
if let Some(protocol) = headers.remove("Sec-WebSocket-Protocol") { if let Some(protocol) = headers.remove("Sec-WebSocket-Protocol")
if protocol && protocol
.to_str() .to_str()
.ok() .ok()
.and_then(|s| BASE64_URL_SAFE_NO_PAD.decode(s).ok()) .and_then(|s| BASE64_URL_SAFE_NO_PAD.decode(s).ok())
.is_some_and(|s| s == token.as_bytes()) .is_some_and(|s| s == token.as_bytes())
{ {
let mut resp = next.run(request).await; let mut resp = next.run(request).await;
resp.headers_mut().insert("Sec-WebSocket-Protocol", protocol); resp.headers_mut().insert("Sec-WebSocket-Protocol", protocol);
return Ok(resp); return Ok(resp);
}
} }
Ok(ApiResponse::<()>::unauthorized("auth token does not match").into_response()) Ok(ApiResponse::<()>::unauthorized("auth token does not match").into_response())
} }
+8 -8
View File
@@ -118,7 +118,7 @@ impl WebSocketHandler {
let rx = log_writer_clone.sender.subscribe(); let rx = log_writer_clone.sender.subscribe();
let log_stream = futures::stream::iter(history_logs.into_iter()) let log_stream = futures::stream::iter(history_logs.into_iter())
.chain(BroadcastStream::new(rx).filter_map(async |msg| msg.ok())) .chain(BroadcastStream::new(rx).filter_map(async |msg| msg.ok()))
.map(|msg| ServerEvent::Logs(msg)); .map(ServerEvent::Logs);
pin!(log_stream); pin!(log_stream);
while let Some(event) = log_stream.next().await { while let Some(event) = log_stream.next().await {
if let Err(e) = tx_clone.send(event).await { if let Err(e) = tx_clone.send(event).await {
@@ -133,8 +133,8 @@ impl WebSocketHandler {
if task_handle.as_ref().is_none_or(|h: &JoinHandle<()>| h.is_finished()) { if task_handle.as_ref().is_none_or(|h: &JoinHandle<()>| h.is_finished()) {
let tx_clone = tx.clone(); let tx_clone = tx.clone();
task_handle = Some(tokio::spawn(async move { task_handle = Some(tokio::spawn(async move {
let mut stream = WatchStream::new(TASK_STATUS_NOTIFIER.subscribe()) let mut stream =
.map(|status| ServerEvent::Tasks(status)); WatchStream::new(TASK_STATUS_NOTIFIER.subscribe()).map(ServerEvent::Tasks);
while let Some(event) = stream.next().await { while let Some(event) = stream.next().await {
if let Err(e) = tx_clone.send(event).await { if let Err(e) = tx_clone.send(event).await {
error!("Failed to send task status: {:?}", e); error!("Failed to send task status: {:?}", e);
@@ -179,7 +179,7 @@ impl WebSocketHandler {
// 添加订阅者 // 添加订阅者
async fn add_sysinfo_subscriber(&self, uuid: Uuid, sender: tokio::sync::mpsc::Sender<ServerEvent>) { async fn add_sysinfo_subscriber(&self, uuid: Uuid, sender: tokio::sync::mpsc::Sender<ServerEvent>) {
self.sysinfo_subscribers.insert(uuid, sender); self.sysinfo_subscribers.insert(uuid, sender);
if self.sysinfo_subscribers.len() > 0 if !self.sysinfo_subscribers.is_empty()
&& self && self
.sysinfo_handles .sysinfo_handles
.read() .read()
@@ -235,10 +235,10 @@ impl WebSocketHandler {
async fn remove_sysinfo_subscriber(&self, uuid: Uuid) { async fn remove_sysinfo_subscriber(&self, uuid: Uuid) {
self.sysinfo_subscribers.remove(&uuid); self.sysinfo_subscribers.remove(&uuid);
if self.sysinfo_subscribers.is_empty() { if self.sysinfo_subscribers.is_empty()
if let Some(handle) = self.sysinfo_handles.write().take() { && let Some(handle) = self.sysinfo_handles.write().take()
handle.abort(); {
} handle.abort();
} }
} }
} }
+26 -28
View File
@@ -263,39 +263,37 @@ impl PageAnalyzer {
}); });
} }
} }
if !filter_option.no_hires { if !filter_option.no_hires
if let Some(flac) = self.info.pointer_mut("/dash/flac/audio") { && let Some(flac) = self.info.pointer_mut("/dash/flac/audio")
let (Some(url), Some(quality)) = (flac["baseUrl"].as_str(), flac["id"].as_u64()) else { {
bail!("invalid flac stream"); let (Some(url), Some(quality)) = (flac["baseUrl"].as_str(), flac["id"].as_u64()) else {
}; bail!("invalid flac stream");
let quality = AudioQuality::from_repr(quality as usize).context("invalid flac stream quality")?; };
if quality >= filter_option.audio_min_quality && quality <= filter_option.audio_max_quality { let quality = AudioQuality::from_repr(quality as usize).context("invalid flac stream quality")?;
streams.push(Stream::DashAudio { if quality >= filter_option.audio_min_quality && quality <= filter_option.audio_max_quality {
url: url.to_string(), streams.push(Stream::DashAudio {
backup_url: serde_json::from_value(flac["backupUrl"].take()).unwrap_or_default(), url: url.to_string(),
quality, backup_url: serde_json::from_value(flac["backupUrl"].take()).unwrap_or_default(),
}); quality,
} });
} }
} }
if !filter_option.no_dolby_audio { if !filter_option.no_dolby_audio
if let Some(dolby_audio) = self && let Some(dolby_audio) = self
.info .info
.pointer_mut("/dash/dolby/audio/0") .pointer_mut("/dash/dolby/audio/0")
.and_then(|a| a.as_object_mut()) .and_then(|a| a.as_object_mut())
{ {
let (Some(url), Some(quality)) = (dolby_audio["baseUrl"].as_str(), dolby_audio["id"].as_u64()) else { let (Some(url), Some(quality)) = (dolby_audio["baseUrl"].as_str(), dolby_audio["id"].as_u64()) else {
bail!("invalid dolby audio stream"); bail!("invalid dolby audio stream");
}; };
let quality = let quality = AudioQuality::from_repr(quality as usize).context("invalid dolby audio stream quality")?;
AudioQuality::from_repr(quality as usize).context("invalid dolby audio stream quality")?; if quality >= filter_option.audio_min_quality && quality <= filter_option.audio_max_quality {
if quality >= filter_option.audio_min_quality && quality <= filter_option.audio_max_quality { streams.push(Stream::DashAudio {
streams.push(Stream::DashAudio { url: url.to_string(),
url: url.to_string(), backup_url: serde_json::from_value(dolby_audio["backupUrl"].take()).unwrap_or_default(),
backup_url: serde_json::from_value(dolby_audio["backupUrl"].take()).unwrap_or_default(), quality,
quality, });
});
}
} }
} }
Ok(streams) Ok(streams)
+1 -1
View File
@@ -149,7 +149,7 @@ impl Downloader {
} }
} }
} }
res.with_context(|| format!("failed to download file")) res.context("failed to download file")
} }
pub async fn merge(&self, video_path: &Path, audio_path: &Path, output_path: &Path) -> Result<()> { pub async fn merge(&self, video_path: &Path, audio_path: &Path, output_path: &Path) -> Result<()> {
+4 -4
View File
@@ -42,10 +42,10 @@ impl From<Result<ExecutionStatus>> for ExecutionStatus {
} }
} }
// 未包裹的 reqwest::Error // 未包裹的 reqwest::Error
if let Some(error) = cause.downcast_ref::<reqwest::Error>() { if let Some(error) = cause.downcast_ref::<reqwest::Error>()
if is_ignored_reqwest_error(error) { && is_ignored_reqwest_error(error)
return ExecutionStatus::Ignored(err); {
} return ExecutionStatus::Ignored(err);
} }
} }
ExecutionStatus::Failed(err) ExecutionStatus::Failed(err)
+20 -20
View File
@@ -53,13 +53,13 @@ async fn frontend_files(request: Request) -> impl IntoResponse {
(header::CACHE_CONTROL, "no-cache"), (header::CACHE_CONTROL, "no-cache"),
(header::ETAG, &content.hash()), (header::ETAG, &content.hash()),
]; ];
if let Some(if_none_match) = request.headers().get(header::IF_NONE_MATCH) { if let Some(if_none_match) = request.headers().get(header::IF_NONE_MATCH)
if let Ok(client_etag) = if_none_match.to_str() { && let Ok(client_etag) = if_none_match.to_str()
if client_etag == content.hash() { && client_etag == content.hash()
return (StatusCode::NOT_MODIFIED, default_headers).into_response(); {
} return (StatusCode::NOT_MODIFIED, default_headers).into_response();
}
} }
if request.method() == axum::http::Method::HEAD { if request.method() == axum::http::Method::HEAD {
return (StatusCode::OK, default_headers).into_response(); return (StatusCode::OK, default_headers).into_response();
} }
@@ -74,20 +74,20 @@ async fn frontend_files(request: Request) -> impl IntoResponse {
.map(|s| s.split(',').map(str::trim).collect::<HashSet<_>>()) .map(|s| s.split(',').map(str::trim).collect::<HashSet<_>>())
.unwrap_or_default(); .unwrap_or_default();
for (encoding, data) in [("br", content.data_br()), ("gzip", content.data_gzip())] { for (encoding, data) in [("br", content.data_br()), ("gzip", content.data_gzip())] {
if accepted_encodings.contains(encoding) { if accepted_encodings.contains(encoding)
if let Some(data) = data { && let Some(data) = data
return ( {
StatusCode::OK, return (
[ StatusCode::OK,
(header::CONTENT_TYPE, content_type), [
(header::CACHE_CONTROL, "no-cache"), (header::CONTENT_TYPE, content_type),
(header::ETAG, &content.hash()), (header::CACHE_CONTROL, "no-cache"),
(header::CONTENT_ENCODING, encoding), (header::ETAG, &content.hash()),
], (header::CONTENT_ENCODING, encoding),
data, ],
) data,
.into_response(); )
} .into_response();
} }
} }
( (
+3 -3
View File
@@ -52,14 +52,14 @@ impl FieldEvaluatable for RuleTarget {
/// 修改模型后进行评估,此时能访问的是未保存的 activeModel,就地使用 activeModel 评估 /// 修改模型后进行评估,此时能访问的是未保存的 activeModel,就地使用 activeModel 评估
fn evaluate(&self, video: &video::ActiveModel, pages: &[page::ActiveModel]) -> bool { fn evaluate(&self, video: &video::ActiveModel, pages: &[page::ActiveModel]) -> bool {
match self { match self {
RuleTarget::Title(cond) => video.name.try_as_ref().is_some_and(|title| cond.evaluate(&title)), RuleTarget::Title(cond) => video.name.try_as_ref().is_some_and(|title| cond.evaluate(title)),
// 目前的所有条件都是分别针对全体标签进行 any 评估的,例如 Prefix("a") && Suffix("b") 意味着 any(tag.Prefix("a")) && any(tag.Suffix("b")) 而非 any(tag.Prefix("a") && tag.Suffix("b")) // 目前的所有条件都是分别针对全体标签进行 any 评估的,例如 Prefix("a") && Suffix("b") 意味着 any(tag.Prefix("a")) && any(tag.Suffix("b")) 而非 any(tag.Prefix("a") && tag.Suffix("b"))
// 这可能不满足用户预期,但应该问题不大,如果真有很多人用复杂标签筛选再单独改 // 这可能不满足用户预期,但应该问题不大,如果真有很多人用复杂标签筛选再单独改
RuleTarget::Tags(cond) => video RuleTarget::Tags(cond) => video
.tags .tags
.try_as_ref() .try_as_ref()
.and_then(|t| t.as_ref()) .and_then(|t| t.as_ref())
.is_some_and(|tags| tags.0.iter().any(|tag| cond.evaluate(&tag))), .is_some_and(|tags| tags.0.iter().any(|tag| cond.evaluate(tag))),
RuleTarget::FavTime(cond) => video RuleTarget::FavTime(cond) => video
.favtime .favtime
.try_as_ref() .try_as_ref()
@@ -84,7 +84,7 @@ impl FieldEvaluatable for RuleTarget {
RuleTarget::Tags(cond) => video RuleTarget::Tags(cond) => video
.tags .tags
.as_ref() .as_ref()
.is_some_and(|tags| tags.0.iter().any(|tag| cond.evaluate(&tag))), .is_some_and(|tags| tags.0.iter().any(|tag| cond.evaluate(tag))),
RuleTarget::FavTime(cond) => cond.evaluate(&video.favtime.and_utc().with_timezone(&Local).naive_local()), RuleTarget::FavTime(cond) => cond.evaluate(&video.favtime.and_utc().with_timezone(&Local).naive_local()),
RuleTarget::PubTime(cond) => cond.evaluate(&video.pubtime.and_utc().with_timezone(&Local).naive_local()), RuleTarget::PubTime(cond) => cond.evaluate(&video.pubtime.and_utc().with_timezone(&Local).naive_local()),
RuleTarget::PageCount(cond) => cond.evaluate(pages.len()), RuleTarget::PageCount(cond) => cond.evaluate(pages.len()),
+2 -13
View File
@@ -7,7 +7,7 @@ use crate::config::VersionedConfig;
pub static TASK_STATUS_NOTIFIER: LazyLock<TaskStatusNotifier> = LazyLock::new(TaskStatusNotifier::new); pub static TASK_STATUS_NOTIFIER: LazyLock<TaskStatusNotifier> = LazyLock::new(TaskStatusNotifier::new);
#[derive(Serialize)] #[derive(Serialize, Default)]
pub struct TaskStatus { pub struct TaskStatus {
is_running: bool, is_running: bool,
last_run: Option<chrono::DateTime<chrono::Local>>, last_run: Option<chrono::DateTime<chrono::Local>>,
@@ -21,17 +21,6 @@ pub struct TaskStatusNotifier {
rx: tokio::sync::watch::Receiver<Arc<TaskStatus>>, rx: tokio::sync::watch::Receiver<Arc<TaskStatus>>,
} }
impl Default for TaskStatus {
fn default() -> Self {
Self {
is_running: false,
last_run: None,
last_finish: None,
next_run: None,
}
}
}
impl TaskStatusNotifier { impl TaskStatusNotifier {
pub fn new() -> Self { pub fn new() -> Self {
let (tx, rx) = tokio::sync::watch::channel(Arc::new(TaskStatus::default())); let (tx, rx) = tokio::sync::watch::channel(Arc::new(TaskStatus::default()));
@@ -55,7 +44,7 @@ impl TaskStatusNotifier {
pub fn finish_running(&self, _lock: MutexGuard<()>) { pub fn finish_running(&self, _lock: MutexGuard<()>) {
let last_status = self.tx.borrow(); let last_status = self.tx.borrow();
let last_run = last_status.last_run.clone(); let last_run = last_status.last_run;
drop(last_status); drop(last_status);
let config = VersionedConfig::get().load(); let config = VersionedConfig::get().load();
let now = chrono::Local::now(); let now = chrono::Local::now();
+8 -8
View File
@@ -296,10 +296,10 @@ pub async fn download_video_pages(
error!("处理视频「{}」{}失败: {:#}", &video_model.name, task_name, e) error!("处理视频「{}」{}失败: {:#}", &video_model.name, task_name, e)
} }
}); });
if let ExecutionStatus::Failed(e) = results.into_iter().nth(4).context("page download result not found")? { if let ExecutionStatus::Failed(e) = results.into_iter().nth(4).context("page download result not found")?
if e.downcast_ref::<DownloadAbortError>().is_some() { && e.downcast_ref::<DownloadAbortError>().is_some()
return Err(e); {
} return Err(e);
} }
let mut video_active_model: video::ActiveModel = video_model.into(); let mut video_active_model: video::ActiveModel = video_model.into();
video_active_model.download_status = Set(status.into()); video_active_model.download_status = Set(status.into());
@@ -488,10 +488,10 @@ pub async fn download_page(
), ),
}); });
// 如果下载视频时触发风控,直接返回 DownloadAbortError // 如果下载视频时触发风控,直接返回 DownloadAbortError
if let ExecutionStatus::Failed(e) = results.into_iter().nth(1).context("video download result not found")? { if let ExecutionStatus::Failed(e) = results.into_iter().nth(1).context("video download result not found")?
if let Ok(BiliError::RiskControlOccurred) = e.downcast::<BiliError>() { && let Ok(BiliError::RiskControlOccurred) = e.downcast::<BiliError>()
bail!(DownloadAbortError()); {
} bail!(DownloadAbortError());
} }
let mut page_active_model: page::ActiveModel = page_model.into(); let mut page_active_model: page::ActiveModel = page_model.into();
page_active_model.download_status = Set(status.into()); page_active_model.download_status = Set(status.into());
@@ -108,11 +108,11 @@ where
{ {
let pattern = String::deserialize(deserializer)?; let pattern = String::deserialize(deserializer)?;
// 反序列化时预编译 regex,优化性能 // 反序列化时预编译 regex,优化性能
let regex = regex::Regex::new(&pattern).map_err(|e| serde::de::Error::custom(e))?; let regex = regex::Regex::new(&pattern).map_err(serde::de::Error::custom)?;
Ok((pattern, regex)) Ok((pattern, regex))
} }
fn serialize_regex<S>(pattern: &String, _regex: &regex::Regex, serializer: S) -> Result<S::Ok, S::Error> fn serialize_regex<S>(pattern: &str, _regex: &regex::Regex, serializer: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
{ {