pinakes-core: fix isbn regex, csv quoting, document extraction, and enrichment accuracy

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I974959e74d2b5b5591437daa0f29291a6a6a6964
This commit is contained in:
raf 2026-03-08 00:42:01 +03:00
commit d5be5026a7
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
5 changed files with 132 additions and 90 deletions

View file

@ -1,6 +1,6 @@
//! MusicBrainz metadata enrichment for audio files.
//! `MusicBrainz` metadata enrichment for audio files.
use std::time::Duration;
use std::{fmt::Write as _, time::Duration};
use chrono::Utc;
use uuid::Uuid;
@ -23,14 +23,17 @@ impl Default for MusicBrainzEnricher {
}
impl MusicBrainzEnricher {
/// Create a new `MusicBrainzEnricher`.
#[must_use]
pub fn new() -> Self {
let client = reqwest::Client::builder()
.user_agent("Pinakes/0.1 (https://github.com/notashelf/pinakes)")
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(5))
.build()
.unwrap_or_else(|_| reqwest::Client::new());
Self {
client: reqwest::Client::builder()
.user_agent("Pinakes/0.1 (https://github.com/notashelf/pinakes)")
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(5))
.build()
.expect("failed to build HTTP client with configured timeouts"),
client,
base_url: "https://musicbrainz.org/ws/2".to_string(),
}
}
@ -65,7 +68,7 @@ impl MetadataEnricher for MusicBrainzEnricher {
let mut query = format!("recording:{}", escape_lucene_query(title));
if let Some(ref artist) = item.artist {
query.push_str(&format!(" AND artist:{}", escape_lucene_query(artist)));
let _ = write!(query, " AND artist:{}", escape_lucene_query(artist));
}
let url = format!("{}/recording/", self.base_url);
@ -113,7 +116,7 @@ impl MetadataEnricher for MusicBrainzEnricher {
})?;
let recordings = json.get("recordings").and_then(|r| r.as_array());
if recordings.is_none_or(|r| r.is_empty()) {
if recordings.is_none_or(std::vec::Vec::is_empty) {
return Ok(None);
}
@ -125,11 +128,12 @@ impl MetadataEnricher for MusicBrainzEnricher {
.get("id")
.and_then(|id| id.as_str())
.map(String::from);
let score = recording
let score = (recording
.get("score")
.and_then(|s| s.as_f64())
.and_then(serde_json::Value::as_f64)
.unwrap_or(0.0)
/ 100.0;
/ 100.0)
.min(1.0);
Ok(Some(ExternalMetadata {
id: Uuid::now_v7(),