Add method to manually add artist metadata #85

Merged
wojtek merged 16 commits from 55---add-method-to-manually-add-artist-metadata into main 2024-01-10 22:33:58 +01:00
2 changed files with 119 additions and 29 deletions
Showing only changes of commit 3ea68d2935 - Show all commits

View File

@ -73,18 +73,18 @@ struct MultiUrlValue {
}
macro_rules! url_command_dispatch {
($command:ident, $mh:ident, $add:ident, $remove:ident, $set:ident, $clear:ident) => {
match $command {
UrlCommand::Add(single_url_value) => {
$mh.$add(ArtistId::new(single_url_value.artist), single_url_value.url)
($cmd:ident, $mh:ident, $add:ident, $remove:ident, $set:ident, $clear:ident, $url:ident) => {
match $cmd {
UrlCommand::Add(url_value) => {
$mh.$add(ArtistId::new(url_value.artist), url_value.$url)
.expect("failed to add URL(s)");
}
UrlCommand::Remove(single_url_value) => {
$mh.$remove(ArtistId::new(single_url_value.artist), single_url_value.url)
UrlCommand::Remove(url_value) => {
$mh.$remove(ArtistId::new(url_value.artist), url_value.$url)
.expect("failed to remove URL(s)");
}
UrlCommand::Set(single_url_value) => {
$mh.$set(ArtistId::new(single_url_value.artist), single_url_value.url)
UrlCommand::Set(url_value) => {
$mh.$set(ArtistId::new(url_value.artist), url_value.$url)
.expect("failed to set URL(s)");
}
UrlCommand::Clear(artist_value) => {
@ -114,24 +114,18 @@ impl ArtistCommand {
add_musicbrainz_url,
remove_musicbrainz_url,
set_musicbrainz_url,
clear_musicbrainz_url
clear_musicbrainz_url,
url
),
ArtistCommand::MusicButler(url_command) => url_command_dispatch!(
url_command,
music_hoard,
add_musicbutler_urls,
remove_musicbutler_urls,
set_musicbutler_urls,
clear_musicbutler_urls,
urls
),
ArtistCommand::MusicButler(url_command) => {
match url_command {
UrlCommand::Add(_) => {
// Add URL.
}
UrlCommand::Remove(_) => {
// Remove URL if it exists.
}
UrlCommand::Set(_) => {
// Set the URLs regardless of previous (if any) value.
}
UrlCommand::Clear(_) => {
// Remove the URLs.
}
}
}
ArtistCommand::Bandcamp(url_command) => {
match url_command {
UrlCommand::Add(_) => {

View File

@ -375,6 +375,65 @@ impl Artist {
self.properties.musicbrainz = None;
Ok(())
}
fn add_musicbutler_urls<S: AsRef<str>>(&mut self, urls: Vec<S>) -> Result<(), Error> {
// Convert into URLs first to facilitate later comparison.
let urls: Result<Vec<MusicButler>, Error> = urls.iter().map(MusicButler::new).collect();
let mut urls = urls?;
// Do not check and insert. First check if any of the provided URLs already exist so that
// the vector remains unchanged in case of failure.
let overlap: Vec<&MusicButler> = urls
.iter()
.filter(|url| self.properties.musicbutler.contains(url))
.collect();
if !overlap.is_empty() {
return Err(Error::CollectionError(format!(
"artist '{}' already has these MusicButler URL(s): {:?}",
self.id, overlap
)));
}
self.properties.musicbutler.append(&mut urls);
Ok(())
}
fn remove_musicbutler_urls<S: AsRef<str>>(&mut self, urls: Vec<S>) -> Result<(), Error> {
// Convert into URLs first to facilitate later comparison.
let urls: Result<Vec<MusicButler>, Error> = urls.iter().map(MusicButler::new).collect();
let urls = urls?;
// Do not check and insert. First check if any of the provided URLs already exist so that
// the vector remains unchanged in case of failure.
let difference: Vec<&MusicButler> = urls
.iter()
.filter(|url| !self.properties.musicbutler.contains(url))
.collect();
if !difference.is_empty() {
return Err(Error::CollectionError(format!(
"artist '{}' does not have these MusicButler URL(s): {:?}",
self.id, difference
)));
}
let musicbutler = mem::take(&mut self.properties.musicbutler);
self.properties.musicbutler = musicbutler
.into_iter()
.filter(|url| !urls.contains(url))
.collect();
Ok(())
}
fn set_musicbutler_urls<S: AsRef<str>>(&mut self, urls: Vec<S>) -> Result<(), Error> {
let urls: Result<Vec<MusicButler>, Error> = urls.iter().map(MusicButler::new).collect();
self.properties.musicbutler = urls?;
Ok(())
}
fn clear_musicbutler_urls(&mut self) -> Result<(), Error> {
self.properties.musicbutler.clear();
Ok(())
}
}
impl PartialOrd for Artist {
@ -663,6 +722,41 @@ impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
.clear_musicbrainz_url()
}
pub fn add_musicbutler_urls<ID: AsRef<ArtistId>, S: AsRef<str>>(
&mut self,
artist_id: ID,
urls: Vec<S>,
) -> Result<(), Error> {
self.get_artist_or_err(artist_id.as_ref())?
.add_musicbutler_urls(urls)
}
pub fn remove_musicbutler_urls<ID: AsRef<ArtistId>, S: AsRef<str>>(
&mut self,
artist_id: ID,
urls: Vec<S>,
) -> Result<(), Error> {
self.get_artist_or_err(artist_id.as_ref())?
.remove_musicbutler_urls(urls)
}
pub fn set_musicbutler_urls<ID: AsRef<ArtistId>, S: AsRef<str>>(
&mut self,
artist_id: ID,
urls: Vec<S>,
) -> Result<(), Error> {
self.get_artist_or_err(artist_id.as_ref())?
.set_musicbutler_urls(urls)
}
pub fn clear_musicbutler_urls<ID: AsRef<ArtistId>>(
&mut self,
artist_id: ID,
) -> Result<(), Error> {
self.get_artist_or_err(artist_id.as_ref())?
.clear_musicbutler_urls()
}
fn sort(collection: &mut [Artist]) {
collection.sort_unstable();
for artist in collection.iter_mut() {
@ -745,10 +839,12 @@ impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
}
fn get_artist_or_err(&mut self, artist_id: &ArtistId) -> Result<&mut Artist, Error> {
let artist_opt = self.collection.iter_mut().find(|a| &a.id == artist_id);
artist_opt.ok_or_else(|| {
Error::CollectionError(format!("artist '{}' is not in the collection", artist_id))
})
self.collection
.iter_mut()
.find(|a| &a.id == artist_id)
.ok_or_else(|| {
Error::CollectionError(format!("artist '{}' is not in the collection", artist_id))
})
}
}