diff --git a/src/main.rs b/src/main.rs index bbf629c..7aedb05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,8 @@ +use crate::aria2::download; +use crate::single::{multiple, replace_special_char}; use log::Level::Debug; +use std::fs; +use std::time::Duration; mod aria2; mod search; @@ -8,6 +12,38 @@ pub mod utils; type ErrorString = String; #[tokio::main] -async fn main() { +async fn main() -> Result<(), ErrorString> { 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> = 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(()) } diff --git a/src/search.rs b/src/search.rs index b82e3b9..4910fe0 100644 --- a/src/search.rs +++ b/src/search.rs @@ -1,5 +1,5 @@ -use crate::utils::create_reqwest_client; use crate::ErrorString; +use crate::utils::create_reqwest_client; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug)] diff --git a/src/single.rs b/src/single.rs index 78cfe57..a614f4d 100644 --- a/src/single.rs +++ b/src/single.rs @@ -1,9 +1,9 @@ -use crate::utils::create_reqwest_client; use crate::ErrorString; +use crate::utils::create_reqwest_client; use serde::{Deserialize, Serialize}; use tokio::task::JoinHandle; -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] pub struct SingleSongsInfo { pub id: i64, pub name: String, @@ -12,6 +12,7 @@ pub struct SingleSongsInfo { pub pic_url: String, pub download_url: String, pub format: String, + pub lyric: Option, } #[derive(Serialize, Deserialize)] @@ -21,6 +22,7 @@ struct DetailJson { al_name: String, pic: String, url: String, + lyric: Option, } pub async fn single(id: i64) -> Result { @@ -55,6 +57,7 @@ pub async fn single(id: i64) -> Result { } else { String::from("mp3") }, + lyric: info_result.lyric, }) } @@ -69,3 +72,44 @@ pub fn replace_special_char(s: String) -> String { .replace(r#"|"#, "-") .replace(r#"""#, "-") } + +#[derive(Serialize, Deserialize)] +pub struct PlayList { + playlist: PlayListDetail, +} + +#[derive(Serialize, Deserialize)] +pub struct PlayListDetail { + tracks: Vec, +} +#[derive(Serialize, Deserialize)] +pub struct PlayListDetailTrack { + id: i64, +} + +pub async fn multiple(id: i64) -> Result, ErrorString> { + let client = create_reqwest_client().await?; + + let info_handle: JoinHandle> = 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::() + .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::>()) +}