diff --git a/.gitignore b/.gitignore index 2bf76b0..0d67fff 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /*.json* /players*.parquet /region*.parquet +/records*.parquet /.python-version /uv.lock diff --git a/sdgb-api/src/title/model/get_user_music_api/mod.rs b/sdgb-api/src/title/model/get_user_music_api/mod.rs index 0d0df8f..b3f8f29 100644 --- a/sdgb-api/src/title/model/get_user_music_api/mod.rs +++ b/sdgb-api/src/title/model/get_user_music_api/mod.rs @@ -64,6 +64,20 @@ pub struct UserMusicDetail { /// DX 分数 pub deluxscore_max: i64, + /// - D = 0, + /// - C = 1, + /// - B = 2, + /// - BB = 3, + /// - BBB = 4, + /// - A = 5, + /// - AA = 6, + /// - AAA = 7, + /// - S = 8, + /// - S_PLUS = 9, + /// - SS = 10, + /// - SS_PLUS = 11, + /// - SSS = 12, + /// - SSS_PLUS = 13 pub score_rank: i64, /// 理论次数 @@ -71,6 +85,21 @@ pub struct UserMusicDetail { pub ext_num2: i64, } +#[cfg_attr(feature = "parquet", derive(parquet_derive::ParquetRecordWriter))] +pub struct UserMusicDetailFlatten { + pub user_id: u32, + pub music_id: u32, + pub level: u8, + pub play_count: u32, + pub achievement: u32, + pub combo_status: u8, + pub sync_status: u8, + pub deluxscore_max: u16, + pub score_rank: u8, + pub ext_num1: u32, + pub ext_num2: u32, +} + impl Display for UserMusicDetail { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if let Some(music_title) = query_music(self.music_id).map(|i| &i.name) { @@ -119,3 +148,35 @@ impl Display for UserMusicDetail { Ok(()) } } + +impl UserMusicDetailFlatten { + pub fn new( + user_id: u32, + UserMusicDetail { + music_id, + level, + play_count, + achievement, + combo_status, + sync_status, + deluxscore_max, + score_rank, + ext_num1, + ext_num2, + }: UserMusicDetail, + ) -> Self { + Self { + user_id, + music_id, + level: level as _, + sync_status: sync_status as _, + deluxscore_max: deluxscore_max as _, + score_rank: score_rank as _, + play_count: play_count as _, + achievement: achievement as _, + combo_status: combo_status as _, + ext_num1: ext_num1 as _, + ext_num2: ext_num2 as _, + } + } +} diff --git a/sdgb-api/src/title/model/mod.rs b/sdgb-api/src/title/model/mod.rs index ba9c431..faa6e7e 100644 --- a/sdgb-api/src/title/model/mod.rs +++ b/sdgb-api/src/title/model/mod.rs @@ -23,7 +23,9 @@ pub use get_user_rating_api::{ }; mod get_user_music_api; -pub use get_user_music_api::{GetUserMusicApi, GetUserMusicApiResp, UserMusic, UserMusicDetail}; +pub use get_user_music_api::{ + GetUserMusicApi, GetUserMusicApiResp, UserMusic, UserMusicDetail, UserMusicDetailFlatten, +}; mod get_user_region_api; pub use get_user_region_api::{ diff --git a/sdgb-cli/src/commands.rs b/sdgb-cli/src/commands.rs index 5f47402..1c8a29d 100644 --- a/sdgb-cli/src/commands.rs +++ b/sdgb-cli/src/commands.rs @@ -123,6 +123,8 @@ pub enum Commands { ScrapeAllB50Dump {}, #[cfg(feature = "fetchall")] ScrapeAllRegionDump {}, + #[cfg(feature = "fetchall")] + ScrapeAllRecordDump {}, Logout { #[arg(short, long)] diff --git a/sdgb-cli/src/main.rs b/sdgb-cli/src/main.rs index 9dd06dc..f5b0fdc 100644 --- a/sdgb-cli/src/main.rs +++ b/sdgb-cli/src/main.rs @@ -337,6 +337,31 @@ async fn main() -> Result<(), Box> { dump_parquet(regions_flat, "regions.parquet")?; } #[cfg(feature = "fetchall")] + Commands::ScrapeAllRecordDump {} => { + use crate::{ + cache::RECORDS, + utils::helpers::{dump_parquet, read_cache}, + }; + use sdgb_api::title::model::GetUserMusicApiResp; + use sdgb_api::title::model::UserMusicDetailFlatten; + + let records: Vec = read_cache(RECORDS)?; + dump_parquet( + records + .into_iter() + .map(|resp| { + resp.user_music_list + .into_iter() + .map(|music| music.user_music_detail_list) + .flatten() + .map(move |detail| UserMusicDetailFlatten::new(resp.user_id, detail)) + }) + .flatten() + .collect::>(), + "records.parquet", + )?; + } + #[cfg(feature = "fetchall")] Commands::ScrapeAllB50Dump {} => { use crate::{cache::B50, utils::helpers::dump_json};