From 028d77928ad2ee2df3e027f96dc619c09a7d6307 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Sun, 6 Oct 2024 17:14:28 +0200 Subject: [PATCH] Submit browse jobs --- src/tui/app/machine/fetch_state.rs | 97 +++++++++++++++++++----------- 1 file changed, 62 insertions(+), 35 deletions(-) diff --git a/src/tui/app/machine/fetch_state.rs b/src/tui/app/machine/fetch_state.rs index 563ace4..7b8ef79 100644 --- a/src/tui/app/machine/fetch_state.rs +++ b/src/tui/app/machine/fetch_state.rs @@ -27,6 +27,11 @@ pub struct FetchState { fetch_rx: Option, } +struct SubmitJob { + fetch: FetchState, + requests: VecDeque, +} + macro_rules! try_recv_mb_api_receiver { ($rx:expr) => { if let Some(rx) = &($rx) { @@ -78,24 +83,62 @@ impl AppMachine { } fn app_fetch_new(inner: AppInner) -> App { - let requests = match Self::search_job(&inner) { - Ok(requests) => requests, + let (tx, rx) = mpsc::channel::(); + let job = match Self::fetch_job(&inner, rx) { + Ok(job) => job, Err(err) => return AppMachine::error_state(inner, err.to_string()).into(), }; - if requests.is_empty() { + if job.requests.is_empty() { return AppMachine::browse_state(inner).into(); } - let (search_tx, search_rx) = mpsc::channel::(); - let fetch = FetchState::search(search_rx); - - match inner.musicbrainz.submit_background_job(search_tx, requests) { - Ok(()) => AppMachine::fetch_state(inner, fetch).into(), + match inner.musicbrainz.submit_background_job(tx, job.requests) { + Ok(()) => AppMachine::fetch_state(inner, job.fetch).into(), Err(err) => AppMachine::error_state(inner, err.to_string()).into(), } } + fn fetch_job(inner: &AppInner, rx: MbApiReceiver) -> Result { + let coll = inner.music_hoard.get_collection(); + + let artist = match inner.selection.state_artist(coll) { + Some(artist_state) => &coll[artist_state.index], + None => return Err("cannot fetch: no artist selected"), + }; + + let requests = match inner.selection.category() { + Category::Artist => { + let fetch: FetchState; + let mut requests = Self::search_artist_job(artist); + if requests.is_empty() { + fetch = FetchState::fetch(rx); + requests = Self::browse_release_group_job(&artist.meta.info.musicbrainz); + } else { + fetch = FetchState::search(rx); + } + SubmitJob { fetch, requests } + } + _ => { + let arid = match artist.meta.info.musicbrainz { + MbRefOption::Some(ref mbref) => mbref, + _ => return Err("cannot fetch album: artist has no MBID"), + }; + let album = match inner.selection.state_album(coll) { + Some(album_state) => &artist.albums[album_state.index], + None => return Err("cannot fetch album: no album selected"), + }; + let artist_id = &artist.meta.id; + SubmitJob { + fetch: FetchState::search(rx), + requests: Self::search_release_group_job(artist_id, arid, album), + } + } + }; + + Ok(requests) + } + pub fn app_fetch_next(inner: AppInner, mut fetch: FetchState) -> App { match fetch.try_recv() { Ok(fetch_result) => match fetch_result { @@ -167,33 +210,6 @@ impl AppMachine { Self::app_fetch_next(inner, fetch) } - fn search_job(inner: &AppInner) -> Result, &'static str> { - let coll = inner.music_hoard.get_collection(); - - let artist = match inner.selection.state_artist(coll) { - Some(artist_state) => &coll[artist_state.index], - None => return Err("cannot fetch: no artist selected"), - }; - - let requests = match inner.selection.category() { - Category::Artist => Self::search_artist_job(artist), - _ => { - let arid = match artist.meta.info.musicbrainz { - MbRefOption::Some(ref mbref) => mbref, - _ => return Err("cannot fetch album: artist has no MBID"), - }; - let album = match inner.selection.state_album(coll) { - Some(album_state) => &artist.albums[album_state.index], - None => return Err("cannot fetch album: no album selected"), - }; - let artist_id = &artist.meta.id; - Self::search_release_group_job(artist_id, arid, album) - } - }; - - Ok(requests) - } - fn search_artist_job(artist: &Artist) -> VecDeque { match artist.meta.info.musicbrainz { MbRefOption::Some(ref arid) => { @@ -231,6 +247,17 @@ impl AppMachine { .collect() } + fn browse_release_group_job(mbopt: &MbRefOption) -> VecDeque { + match mbopt { + MbRefOption::Some(mbref) => Self::browse_release_group_request(mbref), + _ => VecDeque::new(), + } + } + + fn browse_release_group_request(mbref: &MbArtistRef) -> VecDeque { + VecDeque::from([MbParams::browse_release_group(mbref.mbid().clone())]) + } + fn submit_lookup_artist_job( musicbrainz: &dyn IMbJobSender, result_sender: ResultSender,