several small ui updates, plus hopefully a track-matching fix
This commit is contained in:
@@ -38,12 +38,17 @@ pub fn score_tracks(
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
|
||||
// Build playcount lookup by lowercase name
|
||||
// Build playcount lookups by lowercase name and by MBID
|
||||
let playcount_by_name: HashMap<String, u64> = top_tracks
|
||||
.iter()
|
||||
.map(|t| (t.name.to_lowercase(), t.playcount))
|
||||
.collect();
|
||||
|
||||
let playcount_by_mbid: HashMap<String, u64> = top_tracks
|
||||
.iter()
|
||||
.filter_map(|t| t.mbid.as_ref().map(|m| (m.clone(), t.playcount)))
|
||||
.collect();
|
||||
|
||||
let max_playcount = playcount_by_name
|
||||
.values()
|
||||
.copied()
|
||||
@@ -54,6 +59,7 @@ pub fn score_tracks(
|
||||
for track in local_tracks {
|
||||
let title_lower = track.title.as_ref().map(|t| t.to_lowercase());
|
||||
|
||||
// Match by: exact title, MBID, or prefix/contains (for parenthetical suffixes)
|
||||
let playcount = title_lower
|
||||
.as_ref()
|
||||
.and_then(|t| playcount_by_name.get(t).copied())
|
||||
@@ -61,19 +67,31 @@ pub fn score_tracks(
|
||||
track
|
||||
.musicbrainz_id
|
||||
.as_ref()
|
||||
.and_then(|id| playcount_by_name.get(id).copied())
|
||||
.and_then(|id| playcount_by_mbid.get(id).copied())
|
||||
})
|
||||
.or_else(|| {
|
||||
// Fuzzy: local title starts with a top track name, or vice versa
|
||||
title_lower.as_ref().and_then(|local| {
|
||||
playcount_by_name
|
||||
.iter()
|
||||
.filter(|(top_name, _)| {
|
||||
local.starts_with(top_name.as_str())
|
||||
|| top_name.starts_with(local.as_str())
|
||||
})
|
||||
.max_by_key(|(_, &pc)| pc)
|
||||
.map(|(_, &pc)| pc)
|
||||
})
|
||||
});
|
||||
|
||||
// If we have popularity data, require a match; otherwise assign uniform score
|
||||
// If we have popularity data, use it; unmatched tracks get a low base score
|
||||
let (popularity, similarity, score) = if !playcount_by_name.is_empty() {
|
||||
let Some(playcount) = playcount else {
|
||||
continue;
|
||||
};
|
||||
let playcount = playcount.unwrap_or(0);
|
||||
|
||||
let popularity = if playcount > 0 {
|
||||
(playcount as f64 / max_playcount as f64).powf(POPULARITY_EXPONENTS[bias])
|
||||
} else {
|
||||
0.0
|
||||
// Unmatched track: small base score so it can still appear
|
||||
0.01
|
||||
};
|
||||
|
||||
let similarity = (match_score.exp()) / std::f64::consts::E;
|
||||
|
||||
@@ -72,7 +72,7 @@ impl SimilarConfig {
|
||||
}
|
||||
|
||||
fn default_count() -> usize {
|
||||
50
|
||||
30
|
||||
}
|
||||
|
||||
fn default_popularity_bias() -> u8 {
|
||||
|
||||
Reference in New Issue
Block a user