Improve suggestion matching
This commit is contained in:
@@ -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(" ", "")
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user