feat(aria2): 重构 download 函数并添加新功能

- 重构 download 函数,返回通知接收器以支持进度更新
- 新增 search 模块,实现关键词搜索功能
- 更新 single模块,增加音频格式判断- 引入日志模块,优化调试输出
- 新增特殊字符替换函数,用于文件名处理
This commit is contained in:
2025-08-19 10:06:04 +08:00
parent 025ffb6255
commit 0cec957b34
3 changed files with 84 additions and 4 deletions

View File

@@ -1,4 +1,8 @@
use crate::aria2::download;
use crate::single::{multiple, replace_special_char};
use log::Level::Debug; use log::Level::Debug;
use std::fs;
use std::time::Duration;
mod aria2; mod aria2;
mod search; mod search;
@@ -8,6 +12,38 @@ pub mod utils;
type ErrorString = String; type ErrorString = String;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> Result<(), ErrorString> {
simple_logger::init_with_level(Debug).unwrap(); simple_logger::init_with_level(Debug).unwrap();
let multiple = multiple(7308249639).await?;
let mut handles = vec![];
for song in multiple {
let handle: tokio::task::JoinHandle<Result<_, ErrorString>> = tokio::spawn(async move {
let single = single::single(song).await?;
download(
single.download_url.clone(),
format!("{}/{}", single.id, format!("{}.{}", single.name, single.format))
)
.await?;
download(
single.pic_url.clone(),
format!("{}/{}", single.id, format!("{}.jpg", single.id))
)
.await?;
let json = serde_json::to_string_pretty(&single)
.map_err(|e| ErrorString::from(e.to_string()))?;
fs::write(format!("E:\\163\\{}\\{}.json", single.id, single.id), json)
.map_err(|e| ErrorString::from(e.to_string()))?;
Ok(())
});
handles.push(handle);
}
for handle in handles {
tokio::join!(handle);
}
tokio::time::sleep(Duration::from_secs(5000000000)).await;
Ok(())
} }

View File

@@ -1,5 +1,5 @@
use crate::utils::create_reqwest_client;
use crate::ErrorString; use crate::ErrorString;
use crate::utils::create_reqwest_client;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]

View File

@@ -1,9 +1,9 @@
use crate::utils::create_reqwest_client;
use crate::ErrorString; use crate::ErrorString;
use crate::utils::create_reqwest_client;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
#[derive(Debug)] #[derive(Debug, Serialize, Deserialize)]
pub struct SingleSongsInfo { pub struct SingleSongsInfo {
pub id: i64, pub id: i64,
pub name: String, pub name: String,
@@ -12,6 +12,7 @@ pub struct SingleSongsInfo {
pub pic_url: String, pub pic_url: String,
pub download_url: String, pub download_url: String,
pub format: String, pub format: String,
pub lyric: Option<String>,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@@ -21,6 +22,7 @@ struct DetailJson {
al_name: String, al_name: String,
pic: String, pic: String,
url: String, url: String,
lyric: Option<String>,
} }
pub async fn single(id: i64) -> Result<SingleSongsInfo, ErrorString> { pub async fn single(id: i64) -> Result<SingleSongsInfo, ErrorString> {
@@ -55,6 +57,7 @@ pub async fn single(id: i64) -> Result<SingleSongsInfo, ErrorString> {
} else { } else {
String::from("mp3") String::from("mp3")
}, },
lyric: info_result.lyric,
}) })
} }
@@ -69,3 +72,44 @@ pub fn replace_special_char(s: String) -> String {
.replace(r#"|"#, "-") .replace(r#"|"#, "-")
.replace(r#"""#, "-") .replace(r#"""#, "-")
} }
#[derive(Serialize, Deserialize)]
pub struct PlayList {
playlist: PlayListDetail,
}
#[derive(Serialize, Deserialize)]
pub struct PlayListDetail {
tracks: Vec<PlayListDetailTrack>,
}
#[derive(Serialize, Deserialize)]
pub struct PlayListDetailTrack {
id: i64,
}
pub async fn multiple(id: i64) -> Result<Vec<i64>, ErrorString> {
let client = create_reqwest_client().await?;
let info_handle: JoinHandle<Result<PlayList, ErrorString>> = tokio::spawn(async move {
let info_request_url = format!("https://163.genshinmc.eu.org/playlist/detail?id={id}");
client
.get(info_request_url)
.send()
.await
.map_err(|e| format!("无法获取歌曲信息: {e}"))?
.json::<PlayList>()
.await
.map_err(|e| format!("无法解析歌曲信息: {e}"))
});
let info_result = info_handle
.await
.map_err(|e| format!("歌曲信息获取失败: {e}"))??;
Ok(info_result
.playlist
.tracks
.iter()
.map(|track| track.id)
.collect::<Vec<i64>>())
}