Provide a keyboard shortcut to pull all release groups of an artist #233
@ -258,7 +258,9 @@ impl Merge for AlbumInfo {
|
||||
fn merge_in_place(&mut self, other: Self) {
|
||||
self.musicbrainz = self.musicbrainz.take().or(other.musicbrainz);
|
||||
self.primary_type = self.primary_type.take().or(other.primary_type);
|
||||
self.secondary_types.merge_in_place(other.secondary_types);
|
||||
if self.secondary_types.is_empty() {
|
||||
self.secondary_types = other.secondary_types;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ pub trait IMusicHoardBasePrivate {
|
||||
artist_id: &ArtistId,
|
||||
) -> Result<&'a mut Artist, Error>;
|
||||
|
||||
fn get_album<'a>(artist: &'a mut Artist, album_id: &AlbumId) -> Option<&'a Album>;
|
||||
fn get_album_mut<'a>(artist: &'a mut Artist, album_id: &AlbumId) -> Option<&'a mut Album>;
|
||||
fn get_album_mut_or_err<'a>(
|
||||
artist: &'a mut Artist,
|
||||
@ -79,6 +80,10 @@ impl<Database, Library> IMusicHoardBasePrivate for MusicHoard<Database, Library>
|
||||
})
|
||||
}
|
||||
|
||||
fn get_album<'a>(artist: &'a mut Artist, album_id: &AlbumId) -> Option<&'a Album> {
|
||||
artist.albums.iter().find(|a| &a.meta.id == album_id)
|
||||
}
|
||||
|
||||
fn get_album_mut<'a>(artist: &'a mut Artist, album_id: &AlbumId) -> Option<&'a mut Album> {
|
||||
artist.albums.iter_mut().find(|a| &a.meta.id == album_id)
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
use std::mem;
|
||||
|
||||
use crate::{
|
||||
collection::{album::AlbumInfo, artist::ArtistInfo, merge::Merge},
|
||||
collection::{
|
||||
album::{AlbumInfo, AlbumMeta},
|
||||
artist::ArtistInfo,
|
||||
merge::Merge,
|
||||
},
|
||||
core::{
|
||||
collection::{
|
||||
album::{Album, AlbumId, AlbumSeq},
|
||||
@ -57,6 +61,17 @@ pub trait IMusicHoardDatabase {
|
||||
property: S,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
fn add_album<ArtistIdRef: AsRef<ArtistId>>(
|
||||
&mut self,
|
||||
artist_id: ArtistIdRef,
|
||||
album_meta: AlbumMeta,
|
||||
) -> Result<(), Error>;
|
||||
fn remove_album<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: ArtistIdRef,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
fn set_album_seq<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: ArtistIdRef,
|
||||
@ -68,15 +83,15 @@ pub trait IMusicHoardDatabase {
|
||||
artist_id: ArtistIdRef,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error>;
|
||||
fn merge_album_info<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
fn merge_album_info<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
artist_id: ArtistIdRef,
|
||||
album_id: AlbumIdRef,
|
||||
info: AlbumInfo,
|
||||
) -> Result<(), Error>;
|
||||
fn clear_album_info<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
fn clear_album_info<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
artist_id: ArtistIdRef,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error>;
|
||||
}
|
||||
@ -194,6 +209,39 @@ impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
|
||||
})
|
||||
}
|
||||
|
||||
fn add_album<ArtistIdRef: AsRef<ArtistId>>(
|
||||
&mut self,
|
||||
artist_id: ArtistIdRef,
|
||||
album_meta: AlbumMeta,
|
||||
) -> Result<(), Error> {
|
||||
let album = Album {
|
||||
meta: album_meta,
|
||||
tracks: vec![],
|
||||
};
|
||||
self.update_artist(artist_id.as_ref(), |artist| {
|
||||
if Self::get_album(artist, &album.meta.id).is_none() {
|
||||
artist.albums.push(album);
|
||||
artist.albums.sort_unstable();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn remove_album<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: ArtistIdRef,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist(artist_id.as_ref(), |artist| {
|
||||
let index_opt = artist
|
||||
.albums
|
||||
.iter()
|
||||
.position(|a| &a.meta.id == album_id.as_ref());
|
||||
if let Some(index) = index_opt {
|
||||
artist.albums.remove(index);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn set_album_seq<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: ArtistIdRef,
|
||||
|
@ -13,10 +13,12 @@ use musichoard::collection::{
|
||||
use crate::tui::{
|
||||
app::{
|
||||
machine::{match_state::MatchState, App, AppInner, AppMachine},
|
||||
selection::KeySelection,
|
||||
AppPublicState, AppState, Category, IAppEventFetch, IAppInteractFetch,
|
||||
},
|
||||
lib::interface::musicbrainz::daemon::{
|
||||
Error as DaemonError, IMbJobSender, MbApiResult, MbParams, MbReturn, ResultSender,
|
||||
EntityList, Error as DaemonError, IMbJobSender, MbApiResult, MbParams, MbReturn,
|
||||
ResultSender,
|
||||
},
|
||||
};
|
||||
|
||||
@ -139,14 +141,19 @@ impl AppMachine<FetchState> {
|
||||
Ok(requests)
|
||||
}
|
||||
|
||||
pub fn app_fetch_next(inner: AppInner, mut fetch: FetchState) -> App {
|
||||
pub fn app_fetch_next(mut inner: AppInner, mut fetch: FetchState) -> App {
|
||||
loop {
|
||||
let app: App = match fetch.try_recv() {
|
||||
Ok(fetch_result) => match fetch_result {
|
||||
Ok(MbReturn::Match(next_match)) => {
|
||||
AppMachine::match_state(inner, MatchState::new(next_match, fetch)).into()
|
||||
}
|
||||
Ok(MbReturn::Fetch(_)) => continue,
|
||||
Ok(MbReturn::Fetch(list)) => {
|
||||
match Self::apply_fetch_results(&mut inner, list) {
|
||||
Ok(()) => continue,
|
||||
Err(err) => AppMachine::error_state(inner, err.to_string()).into(),
|
||||
}
|
||||
}
|
||||
Err(fetch_err) => {
|
||||
AppMachine::error_state(inner, format!("fetch failed: {fetch_err}")).into()
|
||||
}
|
||||
@ -164,6 +171,52 @@ impl AppMachine<FetchState> {
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_fetch_results(
|
||||
inner: &mut AppInner,
|
||||
list: EntityList,
|
||||
) -> Result<(), musichoard::Error> {
|
||||
match list {
|
||||
EntityList::Album(new_albums) => {
|
||||
let coll = inner.music_hoard.get_collection();
|
||||
let artist_state = inner.selection.state_artist(coll).unwrap();
|
||||
|
||||
let artist = &coll[artist_state.index];
|
||||
let artist_id = &coll[artist_state.index].meta.id.clone();
|
||||
let old_albums = &artist.albums;
|
||||
|
||||
let mut to_be_added = vec![];
|
||||
for new in new_albums.into_iter() {
|
||||
let mut exists = false;
|
||||
for old in old_albums.iter() {
|
||||
if matches!(old.meta.info.musicbrainz, MbRefOption::Some(_)) {
|
||||
if new.info.musicbrainz == old.meta.info.musicbrainz {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !exists {
|
||||
to_be_added.push(new);
|
||||
}
|
||||
}
|
||||
|
||||
let previous =
|
||||
KeySelection::get(inner.music_hoard.get_collection(), &inner.selection);
|
||||
|
||||
for new in to_be_added.into_iter() {
|
||||
inner.music_hoard.add_album(&artist_id, new)?;
|
||||
}
|
||||
|
||||
inner
|
||||
.selection
|
||||
.select_by_id(inner.music_hoard.get_collection(), previous);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn app_lookup_artist(
|
||||
inner: AppInner,
|
||||
fetch: FetchState,
|
||||
|
@ -3,7 +3,7 @@ pub mod interface;
|
||||
|
||||
use musichoard::{
|
||||
collection::{
|
||||
album::{AlbumId, AlbumInfo},
|
||||
album::{AlbumId, AlbumInfo, AlbumMeta},
|
||||
artist::{ArtistId, ArtistInfo},
|
||||
Collection,
|
||||
},
|
||||
@ -20,6 +20,12 @@ pub trait IMusicHoard {
|
||||
fn reload_database(&mut self) -> Result<(), musichoard::Error>;
|
||||
fn get_collection(&self) -> &Collection;
|
||||
|
||||
fn add_album(
|
||||
&mut self,
|
||||
artist_id: &ArtistId,
|
||||
album_meta: AlbumMeta,
|
||||
) -> Result<(), musichoard::Error>;
|
||||
|
||||
fn merge_artist_info(
|
||||
&mut self,
|
||||
id: &ArtistId,
|
||||
@ -47,6 +53,14 @@ impl<Database: IDatabase, Library: ILibrary> IMusicHoard for MusicHoard<Database
|
||||
<Self as IMusicHoardBase>::get_collection(self)
|
||||
}
|
||||
|
||||
fn add_album(
|
||||
&mut self,
|
||||
artist_id: &ArtistId,
|
||||
album_meta: AlbumMeta,
|
||||
) -> Result<(), musichoard::Error> {
|
||||
<Self as IMusicHoardDatabase>::add_album(self, artist_id, album_meta)
|
||||
}
|
||||
|
||||
fn merge_artist_info(
|
||||
&mut self,
|
||||
id: &ArtistId,
|
||||
|
Loading…
x
Reference in New Issue
Block a user