Update for the "full flow"

This commit is contained in:
Connor Johnstone
2026-03-17 21:39:08 -04:00
parent 5583bc21fe
commit 0572722184
4 changed files with 118 additions and 44 deletions

View File

@@ -51,52 +51,60 @@ pub async fn tag_track(
track: &track::Model,
config: &TagConfig,
) -> TagResult<bool> {
// Build search query
let (artist, title) = match matcher::build_query(track) {
Some(q) => q,
None => {
tracing::debug!(id = track.id, path = %track.file_path, "no query possible, skipping");
// If the track already has an MBID, skip searching and go straight to lookup
let (details, best_release) = if let Some(ref mbid) = track.musicbrainz_id {
tracing::info!(id = track.id, mbid = %mbid, "looking up recording by MBID");
if config.dry_run {
tracing::info!(id = track.id, mbid = %mbid, "DRY RUN: would enrich from MBID");
return Ok(true);
}
let details = provider.get_recording(mbid).await?;
let best_release = details.releases.first().cloned();
(details, best_release)
} else {
// No MBID — search by artist + title
let (artist, title) = match matcher::build_query(track) {
Some(q) => q,
None => {
tracing::debug!(id = track.id, path = %track.file_path, "no query possible, skipping");
return Ok(false);
}
};
tracing::info!(id = track.id, artist = %artist, title = %title, "searching MusicBrainz");
let candidates = provider.search_recording(&artist, &title).await?;
if candidates.is_empty() {
tracing::debug!(id = track.id, "no results from MusicBrainz");
return Ok(false);
}
};
tracing::info!(
id = track.id,
artist = %artist,
title = %title,
"searching MusicBrainz"
);
let best = match matcher::select_best_match(track, candidates, config.confidence) {
Some(m) => m,
None => {
tracing::debug!(
id = track.id,
"no match above confidence threshold {}",
config.confidence
);
return Ok(false);
}
};
// Search for recordings
let candidates = provider.search_recording(&artist, &title).await?;
log_match(track, &best);
if candidates.is_empty() {
tracing::debug!(id = track.id, "no results from MusicBrainz");
return Ok(false);
}
// Score and select best match
let best = match matcher::select_best_match(track, candidates, config.confidence) {
Some(m) => m,
None => {
tracing::debug!(
id = track.id,
"no match above confidence threshold {}",
config.confidence
);
return Ok(false);
if config.dry_run {
return Ok(true);
}
let details = provider.get_recording(&best.recording.mbid).await?;
let best_release = best.best_release;
(details, best_release)
};
log_match(track, &best);
if config.dry_run {
return Ok(true);
}
// Get full details for the best match
let details = provider.get_recording(&best.recording.mbid).await?;
// Upsert artist with MusicBrainz ID
let artist_id = match &details.artist_mbid {
Some(mbid) => {
@@ -108,7 +116,7 @@ pub async fn tag_track(
};
// Upsert album from best release
let (album_id, album_name) = if let Some(ref release) = best.best_release {
let (album_id, album_name) = if let Some(ref release) = best_release {
let album = queries::albums::upsert(
conn,
&release.title,
@@ -123,8 +131,7 @@ pub async fn tag_track(
};
// Parse year from release date
let year = best
.best_release
let year = best_release
.as_ref()
.and_then(|r| r.date.as_deref())
.and_then(|d| d.split('-').next())
@@ -164,7 +171,7 @@ pub async fn tag_track(
if let Err(e) = file_tags::write_tags(
&track.file_path,
&details,
best.best_release.as_ref(),
best_release.as_ref(),
year,
genre.as_deref(),
) {
@@ -196,7 +203,7 @@ pub async fn run_tagging(
let tracks: Vec<track::Model> = if let Some(id) = track_id {
vec![queries::tracks::get_by_id(conn, id).await?]
} else {
queries::tracks::get_untagged(conn).await?
queries::tracks::get_needing_metadata(conn).await?
};
tracing::info!(count = tracks.len(), "tracks to process");