From 011a999f28b5d66caef6d9b492b809bb6e31a923 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Sun, 29 Sep 2024 12:20:07 +0200 Subject: [PATCH] Feature implemented --- src/tui/app/machine/fetch_state.rs | 58 +++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/src/tui/app/machine/fetch_state.rs b/src/tui/app/machine/fetch_state.rs index 74c9b2c..534bd3e 100644 --- a/src/tui/app/machine/fetch_state.rs +++ b/src/tui/app/machine/fetch_state.rs @@ -1,5 +1,6 @@ use std::{ collections::VecDeque, + slice, sync::mpsc::{self, TryRecvError}, }; @@ -12,7 +13,7 @@ use musichoard::collection::{ use crate::tui::{ app::{ machine::{match_state::MatchState, App, AppInner, AppMachine}, - AppPublicState, AppState, IAppEventFetch, IAppInteractFetch, + AppPublicState, AppState, Category, IAppEventFetch, IAppInteractFetch, }, lib::interface::musicbrainz::daemon::{ Error as DaemonError, IMbJobSender, MbApiResult, MbParams, ResultSender, @@ -68,16 +69,42 @@ impl AppMachine { fn app_fetch_new(inner: AppInner) -> App { let coll = inner.music_hoard.get_collection(); + let artist = match inner.selection.state_artist(coll) { Some(artist_state) => &coll[artist_state.index], None => { - return AppMachine::error_state(inner, "cannot fetch: no artist selected").into() + let err = "cannot fetch artist: no artist selected"; + return AppMachine::error_state(inner, err).into(); } }; let (fetch_tx, fetch_rx) = mpsc::channel::(); let fetch = FetchState::new(fetch_rx); - match Self::submit_fetch_job(&*inner.musicbrainz, fetch_tx, artist) { + + let mb = &*inner.musicbrainz; + let result = match inner.selection.category() { + Category::Artist => Self::submit_search_artist_job(mb, fetch_tx, artist), + _ => { + let arid = match artist.meta.info.musicbrainz { + MbRefOption::Some(ref mbref) => mbref, + _ => { + let err = "cannot fetch album: artist has no MBID"; + return AppMachine::error_state(inner, err).into(); + } + }; + let album = match inner.selection.state_album(coll) { + Some(album_state) => &artist.albums[album_state.index], + None => { + let err = "cannot fetch album: no album selected"; + return AppMachine::error_state(inner, err).into(); + } + }; + let artist_id = &artist.meta.id; + Self::submit_search_release_group_job(mb, fetch_tx, artist_id, arid, album) + } + }; + + match result { Ok(()) => AppMachine::fetch_state(inner, fetch).into(), Err(FetchError::NothingToFetch) => AppMachine::browse_state(inner).into(), Err(FetchError::SubmitError(daemon_err)) => { @@ -144,17 +171,17 @@ impl AppMachine { Self::app_fetch_next(inner, fetch) } - fn submit_fetch_job( + fn submit_search_artist_job( musicbrainz: &dyn IMbJobSender, result_sender: ResultSender, artist: &Artist, ) -> Result<(), FetchError> { let requests = match artist.meta.info.musicbrainz { MbRefOption::Some(ref arid) => { - Self::fetch_albums_requests(&artist.meta.id, arid, &artist.albums) + Self::search_albums_requests(&artist.meta.id, arid, &artist.albums) } MbRefOption::CannotHaveMbid => VecDeque::new(), - MbRefOption::None => Self::fetch_artist_request(&artist.meta), + MbRefOption::None => Self::search_artist_request(&artist.meta), }; if requests.is_empty() { return Err(FetchError::NothingToFetch); @@ -162,7 +189,22 @@ impl AppMachine { Ok(musicbrainz.submit_background_job(result_sender, requests)?) } - fn fetch_albums_requests( + fn submit_search_release_group_job( + musicbrainz: &dyn IMbJobSender, + result_sender: ResultSender, + artist_id: &ArtistId, + artist_mbid: &MbArtistRef, + album: &Album, + ) -> Result<(), FetchError> { + if !matches!(album.meta.info.musicbrainz, MbRefOption::None) { + return Err(FetchError::NothingToFetch); + } + let requests = + Self::search_albums_requests(&artist_id, &artist_mbid, slice::from_ref(album)); + Ok(musicbrainz.submit_background_job(result_sender, requests)?) + } + + fn search_albums_requests( artist: &ArtistId, arid: &MbArtistRef, albums: &[Album], @@ -177,7 +219,7 @@ impl AppMachine { .collect() } - fn fetch_artist_request(meta: &ArtistMeta) -> VecDeque { + fn search_artist_request(meta: &ArtistMeta) -> VecDeque { VecDeque::from([MbParams::search_artist(meta.clone())]) }