aboutsummaryrefslogtreecommitdiff
path: root/import/src/musicbrainz.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-04-25 21:34:59 +0200
committermetamuffin <metamuffin@disroot.org>2025-04-25 21:34:59 +0200
commit2c6f753797b8e223c5982c4790f1be8b08fe63d6 (patch)
tree32b77bae2fd83927bc37dbbf3fa666e10beb4703 /import/src/musicbrainz.rs
parentb84ac0b04c45aa353ba1a302f96fa5f0f5895d59 (diff)
downloadjellything-2c6f753797b8e223c5982c4790f1be8b08fe63d6.tar
jellything-2c6f753797b8e223c5982c4790f1be8b08fe63d6.tar.bz2
jellything-2c6f753797b8e223c5982c4790f1be8b08fe63d6.tar.zst
images from wikidata works
Diffstat (limited to 'import/src/musicbrainz.rs')
-rw-r--r--import/src/musicbrainz.rs107
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
+ }
}