Provide a keyboard shortcut to pull all release groups of an artist #233

Merged
wojtek merged 14 commits from 160---provide-a-keyboard-shortcut-to-pull-all-release-groups-of-an-artist into main 2024-12-30 23:42:20 +01:00
5 changed files with 103 additions and 48 deletions
Showing only changes of commit 6464f8300d - Show all commits

View File

@ -144,17 +144,26 @@ impl AlbumStatus {
} }
impl Album { impl Album {
pub fn new<Id: Into<AlbumId>, Date: Into<AlbumDate>>( pub fn new<Id: Into<AlbumId>>(id: Id) -> Self {
id: Id, Album {
date: Date, meta: AlbumMeta::new(id),
tracks: vec![],
}
}
pub fn with_date<Date: Into<AlbumDate>>(mut self, date: Date) -> Self {
self.meta.date = date.into();
self
}
pub fn with_type<Id: Into<AlbumId>, Date: Into<AlbumDate>>(
mut self,
primary_type: Option<AlbumPrimaryType>, primary_type: Option<AlbumPrimaryType>,
secondary_types: Vec<AlbumSecondaryType>, secondary_types: Vec<AlbumSecondaryType>,
) -> Self { ) -> Self {
let info = AlbumInfo::new(MbRefOption::None, primary_type, secondary_types); self.meta.info.primary_type = primary_type;
Album { self.meta.info.secondary_types = secondary_types;
meta: AlbumMeta::new(id, date, info), self
tracks: vec![],
}
} }
pub fn get_status(&self) -> AlbumStatus { pub fn get_status(&self) -> AlbumStatus {
@ -183,19 +192,25 @@ impl Merge for Album {
} }
impl AlbumMeta { impl AlbumMeta {
pub fn new<Id: Into<AlbumId>, Date: Into<AlbumDate>>( pub fn new<Id: Into<AlbumId>>(id: Id) -> Self {
id: Id,
date: Date,
info: AlbumInfo,
) -> Self {
AlbumMeta { AlbumMeta {
id: id.into(), id: id.into(),
date: date.into(), date: AlbumDate::default(),
seq: AlbumSeq::default(), seq: AlbumSeq::default(),
info, info: AlbumInfo::default(),
} }
} }
pub fn with_date<Date: Into<AlbumDate>>(mut self, date: Date) -> Self {
self.date = date.into();
self
}
pub fn with_info(mut self, info: AlbumInfo) -> Self {
self.info = info;
self
}
pub fn get_sort_key(&self) -> (&AlbumDate, &AlbumSeq, &AlbumId) { pub fn get_sort_key(&self) -> (&AlbumDate, &AlbumSeq, &AlbumId) {
(&self.date, &self.seq, &self.id) (&self.date, &self.seq, &self.id)
} }
@ -313,13 +328,13 @@ mod tests {
let album_id_1 = AlbumId { let album_id_1 = AlbumId {
title: String::from("album z"), title: String::from("album z"),
}; };
let mut album_1 = Album::new(album_id_1, date.clone(), None, vec![]); let mut album_1 = Album::new(album_id_1).with_date(date.clone());
album_1.meta.set_seq(AlbumSeq(1)); album_1.meta.set_seq(AlbumSeq(1));
let album_id_2 = AlbumId { let album_id_2 = AlbumId {
title: String::from("album a"), title: String::from("album a"),
}; };
let mut album_2 = Album::new(album_id_2, date.clone(), None, vec![]); let mut album_2 = Album::new(album_id_2).with_date(date.clone());
album_2.meta.set_seq(AlbumSeq(2)); album_2.meta.set_seq(AlbumSeq(2));
assert_ne!(album_1, album_2); assert_ne!(album_1, album_2);
@ -329,7 +344,7 @@ mod tests {
#[test] #[test]
fn set_clear_seq() { fn set_clear_seq() {
let mut album = Album::new("An album", AlbumDate::default(), None, vec![]); let mut album = Album::new("An album");
assert_eq!(album.meta.seq, AlbumSeq(0)); assert_eq!(album.meta.seq, AlbumSeq(0));

View File

@ -392,7 +392,7 @@ mod tests {
musicbrainz::{MbArtistRef, MbRefOption}, musicbrainz::{MbArtistRef, MbRefOption},
}, },
core::{ core::{
collection::{album::AlbumDate, artist::ArtistId}, collection::artist::ArtistId,
interface::database::{self, MockIDatabase}, interface::database::{self, MockIDatabase},
musichoard::{base::IMusicHoardBase, NoLibrary}, musichoard::{base::IMusicHoardBase, NoLibrary},
testmod::FULL_COLLECTION, testmod::FULL_COLLECTION,
@ -652,6 +652,62 @@ mod tests {
assert!(music_hoard.collection[0].meta.info.properties.is_empty()); assert!(music_hoard.collection[0].meta.info.properties.is_empty());
} }
#[test]
fn album_new_delete() {
let album_id = AlbumId::new("an album");
let album_meta = AlbumMeta::new(album_id.clone());
let album_id_2 = AlbumId::new("another album");
let album_meta_2 = AlbumMeta::new(album_id_2);
let collection = FULL_COLLECTION.to_owned();
let artist_id = collection[0].meta.id.clone();
let mut with_album = collection.clone();
with_album[0].albums.push(Album::new(album_id));
with_album[0].albums.sort_unstable();
let mut database = MockIDatabase::new();
let mut seq = Sequence::new();
database
.expect_load()
.times(1)
.times(1)
.in_sequence(&mut seq)
.returning(|| Ok(FULL_COLLECTION.to_owned()));
database
.expect_save()
.times(1)
.in_sequence(&mut seq)
.with(predicate::eq(with_album.clone()))
.returning(|_| Ok(()));
database
.expect_save()
.times(1)
.in_sequence(&mut seq)
.with(predicate::eq(collection.clone()))
.returning(|_| Ok(()));
let mut music_hoard = MusicHoard::database(database).unwrap();
assert_eq!(music_hoard.collection, collection);
assert!(music_hoard
.add_album(&artist_id, album_meta.clone())
.is_ok());
assert_eq!(music_hoard.collection, with_album);
assert!(music_hoard
.add_album(&artist_id, album_meta.clone())
.is_ok());
assert_eq!(music_hoard.collection, with_album);
assert!(music_hoard
.remove_album(&artist_id, &album_meta_2.id)
.is_ok());
assert_eq!(music_hoard.collection, with_album);
assert!(music_hoard.remove_album(&artist_id, &album_meta.id).is_ok());
assert_eq!(music_hoard.collection, collection);
}
#[test] #[test]
fn set_clear_album_seq() { fn set_clear_album_seq() {
let mut database = MockIDatabase::new(); let mut database = MockIDatabase::new();
@ -661,12 +717,7 @@ mod tests {
let album_id_2 = AlbumId::new("another album"); let album_id_2 = AlbumId::new("another album");
let mut database_result = vec![Artist::new(artist_id.clone())]; let mut database_result = vec![Artist::new(artist_id.clone())];
database_result[0].albums.push(Album::new( database_result[0].albums.push(Album::new(album_id.clone()));
album_id.clone(),
AlbumDate::default(),
None,
vec![],
));
database database
.expect_load() .expect_load()
@ -706,12 +757,7 @@ mod tests {
let album_id_2 = AlbumId::new("another album"); let album_id_2 = AlbumId::new("another album");
let mut database_result = vec![Artist::new(artist_id.clone())]; let mut database_result = vec![Artist::new(artist_id.clone())];
database_result[0].albums.push(Album::new( database_result[0].albums.push(Album::new(album_id.clone()));
album_id.clone(),
AlbumDate::default(),
None,
vec![],
));
database database
.expect_load() .expect_load()

View File

@ -109,7 +109,7 @@ impl<Database, Library: ILibrary> MusicHoard<Database, Library> {
{ {
Some(album) => album.tracks.push(track), Some(album) => album.tracks.push(track),
None => { None => {
let mut album = Album::new(album_id, album_date, None, vec![]); let mut album = Album::new(album_id).with_date(album_date);
album.tracks.push(track); album.tracks.push(track);
artist.albums.push(album); artist.albums.push(album);
} }

View File

@ -319,15 +319,13 @@ mod tests {
} }
fn album_meta(id: AlbumId) -> AlbumMeta { fn album_meta(id: AlbumId) -> AlbumMeta {
AlbumMeta::new( AlbumMeta::new(id)
id, .with_date(AlbumDate::new(Some(1990), Some(5), None))
AlbumDate::new(Some(1990), Some(5), None), .with_info(AlbumInfo::new(
AlbumInfo::new(
MbRefOption::Some(mbid().into()), MbRefOption::Some(mbid().into()),
Some(AlbumPrimaryType::Album), Some(AlbumPrimaryType::Album),
vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation], vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation],
), ))
)
} }
fn album_match() -> EntityMatches { fn album_match() -> EntityMatches {
@ -625,7 +623,7 @@ mod tests {
fn select_manual_input_album() { fn select_manual_input_album() {
let mut mb_job_sender = MockIMbJobSender::new(); let mut mb_job_sender = MockIMbJobSender::new();
let artist_id = ArtistId::new("Artist"); let artist_id = ArtistId::new("Artist");
let album = AlbumMeta::new("Album", 1990, AlbumInfo::default()); let album = AlbumMeta::new("Album").with_date(1990);
let requests = VecDeque::from([MbParams::lookup_release_group( let requests = VecDeque::from([MbParams::lookup_release_group(
artist_id.clone(), artist_id.clone(),
album.id.clone(), album.id.clone(),

View File

@ -289,9 +289,7 @@ mod tests {
#[test] #[test]
fn empty_album() { fn empty_album() {
let mut artists: Vec<Artist> = vec![Artist::new(ArtistId::new("An artist"))]; let mut artists: Vec<Artist> = vec![Artist::new(ArtistId::new("An artist"))];
artists[0] artists[0].albums.push(Album::new("An album"));
.albums
.push(Album::new("An album", AlbumDate::default(), None, vec![]));
let mut selection = Selection::new(&artists); let mut selection = Selection::new(&artists);
draw_test_suite(&artists, &mut selection); draw_test_suite(&artists, &mut selection);
@ -361,15 +359,13 @@ mod tests {
} }
fn album_meta(id: AlbumId) -> AlbumMeta { fn album_meta(id: AlbumId) -> AlbumMeta {
AlbumMeta::new( AlbumMeta::new(id)
id, .with_date(AlbumDate::new(Some(1990), Some(5), None))
AlbumDate::new(Some(1990), Some(5), None), .with_info(AlbumInfo::new(
AlbumInfo::new(
MbRefOption::None, MbRefOption::None,
Some(AlbumPrimaryType::Album), Some(AlbumPrimaryType::Album),
vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation], vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation],
), ))
)
} }
fn album_matches() -> EntityMatches { fn album_matches() -> EntityMatches {