musicbrainz: dedupe some code

This commit is contained in:
2026-06-17 12:04:26 +02:00
parent 8716350a4e
commit e78a2c3215
2 changed files with 95 additions and 57 deletions
+95 -56
View File
@@ -1,3 +1,6 @@
use log::Record;
use musicbrainz_rs::entity::artist_credit::ArtistCredit;
use musicbrainz_rs::entity::release::Release;
use musicbrainz_rs::{ApiEndpointError, entity::recording::Recording};
use musicbrainz_rs::prelude::*;
use schemars::JsonSchema;
@@ -7,16 +10,94 @@ use uuid::Uuid;
use crate::artifacts::tools::{DataSource, ToolDescription};
use crate::artifacts::{Album, Artifact, ArtifactBuilder, Artist, Contents, Merge, SourceID, Track};
impl From<Recording> for Track {
fn from(value: Recording) -> Self {
let artist = if let Some(artist) = value.artist_credit.unwrap_or_default().first() {
Some(artist.name.clone())
} else {
None
};
let album = if let Some(album) = value.releases.unwrap_or_default().first() {
Some(album.title.clone())
} else {
None
};
Self {
title: value.title,
artist,
album,
..Default::default()
}
}
}
impl From<Release> for Album {
fn from(value: Release) -> Self {
let artist = if let Some(artist) = value.artist_credit.unwrap_or_default().first() {
Some(artist.name.clone())
} else {
None
}.unwrap_or_default();
Self {
about: value.annotation,
title: value.title,
artist,
..Default::default()
}
}
}
impl From<ArtistCredit> for Artist {
fn from(value: ArtistCredit) -> Self {
Self {
bio: value.artist.annotation,
location: value.artist.country,
name: value.name,
..Default::default()
}
}
}
pub struct MBQuery;
impl MBQuery {
fn extract_recording_data(track: Recording) -> (Artifact, Vec<Artifact>) {
let mut ret = vec![];
let ret_track = ArtifactBuilder::new(SourceID::Musicbrainz)
.contents(Track::from(track.clone()))
.mbid(Uuid::parse_str(&track.id).unwrap())
.build();
for release in track.releases.unwrap_or_default() {
log::debug!("Found new release: {:?}", release);
ret.push(ArtifactBuilder::new(SourceID::Musicbrainz)
.mbid(Uuid::parse_str(&release.id).unwrap())
.contents(Album::from(release))
.build());
}
for artist in track.artist_credit.unwrap_or_default() {
ret.push(ArtifactBuilder::new(SourceID::Musicbrainz)
.mbid(Uuid::parse_str(&artist.artist.id).unwrap())
.contents(Artist::from(artist))
.build());
}
(ret_track, ret)
}
}
impl DataSource for MBQuery {
type Error = ApiEndpointError;
type Args = MusicbrainzQueryArgs;
async fn synchronize(&mut self, artifact: &mut Artifact) -> Result<Vec<Artifact>, Self::Error> {
let mut new_artifacts = vec![];
let mut ret = vec![];
if artifact.mbid.is_none() {
return Ok(new_artifacts);
return Ok(ret);
}
let artifact_id = artifact.mbid.clone().unwrap();
log::debug!("Synchronizing {} with musicbrainz", artifact_id);
@@ -34,39 +115,21 @@ impl DataSource for MBQuery {
}
};
let (track, mut new_artifacts) = Self::extract_recording_data(track);
ret.push(track.clone());
ret.append(&mut new_artifacts);
artifact.sources.insert(SourceID::Musicbrainz);
for release in track.releases.unwrap_or_default() {
log::debug!("Found new release: {:?}", release);
let first_artist = release.artist_credit.unwrap_or_default().first().unwrap().clone();
new_artifacts.push(ArtifactBuilder::new(SourceID::Musicbrainz)
.contents(Album {
title: release.title.clone(),
artist: first_artist.name.clone(),
about: release.annotation,
..Default::default()
})
.mbid(Uuid::parse_str(&release.id).unwrap()).build());
target_track.merge(Track {
album: Some(release.title),
title: track.title.clone(),
artist: Some(first_artist.artist.name.clone()),
..Default::default()
});
new_artifacts.push(ArtifactBuilder::new(SourceID::Musicbrainz)
.contents(Artist {
name: first_artist.name,
bio: first_artist.artist.annotation,
location: first_artist.artist.area.and_then(|area| { Some(area.name) }),
..Default::default()
})
.mbid(Uuid::parse_str(&first_artist.artist.id).unwrap()).build());
if let Contents::Track(track) = track.contents {
target_track.merge(track);
}
},
_ => ()
}
Ok(new_artifacts)
Ok(ret)
}
async fn query(&mut self, args: &Self::Args) -> Result<Vec<Artifact>, Self::Error> {
@@ -86,34 +149,10 @@ impl DataSource for MBQuery {
}
};
for release in track.releases.unwrap_or_default() {
log::debug!("Found new release: {:?}", release);
let first_artist = release.artist_credit.unwrap_or_default().first().unwrap().clone();
ret.push(ArtifactBuilder::new(SourceID::Musicbrainz)
.contents(Album {
title: release.title.clone(),
artist: first_artist.name.clone(),
about: release.annotation,
..Default::default()
})
.mbid(Uuid::parse_str(&release.id).unwrap()).build());
ret.push(ArtifactBuilder::new(SourceID::Musicbrainz)
.contents(Track {
album: Some(release.title),
title: track.title.clone(),
artist: Some(first_artist.artist.name.clone()),
..Default::default()
})
.mbid(Uuid::parse_str(&mbid).unwrap()).build());
ret.push(ArtifactBuilder::new(SourceID::Musicbrainz)
.contents(Artist {
name: first_artist.name,
bio: first_artist.artist.annotation,
location: first_artist.artist.area.and_then(|area| { Some(area.name) }),
..Default::default()
})
.mbid(Uuid::parse_str(&first_artist.artist.id).unwrap()).build());
}
let (track, mut new_artifacts) = Self::extract_recording_data(track);
ret.push(track);
ret.append(&mut new_artifacts);
}
Ok(ret)