diff options
Diffstat (limited to 'import/src/musicbrainz.rs')
-rw-r--r-- | import/src/musicbrainz.rs | 107 |
1 files changed, 102 insertions, 5 deletions
diff --git a/import/src/musicbrainz.rs b/import/src/musicbrainz.rs index 0fe839b..704807b 100644 --- a/import/src/musicbrainz.rs +++ b/import/src/musicbrainz.rs @@ -55,6 +55,24 @@ pub struct MbRecordingRel { #[derive(Debug, Deserialize, Encode, Decode)] #[serde(rename_all = "kebab-case")] +pub struct MbArtistRel { + pub id: String, + pub isnis: Vec<String>, + pub ipis: Vec<String>, + pub name: String, + pub disambiguation: String, + pub country: Option<String>, + pub sort_name: String, + pub gender_id: Option<String>, + pub area: Option<MbArea>, + pub begin_area: Option<MbArea>, + pub end_area: Option<MbArea>, + pub life_span: MbTimespan, + pub relations: Vec<MbRelation>, +} + +#[derive(Debug, Deserialize, Encode, Decode)] +#[serde(rename_all = "kebab-case")] pub struct MbArtistCredit { pub name: String, pub artist: MbArtist, @@ -81,6 +99,7 @@ pub struct MbRelation { pub url: Option<MbUrl>, pub recording: Option<MbRecording>, pub series: Option<MbSeries>, + pub event: Option<MbEvent>, } #[derive(Debug, Deserialize, Encode, Decode)] @@ -98,10 +117,12 @@ pub struct MbSeries { pub struct MbRecording { pub id: String, pub title: String, + #[serde(default)] pub isrcs: Vec<String>, pub video: bool, pub disambiguation: String, - pub length: u32, + pub length: Option<u32>, + #[serde(default)] pub artist_credit: Vec<MbArtistCredit>, } @@ -109,8 +130,8 @@ pub struct MbRecording { #[serde(rename_all = "kebab-case")] pub struct MbWork { pub id: String, - pub r#type: String, - pub type_id: String, + pub r#type: Option<String>, + pub type_id: Option<String>, pub languages: Vec<String>, pub iswcs: Vec<String>, pub language: Option<String>, @@ -121,6 +142,19 @@ pub struct MbWork { #[derive(Debug, Deserialize, Encode, Decode)] #[serde(rename_all = "kebab-case")] +pub struct MbEvent { + pub id: String, + pub r#type: String, + pub type_id: String, + pub name: String, + pub time: String, + pub cancelled: bool, + pub setlist: String, + pub life_span: MbTimespan, +} + +#[derive(Debug, Deserialize, Encode, Decode)] +#[serde(rename_all = "kebab-case")] pub struct MbArtist { pub id: String, pub r#type: Option<String>, @@ -133,9 +167,28 @@ pub struct MbArtist { #[derive(Debug, Deserialize, Encode, Decode)] #[serde(rename_all = "kebab-case")] +pub struct MbTimespan { + pub begin: Option<String>, + pub end: Option<String>, + pub ended: bool, +} + +#[derive(Debug, Deserialize, Encode, Decode)] +#[serde(rename_all = "kebab-case")] +pub struct MbArea { + pub name: String, + pub sort_name: String, + #[serde(default)] + pub iso_3166_1_codes: Vec<String>, + pub id: String, + pub disambiguation: String, +} + +#[derive(Debug, Deserialize, Encode, Decode)] +#[serde(rename_all = "kebab-case")] pub struct MbUrl { - id: String, - resource: String, + pub id: String, + pub resource: String, } impl MusicBrainz { @@ -206,4 +259,48 @@ impl MusicBrainz { }) .await } + + pub async fn lookup_artist(&self, id: String) -> Result<Arc<MbArtistRel>> { + async_cache_memory("api-musicbrainz-artist", id.clone(), || async move { + let _permit = self.rate_limit.clone().acquire_owned().await?; + let permit_drop_ts = Instant::now() + Duration::from_secs(10); + info!("artist lookup: {id}"); + + let inc = [ + "area-rels", + "artist-rels", + "event-rels", + "genre-rels", + "instrument-rels", + "label-rels", + "place-rels", + "recording-rels", + "release-rels", + "release-group-rels", + "series-rels", + "url-rels", + "work-rels", + ] + .join("+"); + + let resp = self + .client + .get(format!( + "https://musicbrainz.org/ws/2/artist/{id}?inc={inc}" + )) + .send() + .await? + .error_for_status()? + .json::<MbArtistRel>() + .await?; + + tokio::task::spawn(async move { + sleep_until(permit_drop_ts).await; + drop(_permit); + }); + + Ok(resp) + }) + .await + } } |