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

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

134
Cargo.lock generated
View File

@@ -68,7 +68,7 @@ dependencies = [
"miniz_oxide", "miniz_oxide",
"object", "object",
"rustc-demangle", "rustc-demangle",
"windows-targets", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
@@ -140,6 +140,16 @@ dependencies = [
"windows-link", "windows-link",
] ]
[[package]]
name = "colored"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
dependencies = [
"lazy_static",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "core-foundation-sys" name = "core-foundation-sys"
version = "0.8.7" version = "0.8.7"
@@ -722,6 +732,12 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.175" version = "0.2.175"
@@ -777,10 +793,13 @@ name = "netease-downloader"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"aria2-ws", "aria2-ws",
"log",
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"simple_logger",
"tokio", "tokio",
"urlencoding",
] ]
[[package]] [[package]]
@@ -798,6 +817,15 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "num_threads"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.36.7" version = "0.36.7"
@@ -1211,6 +1239,18 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "simple_logger"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8c5dfa5e08767553704aa0ffd9d9794d527103c736aba9854773851fd7497eb"
dependencies = [
"colored",
"log",
"time",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.11" version = "0.4.11"
@@ -1341,7 +1381,9 @@ checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
dependencies = [ dependencies = [
"deranged", "deranged",
"itoa", "itoa",
"libc",
"num-conv", "num-conv",
"num_threads",
"powerfmt", "powerfmt",
"serde", "serde",
"time-core", "time-core",
@@ -1556,6 +1598,12 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]] [[package]]
name = "utf-8" name = "utf-8"
version = "0.7.6" version = "0.7.6"
@@ -1757,13 +1805,22 @@ dependencies = [
"windows-link", "windows-link",
] ]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [ dependencies = [
"windows-targets", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
@@ -1772,7 +1829,22 @@ version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [ dependencies = [
"windows-targets", "windows-targets 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
] ]
[[package]] [[package]]
@@ -1781,28 +1853,46 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc", "windows_aarch64_msvc 0.52.6",
"windows_i686_gnu", "windows_i686_gnu 0.52.6",
"windows_i686_gnullvm", "windows_i686_gnullvm",
"windows_i686_msvc", "windows_i686_msvc 0.52.6",
"windows_x86_64_gnu", "windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc", "windows_x86_64_msvc 0.52.6",
] ]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.6" version = "0.52.6"
@@ -1815,24 +1905,48 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.6" version = "0.52.6"

View File

@@ -9,3 +9,6 @@ reqwest = { version = "0.12.23", default-features = false, features = ["rustls-t
serde = { version = "1.0.219", default-features = false, features = ["std", "derive"] } serde = { version = "1.0.219", default-features = false, features = ["std", "derive"] }
serde_json = { version = "1.0.142", default-features = false, features = ["std"] } serde_json = { version = "1.0.142", default-features = false, features = ["std"] }
aria2-ws = "0.5.1" aria2-ws = "0.5.1"
simple_logger = { version = "5.0.0", features = ["colored", "colors", "threads"] }
log = { version = "0.4.27",default-features = false, features = ["std"] }
urlencoding = "2.1.3"

View File

@@ -1,18 +1,22 @@
use crate::ErrorString; use crate::ErrorString;
use aria2_ws::{Client, TaskOptions}; use aria2_ws::{Client, TaskOptions};
use tokio::sync::broadcast::Receiver;
pub async fn download(url: String, path: String) -> Result<(), ErrorString> { pub async fn download(
url: String,
path: String,
) -> Result<Receiver<aria2_ws::Notification>, ErrorString> {
let client = Client::connect("ws://127.0.0.1:16800/jsonrpc", Some("GenshinMinecraft")) let client = Client::connect("ws://127.0.0.1:16800/jsonrpc", Some("GenshinMinecraft"))
.await .await
.map_err(|e| format!("无法创建 Client: {e}"))?; .map_err(|e| format!("无法创建 Client: {e}"))?;
let options = TaskOptions { let options = TaskOptions {
out: Some(path), out: Some(path.clone()),
..Default::default() ..Default::default()
}; };
client client
.add_uri(vec![url], Some(options.clone()), None, None) .add_uri(vec![url.clone()], Some(options.clone()), None, None)
.await .await
.map_err(|e| format!("无法添加任务: {e}"))?; .map_err(|e| format!("无法添加任务: {e}"))?;
let not = client.subscribe_notifications();
Ok(()) Ok(not)
} }

View File

@@ -1,4 +1,7 @@
use log::Level::Debug;
mod aria2; mod aria2;
mod search;
mod single; mod single;
pub mod utils; pub mod utils;
@@ -6,7 +9,5 @@ type ErrorString = String;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let single_songs_info = single::single(448317056).await.unwrap(); simple_logger::init_with_level(Debug).unwrap();
println!("{:?}", single_songs_info);
aria2::download(single_songs_info.download_url, format!("{}.flac", single_songs_info.name)).await.unwrap();
} }

