several small ui updates, plus hopefully a track-matching fix
CI / check (push) Failing after 25s
CI / docker (push) Has been skipped

This commit is contained in:
Connor Johnstone
2026-04-01 22:32:52 -04:00
parent b2f030b52d
commit 01365dbb80
3 changed files with 27 additions and 9 deletions
+25 -7
View File
@@ -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;
+1 -1
View File
@@ -72,7 +72,7 @@ impl SimilarConfig {
}
fn default_count() -> usize {
50
30
}
fn default_popularity_bias() -> u8 {