From 19a3d450c12c43c390d3c7a7179184c0872e94ff Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 3 Jan 2025 18:23:53 +0100 Subject: [PATCH 01/10] Rename AlbumStatus to AlbumOwnership --- src/core/collection/album.rs | 14 +++++++------- src/tui/ui/browse_state.rs | 10 +++++----- src/tui/ui/display.rs | 19 +++++++++++-------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/core/collection/album.rs b/src/core/collection/album.rs index f27192a..308e901 100644 --- a/src/core/collection/album.rs +++ b/src/core/collection/album.rs @@ -138,16 +138,16 @@ pub enum AlbumSecondaryType { } /// The album's ownership status. -pub enum AlbumStatus { +pub enum AlbumOwnership { None, Owned(TrackFormat), } -impl AlbumStatus { - pub fn from_tracks(tracks: &[Track]) -> AlbumStatus { +impl AlbumOwnership { + pub fn from_tracks(tracks: &[Track]) -> AlbumOwnership { match tracks.iter().map(|t| t.quality.format).min() { - Some(format) => AlbumStatus::Owned(format), - None => AlbumStatus::None, + Some(format) => AlbumOwnership::Owned(format), + None => AlbumOwnership::None, } } } @@ -165,8 +165,8 @@ impl Album { self } - pub fn get_status(&self) -> AlbumStatus { - AlbumStatus::from_tracks(&self.tracks) + pub fn get_ownership(&self) -> AlbumOwnership { + AlbumOwnership::from_tracks(&self.tracks) } } diff --git a/src/tui/ui/browse_state.rs b/src/tui/ui/browse_state.rs index 72254ff..b5e2201 100644 --- a/src/tui/ui/browse_state.rs +++ b/src/tui/ui/browse_state.rs @@ -1,5 +1,5 @@ use musichoard::collection::{ - album::{Album, AlbumStatus}, + album::{Album, AlbumOwnership}, artist::Artist, track::{Track, TrackFormat}, }; @@ -175,7 +175,7 @@ impl<'a, 'b> AlbumState<'a, 'b> { )) .unwrap_or_default(), album - .map(|a| UiDisplay::display_album_status(&a.get_status())) + .map(|a| UiDisplay::display_album_status(&a.get_ownership())) .unwrap_or("") )); @@ -188,9 +188,9 @@ impl<'a, 'b> AlbumState<'a, 'b> { } fn to_list_item(album: &Album) -> ListItem { - let line = match album.get_status() { - AlbumStatus::None => Line::raw(album.meta.id.title.as_str()), - AlbumStatus::Owned(format) => match format { + let line = match album.get_ownership() { + AlbumOwnership::None => Line::raw(album.meta.id.title.as_str()), + AlbumOwnership::Owned(format) => match format { TrackFormat::Mp3 => Line::styled(album.meta.id.title.as_str(), UiColor::FG_WARN), TrackFormat::Flac => Line::styled(album.meta.id.title.as_str(), UiColor::FG_GOOD), }, diff --git a/src/tui/ui/display.rs b/src/tui/ui/display.rs index 68c2281..1dcc4bb 100644 --- a/src/tui/ui/display.rs +++ b/src/tui/ui/display.rs @@ -1,7 +1,7 @@ use musichoard::collection::{ album::{ - AlbumDate, AlbumId, AlbumLibId, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumSeq, - AlbumStatus, + AlbumDate, AlbumId, AlbumLibId, AlbumMeta, AlbumOwnership, AlbumPrimaryType, + AlbumSecondaryType, AlbumSeq, }, artist::ArtistMeta, musicbrainz::{IMusicBrainzRef, MbRefOption}, @@ -101,10 +101,10 @@ impl UiDisplay { types.join(", ") } - pub fn display_album_status(status: &AlbumStatus) -> &'static str { + pub fn display_album_status(status: &AlbumOwnership) -> &'static str { match status { - AlbumStatus::None => "None", - AlbumStatus::Owned(format) => match format { + AlbumOwnership::None => "None", + AlbumOwnership::Owned(format) => match format { TrackFormat::Mp3 => "MP3", TrackFormat::Flac => "FLAC", }, @@ -284,13 +284,16 @@ mod tests { #[test] fn display_album_status() { - assert_eq!(UiDisplay::display_album_status(&AlbumStatus::None), "None"); assert_eq!( - UiDisplay::display_album_status(&AlbumStatus::Owned(TrackFormat::Mp3)), + UiDisplay::display_album_status(&AlbumOwnership::None), + "None" + ); + assert_eq!( + UiDisplay::display_album_status(&AlbumOwnership::Owned(TrackFormat::Mp3)), "MP3" ); assert_eq!( - UiDisplay::display_album_status(&AlbumStatus::Owned(TrackFormat::Flac)), + UiDisplay::display_album_status(&AlbumOwnership::Owned(TrackFormat::Flac)), "FLAC" ); } -- 2.47.1 From dce402cee0bae7f05c62d03f38ff74829b3bb5c0 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 3 Jan 2025 18:31:47 +0100 Subject: [PATCH 02/10] Fix --- src/tui/ui/browse_state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tui/ui/browse_state.rs b/src/tui/ui/browse_state.rs index b5e2201..4a0129f 100644 --- a/src/tui/ui/browse_state.rs +++ b/src/tui/ui/browse_state.rs @@ -163,7 +163,7 @@ impl<'a, 'b> AlbumState<'a, 'b> { "Title: {}\n\ Date: {}\n\ Type: {}\n\ - Status: {}", + Ownership: {}", album.map(|a| a.meta.id.title.as_str()).unwrap_or(""), album .map(|a| UiDisplay::display_date(&a.meta.date, &a.meta.seq)) -- 2.47.1 From 6d1e8b88f41b23183b680a65932b1c8981ad698f Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 3 Jan 2025 18:36:54 +0100 Subject: [PATCH 03/10] Add AlbumStatus to Album --- src/core/collection/album.rs | 20 ++++++++++++++++++++ src/core/musichoard/database.rs | 3 ++- src/core/testmod.rs | 1 + src/external/database/serde/deserialize.rs | 1 + src/testmod/full.rs | 10 ++++++++++ src/tui/app/machine/match_state.rs | 3 ++- src/tui/lib/external/musicbrainz/api/mod.rs | 1 + src/tui/testmod.rs | 1 + src/tui/ui/mod.rs | 3 ++- tests/testlib.rs | 9 ++++++++- 10 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/core/collection/album.rs b/src/core/collection/album.rs index 308e901..a0088cd 100644 --- a/src/core/collection/album.rs +++ b/src/core/collection/album.rs @@ -27,6 +27,7 @@ pub struct AlbumMeta { /// Album non-identifier metadata. #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct AlbumInfo { + pub status: Option, pub primary_type: Option, pub secondary_types: Vec, } @@ -93,6 +94,23 @@ impl From<(u32, u8, u8)> for AlbumDate { #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd, Ord, Eq, Hash)] pub struct AlbumSeq(pub u8); +/// Based on [MusicBrainz status](https://musicbrainz.org/doc/Release#Status). +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum AlbumStatus { + /// Official + Official, + /// Promotion + Promotion, + /// Bootleg + Bootleg, + /// Pseudo-release + PseudoRelease, + /// Withdrawn + Withdrawn, + /// Cancelled + Cancelled, +} + /// Based on [MusicBrainz types](https://musicbrainz.org/doc/Release_Group/Type). #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum AlbumPrimaryType { @@ -238,10 +256,12 @@ impl AlbumMeta { impl AlbumInfo { pub fn new( + status: Option, primary_type: Option, secondary_types: Vec, ) -> Self { AlbumInfo { + status, primary_type, secondary_types, } diff --git a/src/core/musichoard/database.rs b/src/core/musichoard/database.rs index 0d387aa..8de11a5 100644 --- a/src/core/musichoard/database.rs +++ b/src/core/musichoard/database.rs @@ -453,7 +453,7 @@ mod tests { use crate::{ collection::{ - album::{AlbumPrimaryType, AlbumSecondaryType}, + album::{AlbumPrimaryType, AlbumSecondaryType, AlbumStatus}, musicbrainz::MbArtistRef, }, core::{ @@ -944,6 +944,7 @@ mod tests { assert_eq!(meta.info.secondary_types, Vec::new()); let info = AlbumInfo::new( + Some(AlbumStatus::Official), Some(AlbumPrimaryType::Album), vec![AlbumSecondaryType::Live], ); diff --git a/src/core/testmod.rs b/src/core/testmod.rs index a812f67..929723a 100644 --- a/src/core/testmod.rs +++ b/src/core/testmod.rs @@ -4,6 +4,7 @@ use std::collections::HashMap; use crate::core::collection::{ album::{ Album, AlbumId, AlbumInfo, AlbumLibId, AlbumMbRef, AlbumMeta, AlbumPrimaryType, AlbumSeq, + AlbumStatus, }, artist::{Artist, ArtistId, ArtistInfo, ArtistMbRef, ArtistMeta}, musicbrainz::{MbAlbumRef, MbArtistRef}, diff --git a/src/external/database/serde/deserialize.rs b/src/external/database/serde/deserialize.rs index 182c9c6..889ca84 100644 --- a/src/external/database/serde/deserialize.rs +++ b/src/external/database/serde/deserialize.rs @@ -138,6 +138,7 @@ impl From for Album { date: album.date.into(), seq: AlbumSeq(album.seq), info: AlbumInfo { + status: None, primary_type: album.primary_type.map(Into::into), secondary_types: album.secondary_types.into_iter().map(Into::into).collect(), }, diff --git a/src/testmod/full.rs b/src/testmod/full.rs index 4e5c1d2..a07a5d0 100644 --- a/src/testmod/full.rs +++ b/src/testmod/full.rs @@ -36,6 +36,7 @@ macro_rules! full_collection { date: 1998.into(), seq: AlbumSeq(1), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -100,6 +101,7 @@ macro_rules! full_collection { date: (2015, 4).into(), seq: AlbumSeq(1), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -168,6 +170,7 @@ macro_rules! full_collection { date: (2003, 6, 6).into(), seq: AlbumSeq(1), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -212,6 +215,7 @@ macro_rules! full_collection { date: 2008.into(), seq: AlbumSeq(3), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -256,6 +260,7 @@ macro_rules! full_collection { date: 2009.into(), seq: AlbumSeq(2), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -298,6 +303,7 @@ macro_rules! full_collection { date: 2015.into(), seq: AlbumSeq(4), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -354,6 +360,7 @@ macro_rules! full_collection { date: 1985.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -396,6 +403,7 @@ macro_rules! full_collection { date: 2018.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -452,6 +460,7 @@ macro_rules! full_collection { date: 1995.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -494,6 +503,7 @@ macro_rules! full_collection { date: 2028.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, diff --git a/src/tui/app/machine/match_state.rs b/src/tui/app/machine/match_state.rs index b25e669..241679c 100644 --- a/src/tui/app/machine/match_state.rs +++ b/src/tui/app/machine/match_state.rs @@ -282,7 +282,7 @@ mod tests { Sequence, }; use musichoard::collection::{ - album::{AlbumDate, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType}, + album::{AlbumDate, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumStatus}, artist::{ArtistId, ArtistMeta}, }; @@ -347,6 +347,7 @@ mod tests { AlbumMeta::new(id) .with_date(AlbumDate::new(Some(1990), Some(5), None)) .with_info(AlbumInfo::new( + Some(AlbumStatus::Official), Some(AlbumPrimaryType::Album), vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation], )) diff --git a/src/tui/lib/external/musicbrainz/api/mod.rs b/src/tui/lib/external/musicbrainz/api/mod.rs index f7e893c..3a73660 100644 --- a/src/tui/lib/external/musicbrainz/api/mod.rs +++ b/src/tui/lib/external/musicbrainz/api/mod.rs @@ -138,6 +138,7 @@ fn from_mb_release_group_meta(meta: MbReleaseGroupMeta) -> AlbumMeta { date: meta.first_release_date, seq: AlbumSeq::default(), info: AlbumInfo { + status: None, primary_type: meta.primary_type, secondary_types: meta.secondary_types.unwrap_or_default(), }, diff --git a/src/tui/testmod.rs b/src/tui/testmod.rs index 6346109..f5cb5cf 100644 --- a/src/tui/testmod.rs +++ b/src/tui/testmod.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use musichoard::collection::{ album::{ Album, AlbumId, AlbumInfo, AlbumLibId, AlbumMbRef, AlbumMeta, AlbumPrimaryType, AlbumSeq, + AlbumStatus, }, artist::{Artist, ArtistId, ArtistInfo, ArtistMbRef, ArtistMeta}, musicbrainz::{MbAlbumRef, MbArtistRef}, diff --git a/src/tui/ui/mod.rs b/src/tui/ui/mod.rs index c3e3ee3..5297b03 100644 --- a/src/tui/ui/mod.rs +++ b/src/tui/ui/mod.rs @@ -199,7 +199,7 @@ impl IUi for Ui { #[cfg(test)] mod tests { use musichoard::collection::{ - album::{AlbumDate, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType}, + album::{AlbumDate, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumStatus}, artist::{Artist, ArtistId, ArtistMeta}, }; @@ -361,6 +361,7 @@ mod tests { AlbumMeta::new(id) .with_date(AlbumDate::new(Some(1990), Some(5), None)) .with_info(AlbumInfo::new( + Some(AlbumStatus::Official), Some(AlbumPrimaryType::Album), vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation], )) diff --git a/tests/testlib.rs b/tests/testlib.rs index 119042a..90138c0 100644 --- a/tests/testlib.rs +++ b/tests/testlib.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use musichoard::collection::{ album::{ Album, AlbumId, AlbumInfo, AlbumLibId, AlbumMbRef, AlbumMeta, AlbumPrimaryType, - AlbumSecondaryType, AlbumSeq, + AlbumSecondaryType, AlbumSeq, AlbumStatus, }, artist::{Artist, ArtistId, ArtistInfo, ArtistMbRef, ArtistMeta}, musicbrainz::MbArtistRef, @@ -47,6 +47,7 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 2011.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -240,6 +241,7 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 2004.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Ep), secondary_types: vec![], }, @@ -323,6 +325,7 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 2008.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -494,6 +497,7 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 2001.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -677,6 +681,7 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 2011.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -793,6 +798,7 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 1984.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -898,6 +904,7 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 1999.into(), seq: AlbumSeq(0), info: AlbumInfo { + status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![AlbumSecondaryType::Live], }, -- 2.47.1 From 3fb3f304ff1e72927bcbbb50c89d9908689f80e8 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 3 Jan 2025 19:03:05 +0100 Subject: [PATCH 04/10] Add status to database --- src/core/collection/album.rs | 1 + src/external/database/json/testmod.rs | 20 ++++++++-------- src/external/database/serde/common.rs | 28 +++++++++++++++++++++- src/external/database/serde/deserialize.rs | 5 ++-- src/external/database/serde/serialize.rs | 4 +++- tests/files/database/database.json | 2 +- 6 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/core/collection/album.rs b/src/core/collection/album.rs index a0088cd..ffcdfb8 100644 --- a/src/core/collection/album.rs +++ b/src/core/collection/album.rs @@ -294,6 +294,7 @@ impl Merge for AlbumMeta { impl Merge for AlbumInfo { fn merge_in_place(&mut self, other: Self) { + self.status = self.status.take().or(other.status); self.primary_type = self.primary_type.take().or(other.primary_type); if self.secondary_types.is_empty() { self.secondary_types = other.secondary_types; diff --git a/src/external/database/json/testmod.rs b/src/external/database/json/testmod.rs index 04fd2b1..ccd7fce 100644 --- a/src/external/database/json/testmod.rs +++ b/src/external/database/json/testmod.rs @@ -14,13 +14,13 @@ pub static DATABASE_JSON: &str = "{\ \"title\":\"album_title a.a\",\"lib_id\":{\"Value\":1},\ \"date\":{\"year\":1998,\"month\":null,\"day\":null},\"seq\":1,\ \"musicbrainz\":{\"Some\":\"00000000-0000-0000-0000-000000000000\"},\ - \"primary_type\":\"Album\",\"secondary_types\":[]\ + \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title a.b\",\"lib_id\":{\"Value\":2},\ \"date\":{\"year\":2015,\"month\":4,\"day\":null},\"seq\":1,\ \"musicbrainz\":\"None\",\ - \"primary_type\":\"Album\",\"secondary_types\":[]\ + \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ }\ ]\ },\ @@ -41,25 +41,25 @@ pub static DATABASE_JSON: &str = "{\ \"title\":\"album_title b.a\",\"lib_id\":{\"Value\":3},\ \"date\":{\"year\":2003,\"month\":6,\"day\":6},\"seq\":1,\ \"musicbrainz\":\"None\",\ - \"primary_type\":\"Album\",\"secondary_types\":[]\ + \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title b.b\",\"lib_id\":{\"Value\":4},\ \"date\":{\"year\":2008,\"month\":null,\"day\":null},\"seq\":3,\ \"musicbrainz\":{\"Some\":\"11111111-1111-1111-1111-111111111111\"},\ - \"primary_type\":\"Album\",\"secondary_types\":[]\ + \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title b.c\",\"lib_id\":{\"Value\":5},\ \"date\":{\"year\":2009,\"month\":null,\"day\":null},\"seq\":2,\ \"musicbrainz\":{\"Some\":\"11111111-1111-1111-1111-111111111112\"},\ - \"primary_type\":\"Album\",\"secondary_types\":[]\ + \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title b.d\",\"lib_id\":{\"Value\":6},\ \"date\":{\"year\":2015,\"month\":null,\"day\":null},\"seq\":4,\ \"musicbrainz\":\"None\",\ - \"primary_type\":\"Album\",\"secondary_types\":[]\ + \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ }\ ]\ },\ @@ -73,13 +73,13 @@ pub static DATABASE_JSON: &str = "{\ \"title\":\"album_title c.a\",\"lib_id\":{\"Value\":7},\ \"date\":{\"year\":1985,\"month\":null,\"day\":null},\"seq\":0,\ \"musicbrainz\":\"None\",\ - \"primary_type\":\"Album\",\"secondary_types\":[]\ + \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title c.b\",\"lib_id\":{\"Value\":8},\ \"date\":{\"year\":2018,\"month\":null,\"day\":null},\"seq\":0,\ \"musicbrainz\":\"None\",\ - \"primary_type\":\"Album\",\"secondary_types\":[]\ + \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ }\ ]\ },\ @@ -93,13 +93,13 @@ pub static DATABASE_JSON: &str = "{\ \"title\":\"album_title d.a\",\"lib_id\":{\"Value\":9},\ \"date\":{\"year\":1995,\"month\":null,\"day\":null},\"seq\":0,\ \"musicbrainz\":\"None\",\ - \"primary_type\":\"Album\",\"secondary_types\":[]\ + \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title d.b\",\"lib_id\":{\"Value\":10},\ \"date\":{\"year\":2028,\"month\":null,\"day\":null},\"seq\":0,\ \"musicbrainz\":\"None\",\ - \"primary_type\":\"Album\",\"secondary_types\":[]\ + \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ }\ ]\ }\ diff --git a/src/external/database/serde/common.rs b/src/external/database/serde/common.rs index 1cc230e..c4c245a 100644 --- a/src/external/database/serde/common.rs +++ b/src/external/database/serde/common.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use crate::core::collection::{ - album::{AlbumDate, AlbumLibId, AlbumPrimaryType, AlbumSecondaryType}, + album::{AlbumDate, AlbumLibId, AlbumPrimaryType, AlbumSecondaryType, AlbumStatus}, musicbrainz::MbRefOption, }; @@ -59,6 +59,32 @@ pub enum MbRefOptionDef { None, } +#[derive(Debug, Deserialize, Serialize)] +#[serde(remote = "AlbumStatus")] +pub enum AlbumStatusDef { + Official, + Promotion, + Bootleg, + PseudoRelease, + Withdrawn, + Cancelled, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct SerdeAlbumStatus(#[serde(with = "AlbumStatusDef")] AlbumStatus); + +impl From for AlbumStatus { + fn from(value: SerdeAlbumStatus) -> Self { + value.0 + } +} + +impl From for SerdeAlbumStatus { + fn from(value: AlbumStatus) -> Self { + SerdeAlbumStatus(value) + } +} + #[derive(Debug, Deserialize, Serialize)] #[serde(remote = "AlbumPrimaryType")] pub enum AlbumPrimaryTypeDef { diff --git a/src/external/database/serde/deserialize.rs b/src/external/database/serde/deserialize.rs index 889ca84..f73d46c 100644 --- a/src/external/database/serde/deserialize.rs +++ b/src/external/database/serde/deserialize.rs @@ -11,7 +11,7 @@ use crate::{ }, external::database::serde::common::{ MbRefOptionDef, SerdeAlbumDate, SerdeAlbumLibId, SerdeAlbumPrimaryType, - SerdeAlbumSecondaryType, + SerdeAlbumSecondaryType, SerdeAlbumStatus, }, }; @@ -46,6 +46,7 @@ pub struct DeserializeAlbum { date: SerdeAlbumDate, seq: u8, musicbrainz: DeserializeMbRefOption, + status: Option, primary_type: Option, secondary_types: Vec, } @@ -138,7 +139,7 @@ impl From for Album { date: album.date.into(), seq: AlbumSeq(album.seq), info: AlbumInfo { - status: None, + status: album.status.map(Into::into), primary_type: album.primary_type.map(Into::into), secondary_types: album.secondary_types.into_iter().map(Into::into).collect(), }, diff --git a/src/external/database/serde/serialize.rs b/src/external/database/serde/serialize.rs index a88657f..a794aa7 100644 --- a/src/external/database/serde/serialize.rs +++ b/src/external/database/serde/serialize.rs @@ -7,7 +7,7 @@ use crate::{ core::collection::{album::Album, artist::Artist, musicbrainz::IMusicBrainzRef, Collection}, external::database::serde::common::{ MbRefOptionDef, SerdeAlbumDate, SerdeAlbumLibId, SerdeAlbumPrimaryType, - SerdeAlbumSecondaryType, + SerdeAlbumSecondaryType, SerdeAlbumStatus, }, }; @@ -38,6 +38,7 @@ pub struct SerializeAlbum<'a> { date: SerdeAlbumDate, seq: u8, musicbrainz: SerializeMbRefOption<'a>, + status: Option, primary_type: Option, secondary_types: Vec, } @@ -97,6 +98,7 @@ impl<'a> From<&'a Album> for SerializeAlbum<'a> { date: album.meta.date.into(), seq: album.meta.seq.0, musicbrainz: (&album.meta.id.mb_ref).into(), + status: album.meta.info.status.map(Into::into), primary_type: album.meta.info.primary_type.map(Into::into), secondary_types: album .meta diff --git a/tests/files/database/database.json b/tests/files/database/database.json index ccce86d..9d4d6f7 100644 --- a/tests/files/database/database.json +++ b/tests/files/database/database.json @@ -1 +1 @@ -{"V20250103":[{"name":"Аркона","sort":"Arkona","musicbrainz":{"Some":"baad262d-55ef-427a-83c7-f7530964f212"},"properties":{"Bandcamp":["https://arkonamoscow.bandcamp.com/"],"MusicButler":["https://www.musicbutler.io/artist-page/283448581"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/arkona/download-streaming-albums"]},"albums":[{"title":"Slovo","lib_id":{"Value":7},"date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":[]}]},{"name":"Eluveitie","sort":null,"musicbrainz":{"Some":"8000598a-5edb-401c-8e6d-36b167feaf38"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/269358403"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/eluveitie/download-streaming-albums"]},"albums":[{"title":"Vên [re‐recorded]","lib_id":{"Value":1},"date":{"year":2004,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Ep","secondary_types":[]},{"title":"Slania","lib_id":{"Value":2},"date":{"year":2008,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":[]}]},{"name":"Frontside","sort":null,"musicbrainz":{"Some":"3a901353-fccd-4afd-ad01-9c03f451b490"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/826588800"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/frontside/download-streaming-albums"]},"albums":[{"title":"…nasze jest królestwo, potęga i chwała na wieki…","lib_id":{"Value":3},"date":{"year":2001,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":[]}]},{"name":"Heaven’s Basement","sort":"Heaven’s Basement","musicbrainz":{"Some":"c2c4d56a-d599-4a18-bd2f-ae644e2198cc"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/291158685"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums"]},"albums":[{"title":"Paper Plague","lib_id":"Singleton","date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":null,"secondary_types":[]},{"title":"Unbreakable","lib_id":{"Value":4},"date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":[]}]},{"name":"Metallica","sort":null,"musicbrainz":{"Some":"65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/3996865"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/metallica/download-streaming-albums"]},"albums":[{"title":"Ride the Lightning","lib_id":{"Value":5},"date":{"year":1984,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":[]},{"title":"S&M","lib_id":{"Value":6},"date":{"year":1999,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":["Live"]}]}]} \ No newline at end of file +{"V20250103":[{"name":"Аркона","sort":"Arkona","musicbrainz":{"Some":"baad262d-55ef-427a-83c7-f7530964f212"},"properties":{"Bandcamp":["https://arkonamoscow.bandcamp.com/"],"MusicButler":["https://www.musicbutler.io/artist-page/283448581"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/arkona/download-streaming-albums"]},"albums":[{"title":"Slovo","lib_id":{"Value":7},"date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":[]}]},{"name":"Eluveitie","sort":null,"musicbrainz":{"Some":"8000598a-5edb-401c-8e6d-36b167feaf38"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/269358403"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/eluveitie/download-streaming-albums"]},"albums":[{"title":"Vên [re‐recorded]","lib_id":{"Value":1},"date":{"year":2004,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Ep","secondary_types":[]},{"title":"Slania","lib_id":{"Value":2},"date":{"year":2008,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":[]}]},{"name":"Frontside","sort":null,"musicbrainz":{"Some":"3a901353-fccd-4afd-ad01-9c03f451b490"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/826588800"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/frontside/download-streaming-albums"]},"albums":[{"title":"…nasze jest królestwo, potęga i chwała na wieki…","lib_id":{"Value":3},"date":{"year":2001,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":[]}]},{"name":"Heaven’s Basement","sort":"Heaven’s Basement","musicbrainz":{"Some":"c2c4d56a-d599-4a18-bd2f-ae644e2198cc"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/291158685"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums"]},"albums":[{"title":"Paper Plague","lib_id":"Singleton","date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":null,"primary_type":null,"secondary_types":[]},{"title":"Unbreakable","lib_id":{"Value":4},"date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":[]}]},{"name":"Metallica","sort":null,"musicbrainz":{"Some":"65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/3996865"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/metallica/download-streaming-albums"]},"albums":[{"title":"Ride the Lightning","lib_id":{"Value":5},"date":{"year":1984,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":[]},{"title":"S&M","lib_id":{"Value":6},"date":{"year":1999,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":["Live"]}]}]} \ No newline at end of file -- 2.47.1 From 49e0b6b8f43c43b30f22cff853779df3ebf82c16 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 3 Jan 2025 19:16:11 +0100 Subject: [PATCH 05/10] Add status to display --- src/tui/ui/browse_state.rs | 8 +++- src/tui/ui/display.rs | 96 ++++++++++++++++++++++++++++---------- 2 files changed, 77 insertions(+), 27 deletions(-) diff --git a/src/tui/ui/browse_state.rs b/src/tui/ui/browse_state.rs index 4a0129f..7047802 100644 --- a/src/tui/ui/browse_state.rs +++ b/src/tui/ui/browse_state.rs @@ -163,19 +163,23 @@ impl<'a, 'b> AlbumState<'a, 'b> { "Title: {}\n\ Date: {}\n\ Type: {}\n\ + Status: {}\n\ Ownership: {}", album.map(|a| a.meta.id.title.as_str()).unwrap_or(""), album .map(|a| UiDisplay::display_date(&a.meta.date, &a.meta.seq)) .unwrap_or_default(), album - .map(|a| UiDisplay::display_type( + .map(|a| UiDisplay::display_album_type( &a.meta.info.primary_type, &a.meta.info.secondary_types )) .unwrap_or_default(), album - .map(|a| UiDisplay::display_album_status(&a.get_ownership())) + .map(|a| UiDisplay::display_album_status(&a.meta.info.status)) + .unwrap_or(""), + album + .map(|a| UiDisplay::display_album_ownership(&a.get_ownership())) .unwrap_or("") )); diff --git a/src/tui/ui/display.rs b/src/tui/ui/display.rs index 1dcc4bb..32535cd 100644 --- a/src/tui/ui/display.rs +++ b/src/tui/ui/display.rs @@ -1,7 +1,7 @@ use musichoard::collection::{ album::{ AlbumDate, AlbumId, AlbumLibId, AlbumMeta, AlbumOwnership, AlbumPrimaryType, - AlbumSecondaryType, AlbumSeq, + AlbumSecondaryType, AlbumSeq, AlbumStatus, }, artist::ArtistMeta, musicbrainz::{IMusicBrainzRef, MbRefOption}, @@ -50,19 +50,33 @@ impl UiDisplay { } } - pub fn display_type( + pub fn display_album_status(value: &Option) -> &'static str { + match value { + Some(status) => match status { + AlbumStatus::Official => "Official", + AlbumStatus::Promotion => "Promotion", + AlbumStatus::Bootleg => "Bootleg", + AlbumStatus::PseudoRelease => "Pseudo-Release", + AlbumStatus::Withdrawn => "Withdrawn", + AlbumStatus::Cancelled => "Cancelled", + }, + None => "", + } + } + + pub fn display_album_type( primary: &Option, secondary: &Vec, ) -> String { match primary { Some(ref primary) => { if secondary.is_empty() { - Self::display_primary_type(primary).to_string() + Self::display_album_primary_type(primary).to_string() } else { format!( "{} ({})", - Self::display_primary_type(primary), - Self::display_secondary_types(secondary) + Self::display_album_primary_type(primary), + Self::display_album_secondary_types(secondary) ) } } @@ -70,7 +84,7 @@ impl UiDisplay { } } - pub fn display_primary_type(value: &AlbumPrimaryType) -> &'static str { + pub fn display_album_primary_type(value: &AlbumPrimaryType) -> &'static str { match value { AlbumPrimaryType::Album => "Album", AlbumPrimaryType::Single => "Single", @@ -80,7 +94,7 @@ impl UiDisplay { } } - pub fn display_secondary_types(values: &Vec) -> String { + pub fn display_album_secondary_types(values: &Vec) -> String { let mut types: Vec<&'static str> = vec![]; for value in values { match value { @@ -101,7 +115,7 @@ impl UiDisplay { types.join(", ") } - pub fn display_album_status(status: &AlbumOwnership) -> &'static str { + pub fn display_album_ownership(status: &AlbumOwnership) -> &'static str { match status { AlbumOwnership::None => "None", AlbumOwnership::Owned(format) => match format { @@ -173,7 +187,7 @@ impl UiDisplay { "{:010} | {} [{}]", UiDisplay::display_album_date(&album.date), album.id.title, - UiDisplay::display_type(&album.info.primary_type, &album.info.secondary_types), + UiDisplay::display_album_type(&album.info.primary_type, &album.info.secondary_types), ) } @@ -224,30 +238,62 @@ mod tests { } #[test] - fn display_primary_type() { + fn display_album_status() { assert_eq!( - UiDisplay::display_primary_type(&AlbumPrimaryType::Album), + UiDisplay::display_album_status(&Some(AlbumStatus::Official)), + "Official" + ); + assert_eq!( + UiDisplay::display_album_status(&Some(AlbumStatus::Promotion)), + "Promotion" + ); + assert_eq!( + UiDisplay::display_album_status(&Some(AlbumStatus::Bootleg)), + "Bootleg" + ); + assert_eq!( + UiDisplay::display_album_status(&Some(AlbumStatus::PseudoRelease)), + "Pseudo-Release" + ); + assert_eq!( + UiDisplay::display_album_status(&Some(AlbumStatus::Withdrawn)), + "Withdrawn" + ); + assert_eq!( + UiDisplay::display_album_status(&Some(AlbumStatus::Cancelled)), + "Cancelled" + ); + assert_eq!(UiDisplay::display_album_status(&None), ""); + } + + #[test] + fn display_album_primary_type() { + assert_eq!( + UiDisplay::display_album_primary_type(&AlbumPrimaryType::Album), "Album" ); assert_eq!( - UiDisplay::display_primary_type(&AlbumPrimaryType::Single), + UiDisplay::display_album_primary_type(&AlbumPrimaryType::Single), "Single" ); - assert_eq!(UiDisplay::display_primary_type(&AlbumPrimaryType::Ep), "EP"); assert_eq!( - UiDisplay::display_primary_type(&AlbumPrimaryType::Broadcast), + UiDisplay::display_album_primary_type(&AlbumPrimaryType::Ep), + "EP" + ); + assert_eq!( + UiDisplay::display_album_primary_type(&AlbumPrimaryType::Broadcast), "Broadcast" ); assert_eq!( - UiDisplay::display_primary_type(&AlbumPrimaryType::Other), + UiDisplay::display_album_primary_type(&AlbumPrimaryType::Other), "Other" ); } #[test] - fn display_secondary_types() { + fn display_album_secondary_types() { assert_eq!( - UiDisplay::display_secondary_types(&vec![ + UiDisplay::display_album_secondary_types(&vec![ AlbumSecondaryType::Compilation, AlbumSecondaryType::Soundtrack, AlbumSecondaryType::Spokenword, @@ -267,14 +313,14 @@ mod tests { } #[test] - fn display_type() { - assert_eq!(UiDisplay::display_type(&None, &vec![]), ""); + fn display_album_type() { + assert_eq!(UiDisplay::display_album_type(&None, &vec![]), ""); assert_eq!( - UiDisplay::display_type(&Some(AlbumPrimaryType::Album), &vec![]), + UiDisplay::display_album_type(&Some(AlbumPrimaryType::Album), &vec![]), "Album" ); assert_eq!( - UiDisplay::display_type( + UiDisplay::display_album_type( &Some(AlbumPrimaryType::Album), &vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation] ), @@ -283,17 +329,17 @@ mod tests { } #[test] - fn display_album_status() { + fn display_album_ownership() { assert_eq!( - UiDisplay::display_album_status(&AlbumOwnership::None), + UiDisplay::display_album_ownership(&AlbumOwnership::None), "None" ); assert_eq!( - UiDisplay::display_album_status(&AlbumOwnership::Owned(TrackFormat::Mp3)), + UiDisplay::display_album_ownership(&AlbumOwnership::Owned(TrackFormat::Mp3)), "MP3" ); assert_eq!( - UiDisplay::display_album_status(&AlbumOwnership::Owned(TrackFormat::Flac)), + UiDisplay::display_album_ownership(&AlbumOwnership::Owned(TrackFormat::Flac)), "FLAC" ); } -- 2.47.1 From 1a5007459ff8bbdb687a2ae7d733077924b399e4 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 3 Jan 2025 20:09:11 +0100 Subject: [PATCH 06/10] Integrate with MB API --- src/external/musicbrainz/api/browse.rs | 32 ++++++++++++++++++++- src/external/musicbrainz/api/mod.rs | 25 +++++++++++++++- src/tui/lib/external/musicbrainz/api/mod.rs | 4 +-- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/external/musicbrainz/api/browse.rs b/src/external/musicbrainz/api/browse.rs index c62dc14..3a9d9cd 100644 --- a/src/external/musicbrainz/api/browse.rs +++ b/src/external/musicbrainz/api/browse.rs @@ -40,9 +40,21 @@ impl MusicBrainzClient { ) -> Result { let entity = &request.entity; let mbid = request.mbid.uuid().as_hyphenated(); + let status = match request.release_group_status { + Some(ref value) => { + let value_str = match value { + BrowseReleaseGroupRequestReleaseGroupStatus::WebsiteDefault => { + "website-default" + } + BrowseReleaseGroupRequestReleaseGroupStatus::All => "all", + }; + format!("&release-group-status={value_str}") + } + None => String::from(""), + }; let page = ApiDisplay::format_page_settings(paging); - let url = format!("{MB_BASE_URL}/release-group?{entity}={mbid}{page}"); + let url = format!("{MB_BASE_URL}/release-group?{entity}={mbid}{status}{page}"); let response: DeserializeBrowseReleaseGroupResponse = self.http.get(&url)?; Ok(response.into()) @@ -52,12 +64,18 @@ impl MusicBrainzClient { pub struct BrowseReleaseGroupRequest<'a> { entity: BrowseReleaseGroupRequestEntity, mbid: &'a Mbid, + release_group_status: Option, } enum BrowseReleaseGroupRequestEntity { Artist, } +enum BrowseReleaseGroupRequestReleaseGroupStatus { + WebsiteDefault, + All, +} + impl fmt::Display for BrowseReleaseGroupRequestEntity { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -71,8 +89,20 @@ impl<'a> BrowseReleaseGroupRequest<'a> { BrowseReleaseGroupRequest { entity: BrowseReleaseGroupRequestEntity::Artist, mbid, + release_group_status: None, } } + + pub fn status_website_default(mut self) -> Self { + self.release_group_status = + Some(BrowseReleaseGroupRequestReleaseGroupStatus::WebsiteDefault); + self + } + + pub fn status_all(mut self) -> Self { + self.release_group_status = Some(BrowseReleaseGroupRequestReleaseGroupStatus::All); + self + } } #[derive(Debug, PartialEq, Eq)] diff --git a/src/external/musicbrainz/api/mod.rs b/src/external/musicbrainz/api/mod.rs index bc3cc60..46e01a0 100644 --- a/src/external/musicbrainz/api/mod.rs +++ b/src/external/musicbrainz/api/mod.rs @@ -4,7 +4,7 @@ use serde::{de::Visitor, Deserialize, Deserializer}; use crate::{ collection::{ - album::{AlbumDate, AlbumPrimaryType, AlbumSecondaryType}, + album::{AlbumDate, AlbumPrimaryType, AlbumSecondaryType, AlbumStatus}, musicbrainz::Mbid, Error as CollectionError, }, @@ -131,6 +131,7 @@ pub struct MbReleaseGroupMeta { pub id: Mbid, pub title: String, pub first_release_date: AlbumDate, + pub status: Option, pub primary_type: Option, pub secondary_types: Option>, } @@ -141,6 +142,7 @@ pub struct SerdeMbReleaseGroupMeta { id: SerdeMbid, title: String, first_release_date: SerdeAlbumDate, + status: Option, primary_type: Option, secondary_types: Option>, } @@ -151,6 +153,7 @@ impl From for MbReleaseGroupMeta { id: value.id.into(), title: value.title, first_release_date: value.first_release_date.into(), + status: value.status.map(Into::into), primary_type: value.primary_type.map(Into::into), secondary_types: value .secondary_types @@ -281,6 +284,26 @@ impl<'de> Deserialize<'de> for SerdeAlbumDate { } } +#[derive(Debug, Deserialize)] +#[serde(remote = "AlbumStatus", rename_all(deserialize = "kebab-case"))] +pub enum AlbumStatusDef { + Official, + Promotion, + Bootleg, + PseudoRelease, + Withdrawn, + Cancelled, +} + +#[derive(Clone, Debug, Deserialize)] +pub struct SerdeAlbumStatus(#[serde(with = "AlbumStatusDef")] AlbumStatus); + +impl From for AlbumStatus { + fn from(value: SerdeAlbumStatus) -> Self { + value.0 + } +} + #[derive(Debug, Deserialize)] #[serde(remote = "AlbumPrimaryType")] pub enum AlbumPrimaryTypeDef { diff --git a/src/tui/lib/external/musicbrainz/api/mod.rs b/src/tui/lib/external/musicbrainz/api/mod.rs index 3a73660..eede4a1 100644 --- a/src/tui/lib/external/musicbrainz/api/mod.rs +++ b/src/tui/lib/external/musicbrainz/api/mod.rs @@ -99,7 +99,7 @@ impl IMusicBrainz for MusicBrainz { artist: &Mbid, paging: &mut Option, ) -> Result>, Error> { - let request = BrowseReleaseGroupRequest::artist(artist); + let request = BrowseReleaseGroupRequest::artist(artist).status_website_default(); let page = paging.take().unwrap_or_default(); let mb_response = self.client.browse_release_group(&request, &page)?; @@ -138,7 +138,7 @@ fn from_mb_release_group_meta(meta: MbReleaseGroupMeta) -> AlbumMeta { date: meta.first_release_date, seq: AlbumSeq::default(), info: AlbumInfo { - status: None, + status: meta.status, primary_type: meta.primary_type, secondary_types: meta.secondary_types.unwrap_or_default(), }, -- 2.47.1 From 397027192214d8e5451eae40e2a0e9d84ff5b471 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 3 Jan 2025 20:21:45 +0100 Subject: [PATCH 07/10] Remove album status from all types --- src/core/collection/album.rs | 21 ---------- src/core/musichoard/database.rs | 3 +- src/core/testmod.rs | 1 - src/external/database/serde/common.rs | 28 +------------ src/external/database/serde/deserialize.rs | 4 +- src/external/database/serde/serialize.rs | 4 +- src/external/musicbrainz/api/mod.rs | 25 +----------- src/testmod/full.rs | 10 ----- src/tui/app/machine/match_state.rs | 3 +- src/tui/lib/external/musicbrainz/api/mod.rs | 1 - src/tui/testmod.rs | 1 - src/tui/ui/browse_state.rs | 4 -- src/tui/ui/display.rs | 45 +-------------------- src/tui/ui/mod.rs | 3 +- tests/testlib.rs | 9 +---- 15 files changed, 9 insertions(+), 153 deletions(-) diff --git a/src/core/collection/album.rs b/src/core/collection/album.rs index ffcdfb8..308e901 100644 --- a/src/core/collection/album.rs +++ b/src/core/collection/album.rs @@ -27,7 +27,6 @@ pub struct AlbumMeta { /// Album non-identifier metadata. #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct AlbumInfo { - pub status: Option, pub primary_type: Option, pub secondary_types: Vec, } @@ -94,23 +93,6 @@ impl From<(u32, u8, u8)> for AlbumDate { #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd, Ord, Eq, Hash)] pub struct AlbumSeq(pub u8); -/// Based on [MusicBrainz status](https://musicbrainz.org/doc/Release#Status). -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub enum AlbumStatus { - /// Official - Official, - /// Promotion - Promotion, - /// Bootleg - Bootleg, - /// Pseudo-release - PseudoRelease, - /// Withdrawn - Withdrawn, - /// Cancelled - Cancelled, -} - /// Based on [MusicBrainz types](https://musicbrainz.org/doc/Release_Group/Type). #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum AlbumPrimaryType { @@ -256,12 +238,10 @@ impl AlbumMeta { impl AlbumInfo { pub fn new( - status: Option, primary_type: Option, secondary_types: Vec, ) -> Self { AlbumInfo { - status, primary_type, secondary_types, } @@ -294,7 +274,6 @@ impl Merge for AlbumMeta { impl Merge for AlbumInfo { fn merge_in_place(&mut self, other: Self) { - self.status = self.status.take().or(other.status); self.primary_type = self.primary_type.take().or(other.primary_type); if self.secondary_types.is_empty() { self.secondary_types = other.secondary_types; diff --git a/src/core/musichoard/database.rs b/src/core/musichoard/database.rs index 8de11a5..0d387aa 100644 --- a/src/core/musichoard/database.rs +++ b/src/core/musichoard/database.rs @@ -453,7 +453,7 @@ mod tests { use crate::{ collection::{ - album::{AlbumPrimaryType, AlbumSecondaryType, AlbumStatus}, + album::{AlbumPrimaryType, AlbumSecondaryType}, musicbrainz::MbArtistRef, }, core::{ @@ -944,7 +944,6 @@ mod tests { assert_eq!(meta.info.secondary_types, Vec::new()); let info = AlbumInfo::new( - Some(AlbumStatus::Official), Some(AlbumPrimaryType::Album), vec![AlbumSecondaryType::Live], ); diff --git a/src/core/testmod.rs b/src/core/testmod.rs index 929723a..a812f67 100644 --- a/src/core/testmod.rs +++ b/src/core/testmod.rs @@ -4,7 +4,6 @@ use std::collections::HashMap; use crate::core::collection::{ album::{ Album, AlbumId, AlbumInfo, AlbumLibId, AlbumMbRef, AlbumMeta, AlbumPrimaryType, AlbumSeq, - AlbumStatus, }, artist::{Artist, ArtistId, ArtistInfo, ArtistMbRef, ArtistMeta}, musicbrainz::{MbAlbumRef, MbArtistRef}, diff --git a/src/external/database/serde/common.rs b/src/external/database/serde/common.rs index c4c245a..1cc230e 100644 --- a/src/external/database/serde/common.rs +++ b/src/external/database/serde/common.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use crate::core::collection::{ - album::{AlbumDate, AlbumLibId, AlbumPrimaryType, AlbumSecondaryType, AlbumStatus}, + album::{AlbumDate, AlbumLibId, AlbumPrimaryType, AlbumSecondaryType}, musicbrainz::MbRefOption, }; @@ -59,32 +59,6 @@ pub enum MbRefOptionDef { None, } -#[derive(Debug, Deserialize, Serialize)] -#[serde(remote = "AlbumStatus")] -pub enum AlbumStatusDef { - Official, - Promotion, - Bootleg, - PseudoRelease, - Withdrawn, - Cancelled, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct SerdeAlbumStatus(#[serde(with = "AlbumStatusDef")] AlbumStatus); - -impl From for AlbumStatus { - fn from(value: SerdeAlbumStatus) -> Self { - value.0 - } -} - -impl From for SerdeAlbumStatus { - fn from(value: AlbumStatus) -> Self { - SerdeAlbumStatus(value) - } -} - #[derive(Debug, Deserialize, Serialize)] #[serde(remote = "AlbumPrimaryType")] pub enum AlbumPrimaryTypeDef { diff --git a/src/external/database/serde/deserialize.rs b/src/external/database/serde/deserialize.rs index f73d46c..182c9c6 100644 --- a/src/external/database/serde/deserialize.rs +++ b/src/external/database/serde/deserialize.rs @@ -11,7 +11,7 @@ use crate::{ }, external::database::serde::common::{ MbRefOptionDef, SerdeAlbumDate, SerdeAlbumLibId, SerdeAlbumPrimaryType, - SerdeAlbumSecondaryType, SerdeAlbumStatus, + SerdeAlbumSecondaryType, }, }; @@ -46,7 +46,6 @@ pub struct DeserializeAlbum { date: SerdeAlbumDate, seq: u8, musicbrainz: DeserializeMbRefOption, - status: Option, primary_type: Option, secondary_types: Vec, } @@ -139,7 +138,6 @@ impl From for Album { date: album.date.into(), seq: AlbumSeq(album.seq), info: AlbumInfo { - status: album.status.map(Into::into), primary_type: album.primary_type.map(Into::into), secondary_types: album.secondary_types.into_iter().map(Into::into).collect(), }, diff --git a/src/external/database/serde/serialize.rs b/src/external/database/serde/serialize.rs index a794aa7..a88657f 100644 --- a/src/external/database/serde/serialize.rs +++ b/src/external/database/serde/serialize.rs @@ -7,7 +7,7 @@ use crate::{ core::collection::{album::Album, artist::Artist, musicbrainz::IMusicBrainzRef, Collection}, external::database::serde::common::{ MbRefOptionDef, SerdeAlbumDate, SerdeAlbumLibId, SerdeAlbumPrimaryType, - SerdeAlbumSecondaryType, SerdeAlbumStatus, + SerdeAlbumSecondaryType, }, }; @@ -38,7 +38,6 @@ pub struct SerializeAlbum<'a> { date: SerdeAlbumDate, seq: u8, musicbrainz: SerializeMbRefOption<'a>, - status: Option, primary_type: Option, secondary_types: Vec, } @@ -98,7 +97,6 @@ impl<'a> From<&'a Album> for SerializeAlbum<'a> { date: album.meta.date.into(), seq: album.meta.seq.0, musicbrainz: (&album.meta.id.mb_ref).into(), - status: album.meta.info.status.map(Into::into), primary_type: album.meta.info.primary_type.map(Into::into), secondary_types: album .meta diff --git a/src/external/musicbrainz/api/mod.rs b/src/external/musicbrainz/api/mod.rs index 46e01a0..bc3cc60 100644 --- a/src/external/musicbrainz/api/mod.rs +++ b/src/external/musicbrainz/api/mod.rs @@ -4,7 +4,7 @@ use serde::{de::Visitor, Deserialize, Deserializer}; use crate::{ collection::{ - album::{AlbumDate, AlbumPrimaryType, AlbumSecondaryType, AlbumStatus}, + album::{AlbumDate, AlbumPrimaryType, AlbumSecondaryType}, musicbrainz::Mbid, Error as CollectionError, }, @@ -131,7 +131,6 @@ pub struct MbReleaseGroupMeta { pub id: Mbid, pub title: String, pub first_release_date: AlbumDate, - pub status: Option, pub primary_type: Option, pub secondary_types: Option>, } @@ -142,7 +141,6 @@ pub struct SerdeMbReleaseGroupMeta { id: SerdeMbid, title: String, first_release_date: SerdeAlbumDate, - status: Option, primary_type: Option, secondary_types: Option>, } @@ -153,7 +151,6 @@ impl From for MbReleaseGroupMeta { id: value.id.into(), title: value.title, first_release_date: value.first_release_date.into(), - status: value.status.map(Into::into), primary_type: value.primary_type.map(Into::into), secondary_types: value .secondary_types @@ -284,26 +281,6 @@ impl<'de> Deserialize<'de> for SerdeAlbumDate { } } -#[derive(Debug, Deserialize)] -#[serde(remote = "AlbumStatus", rename_all(deserialize = "kebab-case"))] -pub enum AlbumStatusDef { - Official, - Promotion, - Bootleg, - PseudoRelease, - Withdrawn, - Cancelled, -} - -#[derive(Clone, Debug, Deserialize)] -pub struct SerdeAlbumStatus(#[serde(with = "AlbumStatusDef")] AlbumStatus); - -impl From for AlbumStatus { - fn from(value: SerdeAlbumStatus) -> Self { - value.0 - } -} - #[derive(Debug, Deserialize)] #[serde(remote = "AlbumPrimaryType")] pub enum AlbumPrimaryTypeDef { diff --git a/src/testmod/full.rs b/src/testmod/full.rs index a07a5d0..4e5c1d2 100644 --- a/src/testmod/full.rs +++ b/src/testmod/full.rs @@ -36,7 +36,6 @@ macro_rules! full_collection { date: 1998.into(), seq: AlbumSeq(1), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -101,7 +100,6 @@ macro_rules! full_collection { date: (2015, 4).into(), seq: AlbumSeq(1), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -170,7 +168,6 @@ macro_rules! full_collection { date: (2003, 6, 6).into(), seq: AlbumSeq(1), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -215,7 +212,6 @@ macro_rules! full_collection { date: 2008.into(), seq: AlbumSeq(3), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -260,7 +256,6 @@ macro_rules! full_collection { date: 2009.into(), seq: AlbumSeq(2), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -303,7 +298,6 @@ macro_rules! full_collection { date: 2015.into(), seq: AlbumSeq(4), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -360,7 +354,6 @@ macro_rules! full_collection { date: 1985.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -403,7 +396,6 @@ macro_rules! full_collection { date: 2018.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -460,7 +452,6 @@ macro_rules! full_collection { date: 1995.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -503,7 +494,6 @@ macro_rules! full_collection { date: 2028.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, diff --git a/src/tui/app/machine/match_state.rs b/src/tui/app/machine/match_state.rs index 241679c..b25e669 100644 --- a/src/tui/app/machine/match_state.rs +++ b/src/tui/app/machine/match_state.rs @@ -282,7 +282,7 @@ mod tests { Sequence, }; use musichoard::collection::{ - album::{AlbumDate, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumStatus}, + album::{AlbumDate, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType}, artist::{ArtistId, ArtistMeta}, }; @@ -347,7 +347,6 @@ mod tests { AlbumMeta::new(id) .with_date(AlbumDate::new(Some(1990), Some(5), None)) .with_info(AlbumInfo::new( - Some(AlbumStatus::Official), Some(AlbumPrimaryType::Album), vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation], )) diff --git a/src/tui/lib/external/musicbrainz/api/mod.rs b/src/tui/lib/external/musicbrainz/api/mod.rs index eede4a1..acc1d4f 100644 --- a/src/tui/lib/external/musicbrainz/api/mod.rs +++ b/src/tui/lib/external/musicbrainz/api/mod.rs @@ -138,7 +138,6 @@ fn from_mb_release_group_meta(meta: MbReleaseGroupMeta) -> AlbumMeta { date: meta.first_release_date, seq: AlbumSeq::default(), info: AlbumInfo { - status: meta.status, primary_type: meta.primary_type, secondary_types: meta.secondary_types.unwrap_or_default(), }, diff --git a/src/tui/testmod.rs b/src/tui/testmod.rs index f5cb5cf..6346109 100644 --- a/src/tui/testmod.rs +++ b/src/tui/testmod.rs @@ -3,7 +3,6 @@ use std::collections::HashMap; use musichoard::collection::{ album::{ Album, AlbumId, AlbumInfo, AlbumLibId, AlbumMbRef, AlbumMeta, AlbumPrimaryType, AlbumSeq, - AlbumStatus, }, artist::{Artist, ArtistId, ArtistInfo, ArtistMbRef, ArtistMeta}, musicbrainz::{MbAlbumRef, MbArtistRef}, diff --git a/src/tui/ui/browse_state.rs b/src/tui/ui/browse_state.rs index 7047802..a99e195 100644 --- a/src/tui/ui/browse_state.rs +++ b/src/tui/ui/browse_state.rs @@ -163,7 +163,6 @@ impl<'a, 'b> AlbumState<'a, 'b> { "Title: {}\n\ Date: {}\n\ Type: {}\n\ - Status: {}\n\ Ownership: {}", album.map(|a| a.meta.id.title.as_str()).unwrap_or(""), album @@ -175,9 +174,6 @@ impl<'a, 'b> AlbumState<'a, 'b> { &a.meta.info.secondary_types )) .unwrap_or_default(), - album - .map(|a| UiDisplay::display_album_status(&a.meta.info.status)) - .unwrap_or(""), album .map(|a| UiDisplay::display_album_ownership(&a.get_ownership())) .unwrap_or("") diff --git a/src/tui/ui/display.rs b/src/tui/ui/display.rs index 32535cd..1c91792 100644 --- a/src/tui/ui/display.rs +++ b/src/tui/ui/display.rs @@ -1,7 +1,7 @@ use musichoard::collection::{ album::{ AlbumDate, AlbumId, AlbumLibId, AlbumMeta, AlbumOwnership, AlbumPrimaryType, - AlbumSecondaryType, AlbumSeq, AlbumStatus, + AlbumSecondaryType, AlbumSeq, }, artist::ArtistMeta, musicbrainz::{IMusicBrainzRef, MbRefOption}, @@ -50,20 +50,6 @@ impl UiDisplay { } } - pub fn display_album_status(value: &Option) -> &'static str { - match value { - Some(status) => match status { - AlbumStatus::Official => "Official", - AlbumStatus::Promotion => "Promotion", - AlbumStatus::Bootleg => "Bootleg", - AlbumStatus::PseudoRelease => "Pseudo-Release", - AlbumStatus::Withdrawn => "Withdrawn", - AlbumStatus::Cancelled => "Cancelled", - }, - None => "", - } - } - pub fn display_album_type( primary: &Option, secondary: &Vec, @@ -237,35 +223,6 @@ mod tests { assert_eq!(UiDisplay::display_date(&date, &AlbumSeq(5)), "1990 (5)"); } - #[test] - fn display_album_status() { - assert_eq!( - UiDisplay::display_album_status(&Some(AlbumStatus::Official)), - "Official" - ); - assert_eq!( - UiDisplay::display_album_status(&Some(AlbumStatus::Promotion)), - "Promotion" - ); - assert_eq!( - UiDisplay::display_album_status(&Some(AlbumStatus::Bootleg)), - "Bootleg" - ); - assert_eq!( - UiDisplay::display_album_status(&Some(AlbumStatus::PseudoRelease)), - "Pseudo-Release" - ); - assert_eq!( - UiDisplay::display_album_status(&Some(AlbumStatus::Withdrawn)), - "Withdrawn" - ); - assert_eq!( - UiDisplay::display_album_status(&Some(AlbumStatus::Cancelled)), - "Cancelled" - ); - assert_eq!(UiDisplay::display_album_status(&None), ""); - } - #[test] fn display_album_primary_type() { assert_eq!( diff --git a/src/tui/ui/mod.rs b/src/tui/ui/mod.rs index 5297b03..c3e3ee3 100644 --- a/src/tui/ui/mod.rs +++ b/src/tui/ui/mod.rs @@ -199,7 +199,7 @@ impl IUi for Ui { #[cfg(test)] mod tests { use musichoard::collection::{ - album::{AlbumDate, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumStatus}, + album::{AlbumDate, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType}, artist::{Artist, ArtistId, ArtistMeta}, }; @@ -361,7 +361,6 @@ mod tests { AlbumMeta::new(id) .with_date(AlbumDate::new(Some(1990), Some(5), None)) .with_info(AlbumInfo::new( - Some(AlbumStatus::Official), Some(AlbumPrimaryType::Album), vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation], )) diff --git a/tests/testlib.rs b/tests/testlib.rs index 90138c0..119042a 100644 --- a/tests/testlib.rs +++ b/tests/testlib.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use musichoard::collection::{ album::{ Album, AlbumId, AlbumInfo, AlbumLibId, AlbumMbRef, AlbumMeta, AlbumPrimaryType, - AlbumSecondaryType, AlbumSeq, AlbumStatus, + AlbumSecondaryType, AlbumSeq, }, artist::{Artist, ArtistId, ArtistInfo, ArtistMbRef, ArtistMeta}, musicbrainz::MbArtistRef, @@ -47,7 +47,6 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 2011.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -241,7 +240,6 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 2004.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Ep), secondary_types: vec![], }, @@ -325,7 +323,6 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 2008.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -497,7 +494,6 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 2001.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -681,7 +677,6 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 2011.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -798,7 +793,6 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 1984.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![], }, @@ -904,7 +898,6 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { date: 1999.into(), seq: AlbumSeq(0), info: AlbumInfo { - status: Some(AlbumStatus::Official), primary_type: Some(AlbumPrimaryType::Album), secondary_types: vec![AlbumSecondaryType::Live], }, -- 2.47.1 From 5e4baf71910efb3cd71de0a695ebd993063b6d31 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 3 Jan 2025 20:23:42 +0100 Subject: [PATCH 08/10] Remove status from tests --- src/external/database/json/testmod.rs | 20 ++++++++++---------- tests/files/database/database.json | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/external/database/json/testmod.rs b/src/external/database/json/testmod.rs index ccd7fce..04fd2b1 100644 --- a/src/external/database/json/testmod.rs +++ b/src/external/database/json/testmod.rs @@ -14,13 +14,13 @@ pub static DATABASE_JSON: &str = "{\ \"title\":\"album_title a.a\",\"lib_id\":{\"Value\":1},\ \"date\":{\"year\":1998,\"month\":null,\"day\":null},\"seq\":1,\ \"musicbrainz\":{\"Some\":\"00000000-0000-0000-0000-000000000000\"},\ - \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ + \"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title a.b\",\"lib_id\":{\"Value\":2},\ \"date\":{\"year\":2015,\"month\":4,\"day\":null},\"seq\":1,\ \"musicbrainz\":\"None\",\ - \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ + \"primary_type\":\"Album\",\"secondary_types\":[]\ }\ ]\ },\ @@ -41,25 +41,25 @@ pub static DATABASE_JSON: &str = "{\ \"title\":\"album_title b.a\",\"lib_id\":{\"Value\":3},\ \"date\":{\"year\":2003,\"month\":6,\"day\":6},\"seq\":1,\ \"musicbrainz\":\"None\",\ - \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ + \"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title b.b\",\"lib_id\":{\"Value\":4},\ \"date\":{\"year\":2008,\"month\":null,\"day\":null},\"seq\":3,\ \"musicbrainz\":{\"Some\":\"11111111-1111-1111-1111-111111111111\"},\ - \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ + \"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title b.c\",\"lib_id\":{\"Value\":5},\ \"date\":{\"year\":2009,\"month\":null,\"day\":null},\"seq\":2,\ \"musicbrainz\":{\"Some\":\"11111111-1111-1111-1111-111111111112\"},\ - \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ + \"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title b.d\",\"lib_id\":{\"Value\":6},\ \"date\":{\"year\":2015,\"month\":null,\"day\":null},\"seq\":4,\ \"musicbrainz\":\"None\",\ - \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ + \"primary_type\":\"Album\",\"secondary_types\":[]\ }\ ]\ },\ @@ -73,13 +73,13 @@ pub static DATABASE_JSON: &str = "{\ \"title\":\"album_title c.a\",\"lib_id\":{\"Value\":7},\ \"date\":{\"year\":1985,\"month\":null,\"day\":null},\"seq\":0,\ \"musicbrainz\":\"None\",\ - \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ + \"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title c.b\",\"lib_id\":{\"Value\":8},\ \"date\":{\"year\":2018,\"month\":null,\"day\":null},\"seq\":0,\ \"musicbrainz\":\"None\",\ - \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ + \"primary_type\":\"Album\",\"secondary_types\":[]\ }\ ]\ },\ @@ -93,13 +93,13 @@ pub static DATABASE_JSON: &str = "{\ \"title\":\"album_title d.a\",\"lib_id\":{\"Value\":9},\ \"date\":{\"year\":1995,\"month\":null,\"day\":null},\"seq\":0,\ \"musicbrainz\":\"None\",\ - \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ + \"primary_type\":\"Album\",\"secondary_types\":[]\ },\ {\ \"title\":\"album_title d.b\",\"lib_id\":{\"Value\":10},\ \"date\":{\"year\":2028,\"month\":null,\"day\":null},\"seq\":0,\ \"musicbrainz\":\"None\",\ - \"status\":\"Official\",\"primary_type\":\"Album\",\"secondary_types\":[]\ + \"primary_type\":\"Album\",\"secondary_types\":[]\ }\ ]\ }\ diff --git a/tests/files/database/database.json b/tests/files/database/database.json index 9d4d6f7..ccce86d 100644 --- a/tests/files/database/database.json +++ b/tests/files/database/database.json @@ -1 +1 @@ -{"V20250103":[{"name":"Аркона","sort":"Arkona","musicbrainz":{"Some":"baad262d-55ef-427a-83c7-f7530964f212"},"properties":{"Bandcamp":["https://arkonamoscow.bandcamp.com/"],"MusicButler":["https://www.musicbutler.io/artist-page/283448581"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/arkona/download-streaming-albums"]},"albums":[{"title":"Slovo","lib_id":{"Value":7},"date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":[]}]},{"name":"Eluveitie","sort":null,"musicbrainz":{"Some":"8000598a-5edb-401c-8e6d-36b167feaf38"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/269358403"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/eluveitie/download-streaming-albums"]},"albums":[{"title":"Vên [re‐recorded]","lib_id":{"Value":1},"date":{"year":2004,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Ep","secondary_types":[]},{"title":"Slania","lib_id":{"Value":2},"date":{"year":2008,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":[]}]},{"name":"Frontside","sort":null,"musicbrainz":{"Some":"3a901353-fccd-4afd-ad01-9c03f451b490"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/826588800"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/frontside/download-streaming-albums"]},"albums":[{"title":"…nasze jest królestwo, potęga i chwała na wieki…","lib_id":{"Value":3},"date":{"year":2001,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":[]}]},{"name":"Heaven’s Basement","sort":"Heaven’s Basement","musicbrainz":{"Some":"c2c4d56a-d599-4a18-bd2f-ae644e2198cc"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/291158685"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums"]},"albums":[{"title":"Paper Plague","lib_id":"Singleton","date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":null,"primary_type":null,"secondary_types":[]},{"title":"Unbreakable","lib_id":{"Value":4},"date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":[]}]},{"name":"Metallica","sort":null,"musicbrainz":{"Some":"65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/3996865"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/metallica/download-streaming-albums"]},"albums":[{"title":"Ride the Lightning","lib_id":{"Value":5},"date":{"year":1984,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":[]},{"title":"S&M","lib_id":{"Value":6},"date":{"year":1999,"month":null,"day":null},"seq":0,"musicbrainz":"None","status":"Official","primary_type":"Album","secondary_types":["Live"]}]}]} \ No newline at end of file +{"V20250103":[{"name":"Аркона","sort":"Arkona","musicbrainz":{"Some":"baad262d-55ef-427a-83c7-f7530964f212"},"properties":{"Bandcamp":["https://arkonamoscow.bandcamp.com/"],"MusicButler":["https://www.musicbutler.io/artist-page/283448581"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/arkona/download-streaming-albums"]},"albums":[{"title":"Slovo","lib_id":{"Value":7},"date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":[]}]},{"name":"Eluveitie","sort":null,"musicbrainz":{"Some":"8000598a-5edb-401c-8e6d-36b167feaf38"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/269358403"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/eluveitie/download-streaming-albums"]},"albums":[{"title":"Vên [re‐recorded]","lib_id":{"Value":1},"date":{"year":2004,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Ep","secondary_types":[]},{"title":"Slania","lib_id":{"Value":2},"date":{"year":2008,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":[]}]},{"name":"Frontside","sort":null,"musicbrainz":{"Some":"3a901353-fccd-4afd-ad01-9c03f451b490"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/826588800"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/frontside/download-streaming-albums"]},"albums":[{"title":"…nasze jest królestwo, potęga i chwała na wieki…","lib_id":{"Value":3},"date":{"year":2001,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":[]}]},{"name":"Heaven’s Basement","sort":"Heaven’s Basement","musicbrainz":{"Some":"c2c4d56a-d599-4a18-bd2f-ae644e2198cc"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/291158685"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums"]},"albums":[{"title":"Paper Plague","lib_id":"Singleton","date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":null,"secondary_types":[]},{"title":"Unbreakable","lib_id":{"Value":4},"date":{"year":2011,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":[]}]},{"name":"Metallica","sort":null,"musicbrainz":{"Some":"65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab"},"properties":{"MusicButler":["https://www.musicbutler.io/artist-page/3996865"],"Qobuz":["https://www.qobuz.com/nl-nl/interpreter/metallica/download-streaming-albums"]},"albums":[{"title":"Ride the Lightning","lib_id":{"Value":5},"date":{"year":1984,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":[]},{"title":"S&M","lib_id":{"Value":6},"date":{"year":1999,"month":null,"day":null},"seq":0,"musicbrainz":"None","primary_type":"Album","secondary_types":["Live"]}]}]} \ No newline at end of file -- 2.47.1 From 493b8a3928436dd4fe8128d4f812281d67069cc4 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 3 Jan 2025 20:42:05 +0100 Subject: [PATCH 09/10] More ergonomic code --- src/external/musicbrainz/api/browse.rs | 34 +++++++++++---------- src/tui/lib/external/musicbrainz/api/mod.rs | 2 +- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/external/musicbrainz/api/browse.rs b/src/external/musicbrainz/api/browse.rs index 3a9d9cd..e662d0f 100644 --- a/src/external/musicbrainz/api/browse.rs +++ b/src/external/musicbrainz/api/browse.rs @@ -40,18 +40,11 @@ impl MusicBrainzClient { ) -> Result { let entity = &request.entity; let mbid = request.mbid.uuid().as_hyphenated(); - let status = match request.release_group_status { - Some(ref value) => { - let value_str = match value { - BrowseReleaseGroupRequestReleaseGroupStatus::WebsiteDefault => { - "website-default" - } - BrowseReleaseGroupRequestReleaseGroupStatus::All => "all", - }; - format!("&release-group-status={value_str}") - } - None => String::from(""), - }; + let status = request + .release_group_status + .as_ref() + .map(|s| format!("&release-group-status={s}")) + .unwrap_or_default(); let page = ApiDisplay::format_page_settings(paging); let url = format!("{MB_BASE_URL}/release-group?{entity}={mbid}{status}{page}"); @@ -71,15 +64,24 @@ enum BrowseReleaseGroupRequestEntity { Artist, } +impl fmt::Display for BrowseReleaseGroupRequestEntity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Artist => write!(f, "artist"), + } + } +} + enum BrowseReleaseGroupRequestReleaseGroupStatus { WebsiteDefault, All, } -impl fmt::Display for BrowseReleaseGroupRequestEntity { +impl fmt::Display for BrowseReleaseGroupRequestReleaseGroupStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - BrowseReleaseGroupRequestEntity::Artist => write!(f, "artist"), + Self::WebsiteDefault => write!(f, "website-default"), + Self::All => write!(f, "all"), } } } @@ -93,13 +95,13 @@ impl<'a> BrowseReleaseGroupRequest<'a> { } } - pub fn status_website_default(mut self) -> Self { + pub fn filter_status_website_default(mut self) -> Self { self.release_group_status = Some(BrowseReleaseGroupRequestReleaseGroupStatus::WebsiteDefault); self } - pub fn status_all(mut self) -> Self { + pub fn filter_status_all(mut self) -> Self { self.release_group_status = Some(BrowseReleaseGroupRequestReleaseGroupStatus::All); self } diff --git a/src/tui/lib/external/musicbrainz/api/mod.rs b/src/tui/lib/external/musicbrainz/api/mod.rs index acc1d4f..d648b8d 100644 --- a/src/tui/lib/external/musicbrainz/api/mod.rs +++ b/src/tui/lib/external/musicbrainz/api/mod.rs @@ -99,7 +99,7 @@ impl IMusicBrainz for MusicBrainz { artist: &Mbid, paging: &mut Option, ) -> Result>, Error> { - let request = BrowseReleaseGroupRequest::artist(artist).status_website_default(); + let request = BrowseReleaseGroupRequest::artist(artist).filter_status_website_default(); let page = paging.take().unwrap_or_default(); let mb_response = self.client.browse_release_group(&request, &page)?; -- 2.47.1 From b84be9abcd9738d9ba6fcb9b11b50cfb38173e2d Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 3 Jan 2025 20:56:10 +0100 Subject: [PATCH 10/10] Complete unit tests --- src/external/musicbrainz/api/browse.rs | 48 +++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/external/musicbrainz/api/browse.rs b/src/external/musicbrainz/api/browse.rs index e662d0f..2a3125d 100644 --- a/src/external/musicbrainz/api/browse.rs +++ b/src/external/musicbrainz/api/browse.rs @@ -33,11 +33,10 @@ impl BrowseReleaseGroupPage { pub type SerdeBrowseReleaseGroupPage = BrowseReleaseGroupPage; impl MusicBrainzClient { - pub fn browse_release_group( - &mut self, + fn browse_release_group_url( request: &BrowseReleaseGroupRequest, paging: &PageSettings, - ) -> Result { + ) -> String { let entity = &request.entity; let mbid = request.mbid.uuid().as_hyphenated(); let status = request @@ -47,8 +46,15 @@ impl MusicBrainzClient { .unwrap_or_default(); let page = ApiDisplay::format_page_settings(paging); - let url = format!("{MB_BASE_URL}/release-group?{entity}={mbid}{status}{page}"); + format!("{MB_BASE_URL}/release-group?{entity}={mbid}{status}{page}") + } + pub fn browse_release_group( + &mut self, + request: &BrowseReleaseGroupRequest, + paging: &PageSettings, + ) -> Result { + let url = Self::browse_release_group_url(request, paging); let response: DeserializeBrowseReleaseGroupResponse = self.http.get(&url)?; Ok(response.into()) } @@ -207,4 +213,38 @@ mod tests { let result = client.browse_release_group(&request, &paging).unwrap(); assert_eq!(result, response); } + + #[test] + fn browse_release_group_filter_status() { + type Client = MusicBrainzClient; + let mbid_str = "00000000-0000-0000-0000-000000000000"; + let mbid: Mbid = mbid_str.try_into().unwrap(); + let paging = PageSettings::with_max_limit(); + + let request = BrowseReleaseGroupRequest::artist(&mbid); + let url = format!( + "https://musicbrainz.org/ws/2/release-group\ + ?artist={mbid_str}\ + &limit={MB_MAX_PAGE_LIMIT}", + ); + assert_eq!(Client::browse_release_group_url(&request, &paging), url); + + let request = BrowseReleaseGroupRequest::artist(&mbid).filter_status_website_default(); + let url = format!( + "https://musicbrainz.org/ws/2/release-group\ + ?artist={mbid_str}\ + &release-group-status=website-default\ + &limit={MB_MAX_PAGE_LIMIT}", + ); + assert_eq!(Client::browse_release_group_url(&request, &paging), url); + + let request = BrowseReleaseGroupRequest::artist(&mbid).filter_status_all(); + let url = format!( + "https://musicbrainz.org/ws/2/release-group\ + ?artist={mbid_str}\ + &release-group-status=all\ + &limit={MB_MAX_PAGE_LIMIT}", + ); + assert_eq!(Client::browse_release_group_url(&request, &paging), url); + } } -- 2.47.1