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
Showing only changes of commit 3763abfb17 - Show all commits

View File

@ -60,17 +60,6 @@ impl FetchState {
} }
} }
enum FetchError {
NothingToFetch,
SubmitError(DaemonError),
}
impl From<DaemonError> for FetchError {
fn from(value: DaemonError) -> Self {
FetchError::SubmitError(value)
}
}
impl AppMachine<FetchState> { impl AppMachine<FetchState> {
fn fetch_state(inner: AppInner, state: FetchState) -> Self { fn fetch_state(inner: AppInner, state: FetchState) -> Self {
AppMachine::new(inner, state) AppMachine::new(inner, state)
@ -81,48 +70,21 @@ impl AppMachine<FetchState> {
} }
fn app_fetch_new(inner: AppInner) -> App { fn app_fetch_new(inner: AppInner) -> App {
let coll = inner.music_hoard.get_collection(); let requests = match Self::search_job(&inner) {
Ok(requests) => requests,
let artist = match inner.selection.state_artist(coll) { Err(err) => return AppMachine::error_state(inner, err.to_string()).into(),
Some(artist_state) => &coll[artist_state.index],
None => {
let err = "cannot fetch artist: no artist selected";
return AppMachine::error_state(inner, err).into();
}
}; };
if requests.is_empty() {
return AppMachine::browse_state(inner).into();
}
let (fetch_tx, fetch_rx) = mpsc::channel::<MbApiResult>(); let (fetch_tx, fetch_rx) = mpsc::channel::<MbApiResult>();
let fetch = FetchState::search(fetch_rx); let fetch = FetchState::search(fetch_rx);
let mb = &*inner.musicbrainz; match inner.musicbrainz.submit_background_job(fetch_tx, requests) {
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(), Ok(()) => AppMachine::fetch_state(inner, fetch).into(),
Err(FetchError::NothingToFetch) => AppMachine::browse_state(inner).into(), Err(err) => AppMachine::error_state(inner, err.to_string()).into(),
Err(FetchError::SubmitError(daemon_err)) => {
AppMachine::error_state(inner, daemon_err.to_string()).into()
}
} }
} }
@ -191,36 +153,49 @@ impl AppMachine<FetchState> {
Self::app_fetch_next(inner, fetch) Self::app_fetch_next(inner, fetch)
} }
fn submit_search_artist_job( fn search_job(inner: &AppInner) -> Result<VecDeque<MbParams>, &'static str> {
musicbrainz: &dyn IMbJobSender, let coll = inner.music_hoard.get_collection();
result_sender: ResultSender,
artist: &Artist, let artist = match inner.selection.state_artist(coll) {
) -> Result<(), FetchError> { Some(artist_state) => &coll[artist_state.index],
let requests = match artist.meta.info.musicbrainz { 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<MbParams> {
match artist.meta.info.musicbrainz {
MbRefOption::Some(ref arid) => { MbRefOption::Some(ref arid) => {
Self::search_albums_requests(&artist.meta.id, arid, &artist.albums) Self::search_albums_requests(&artist.meta.id, arid, &artist.albums)
} }
MbRefOption::CannotHaveMbid => VecDeque::new(), MbRefOption::CannotHaveMbid => VecDeque::new(),
MbRefOption::None => Self::search_artist_request(&artist.meta), MbRefOption::None => Self::search_artist_request(&artist.meta),
};
if requests.is_empty() {
return Err(FetchError::NothingToFetch);
} }
Ok(musicbrainz.submit_background_job(result_sender, requests)?)
} }
fn submit_search_release_group_job( fn search_release_group_job(
musicbrainz: &dyn IMbJobSender,
result_sender: ResultSender,
artist_id: &ArtistId, artist_id: &ArtistId,
artist_mbid: &MbArtistRef, artist_mbid: &MbArtistRef,
album: &Album, album: &Album,
) -> Result<(), FetchError> { ) -> VecDeque<MbParams> {
let requests = Self::search_albums_requests(artist_id, artist_mbid, slice::from_ref(album)); Self::search_albums_requests(artist_id, artist_mbid, slice::from_ref(album))
if requests.is_empty() {
return Err(FetchError::NothingToFetch);
}
Ok(musicbrainz.submit_background_job(result_sender, requests)?)
} }
fn search_albums_requests( fn search_albums_requests(