This commit is contained in:
Wojciech Kozlowski 2024-10-06 20:01:09 +02:00
parent 12b27655e3
commit 73aab07d9b
5 changed files with 132 additions and 10 deletions

View File

@ -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;
}
}
}

View File

@ -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)
}

View File

@ -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,

View File

@ -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,

View File

@ -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,