43
src/search.rs Normal file
View File

@@ -0,0 +1,43 @@
use crate::utils::create_reqwest_client;
use crate::ErrorString;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct Search {
pub result: SearchResult,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SearchResult {
pub songs: Vec<SearchResultSong>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SearchResultSong {
pub id: i64,
pub name: String,
pub artists: Vec<SearchResultSongArtist>,
pub duration: u64,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct SearchResultSongArtist {
pub name: String,
}
pub async fn search(keyword: String) -> Result<Vec<SearchResultSong>, ErrorString> {
let client = create_reqwest_client().await?;
let resp = client
.get(format!(
"https://163.genshinmc.eu.org/search?keywords={}&limit=20",
urlencoding::encode(keyword.as_str())
))
.send()
.await
.map_err(|e| format!("请求错误: {}", e))?;
let json: Search = resp.json().await.map_err(|e| format!("解析错误: {}", e))?;
Ok(json.result.songs)
}

View File

@@ -1,16 +1,17 @@
use crate::ErrorString;
use crate::utils::create_reqwest_client; use crate::utils::create_reqwest_client;
use crate::ErrorString;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
#[derive(Debug)] #[derive(Debug)]
pub struct SingleSongsInfo { pub struct SingleSongsInfo {
pub id: u64, pub id: i64,
pub name: String, pub name: String,
pub artist: String, pub artist: String,
pub album: String, pub album: String,
pub pic_url: String, pub pic_url: String,
pub download_url: String, pub download_url: String,
pub format: String,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@@ -22,7 +23,7 @@ struct DetailJson {
url: String, url: String,
} }
pub async fn single(id: u64) -> Result<SingleSongsInfo, ErrorString> { pub async fn single(id: i64) -> Result<SingleSongsInfo, ErrorString> {
let client = create_reqwest_client().await?; let client = create_reqwest_client().await?;
let info_handle: JoinHandle<Result<DetailJson, ErrorString>> = tokio::spawn(async move { let info_handle: JoinHandle<Result<DetailJson, ErrorString>> = tokio::spawn(async move {
@@ -48,6 +49,23 @@ pub async fn single(id: u64) -> Result<SingleSongsInfo, ErrorString> {
artist: info_result.ar_name, artist: info_result.ar_name,
album: info_result.al_name, album: info_result.al_name,
pic_url: info_result.pic, pic_url: info_result.pic,
download_url: info_result.url, download_url: info_result.url.clone(),
format: if info_result.url.contains(".flac") {
String::from("flac")
} else {
String::from("mp3")
},
}) })
} }
pub fn replace_special_char(s: String) -> String {
s.replace(r#"\"#, "-")
.replace(r#"/"#, "-")
.replace(r#"*"#, "-")
.replace(r#"?"#, "-")
.replace(r#"<"#, "-")
.replace(r#">"#, "-")
.replace(r#":"#, "-")
.replace(r#"|"#, "-")
.replace(r#"""#, "-")
}