Allow fetching of a single album #226

Merged
wojtek merged 3 commits from 225---allow-fetching-of-a-single-album into main 2024-09-29 12:38:38 +02:00
Showing only changes of commit 011a999f28 - Show all commits

View File

@ -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<FetchState> {
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::<MbApiResult>();
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<FetchState> {
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<FetchState> {
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<FetchState> {
.collect()
}
fn fetch_artist_request(meta: &ArtistMeta) -> VecDeque<MbParams> {
fn search_artist_request(meta: &ArtistMeta) -> VecDeque<MbParams> {
VecDeque::from([MbParams::search_artist(meta.clone())])
}