Improve suggestion matching
Some checks failed
CI / Check Style (push) Has been cancelled
CI / Run Clippy (push) Has been cancelled
CI / Run Tests (push) Has been cancelled

This commit is contained in:
2025-07-25 03:13:47 +02:00
parent 41afc170ba
commit 43bd076d04

View File

@@ -1,4 +1,5 @@
use std::collections::HashSet; use std::collections::HashSet;
use strsim::jaro_winkler;
use musicbrainz_rs::entity::release::Track; use musicbrainz_rs::entity::release::Track;
use serde::Serialize; use serde::Serialize;
@@ -6,6 +7,8 @@ use tracing::info;
use crate::models::music_files; use crate::models::music_files;
const SIMILARITY_THRESHOLD: f64 = 0.85;
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct SuggestedTrackFix { pub struct SuggestedTrackFix {
pub file_id: i32, pub file_id: i32,
@@ -32,20 +35,18 @@ pub fn match_album_metadata(
let mut suggestions = Vec::new(); let mut suggestions = Vec::new();
for mb_track in mb_tracks { for mb_track in mb_tracks {
let mb_title_norm = mb_track.title.to_lowercase(); let mb_title_norm = normalize(&mb_track.title);
if let Some((local, _)) = local_files if let Some((local, _)) = local_files
.iter() .iter()
.filter(|f| !used_file_ids.contains(&f.id)) .filter(|f| !used_file_ids.contains(&f.id))
.map(|f| { .filter_map(|f| {
let title_match_score = f let local_title = f.title.as_ref().map(|t| normalize(t))?;
.title let score = jaro_winkler(&mb_title_norm, &local_title);
.as_ref() Some((f, score))
.map(|t| (t.to_lowercase() == mb_title_norm) as u8)
.unwrap_or(0);
(f, title_match_score)
}) })
.max_by_key(|(_, score)| *score) .filter(|(_, score)| *score > SIMILARITY_THRESHOLD)
.max_by(|a, b| a.1.partial_cmp(&b.1).unwrap())
{ {
info!( info!(
"Matched MB track '{}' with local '{}'", "Matched MB track '{}' with local '{}'",
@@ -97,3 +98,11 @@ pub fn match_album_metadata(
suggestions suggestions
} }
fn normalize(s: &str) -> String {
s.to_lowercase()
.replace(['(', ')', '[', ']', '-', '_', '.', '\''], "")
.replace("feat", "")
.replace("ft", "")
.replace(" ", "")
}