Fixes for track management
This commit is contained in:
@@ -6,7 +6,7 @@ use crate::cleaning::escape_lucene;
|
||||
use crate::error::{TagError, TagResult};
|
||||
use crate::provider::{
|
||||
ArtistSearchResult, DiscographyEntry, MetadataProvider, RecordingDetails, RecordingMatch,
|
||||
ReleaseMatch, ReleaseRef, ReleaseTrack,
|
||||
ReleaseGroupEntry, ReleaseMatch, ReleaseRef, ReleaseTrack,
|
||||
};
|
||||
|
||||
const BASE_URL: &str = "https://musicbrainz.org/ws/2";
|
||||
@@ -54,6 +54,13 @@ impl MusicBrainzClient {
|
||||
}
|
||||
Ok(resp.json().await?)
|
||||
}
|
||||
|
||||
/// Look up an artist directly by MBID. Returns (name, disambiguation).
|
||||
pub async fn get_artist_by_mbid(&self, mbid: &str) -> TagResult<(String, Option<String>)> {
|
||||
let url = format!("{BASE_URL}/artist/{mbid}?fmt=json");
|
||||
let resp: MbArtistLookup = self.get_json(&url).await?;
|
||||
Ok((resp.name, resp.disambiguation.filter(|s| !s.is_empty())))
|
||||
}
|
||||
}
|
||||
|
||||
impl MetadataProvider for MusicBrainzClient {
|
||||
@@ -240,6 +247,32 @@ impl MetadataProvider for MusicBrainzClient {
|
||||
|
||||
Ok(tracks)
|
||||
}
|
||||
|
||||
async fn get_artist_release_groups(
|
||||
&self,
|
||||
artist_mbid: &str,
|
||||
) -> TagResult<Vec<ReleaseGroupEntry>> {
|
||||
// Fetch album, single, and EP release groups
|
||||
let url = format!(
|
||||
"{BASE_URL}/release-group?artist={artist_mbid}&type=album|single|ep&fmt=json&limit=100"
|
||||
);
|
||||
let resp: MbReleaseGroupResponse = self.get_json(&url).await?;
|
||||
|
||||
Ok(resp
|
||||
.release_groups
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|rg| ReleaseGroupEntry {
|
||||
mbid: rg.id,
|
||||
title: rg.title,
|
||||
primary_type: rg.primary_type,
|
||||
secondary_types: rg.secondary_types.unwrap_or_default(),
|
||||
first_release_date: rg.first_release_date,
|
||||
first_release_mbid: rg.releases
|
||||
.and_then(|r| r.into_iter().next().map(|rel| rel.id)),
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_artist_credit(credits: &Option<Vec<MbArtistCredit>>) -> (String, Option<String>) {
|
||||
@@ -287,6 +320,12 @@ struct MbArtistResult {
|
||||
artist_type: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct MbArtistLookup {
|
||||
name: String,
|
||||
disambiguation: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct MbRecordingSearchResponse {
|
||||
recordings: Vec<MbRecordingResult>,
|
||||
@@ -369,3 +408,27 @@ struct MbTrackEntry {
|
||||
struct MbTrackRecording {
|
||||
id: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct MbReleaseGroupResponse {
|
||||
#[serde(rename = "release-groups")]
|
||||
release_groups: Option<Vec<MbReleaseGroup>>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct MbReleaseGroup {
|
||||
id: String,
|
||||
title: String,
|
||||
#[serde(rename = "primary-type")]
|
||||
primary_type: Option<String>,
|
||||
#[serde(rename = "secondary-types", default)]
|
||||
secondary_types: Option<Vec<String>>,
|
||||
#[serde(rename = "first-release-date")]
|
||||
first_release_date: Option<String>,
|
||||
releases: Option<Vec<MbReleaseGroupRelease>>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct MbReleaseGroupRelease {
|
||||
id: String,
|
||||
}
|
||||
|
||||
@@ -104,6 +104,24 @@ pub trait MetadataProvider: Send + Sync {
|
||||
&self,
|
||||
release_mbid: &str,
|
||||
) -> impl std::future::Future<Output = TagResult<Vec<ReleaseTrack>>> + Send;
|
||||
|
||||
/// Get deduplicated release groups (albums, EPs, singles) for an artist.
|
||||
fn get_artist_release_groups(
|
||||
&self,
|
||||
artist_mbid: &str,
|
||||
) -> impl std::future::Future<Output = TagResult<Vec<ReleaseGroupEntry>>> + Send;
|
||||
}
|
||||
|
||||
/// A release group (deduplicated album/EP/single concept).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ReleaseGroupEntry {
|
||||
pub mbid: String,
|
||||
pub title: String,
|
||||
pub primary_type: Option<String>,
|
||||
pub secondary_types: Vec<String>,
|
||||
pub first_release_date: Option<String>,
|
||||
/// MBID of the first release in this group (for fetching tracks).
|
||||
pub first_release_mbid: Option<String>,
|
||||
}
|
||||
|
||||
/// A track within a release.
|
||||
|
||||
@@ -70,6 +70,10 @@ impl MetadataProvider for MockProvider {
|
||||
async fn get_release_tracks(&self, _release_mbid: &str) -> TagResult<Vec<shanty_tag::provider::ReleaseTrack>> {
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
async fn get_artist_release_groups(&self, _artist_mbid: &str) -> TagResult<Vec<shanty_tag::provider::ReleaseGroupEntry>> {
|
||||
Ok(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
async fn test_db() -> Database {
|
||||
|
||||
Reference in New Issue
Block a user