Hardened the indexing for blink-182

This commit is contained in:
Connor Johnstone
2026-03-03 13:30:51 -05:00
parent f5f0273853
commit 60a1d704dd
4 changed files with 104 additions and 26 deletions

View File

@@ -26,7 +26,7 @@ fn db_path() -> PathBuf {
fn usage(program: &str) -> ! {
eprintln!("Usage:");
eprintln!(" {program} index [-v] <directory>");
eprintln!(" {program} index [-v] [-f] <directory>");
eprintln!(" {program} build [-v] [-m] [-s|-r] [-n COUNT] [file]");
std::process::exit(1);
}
@@ -47,10 +47,11 @@ fn main() {
fn cmd_index(args: &[String]) {
let verbose = args.iter().any(|a| a == "-v");
let rest: Vec<&String> = args.iter().skip(2).filter(|a| *a != "-v").collect();
let force = args.iter().any(|a| a == "-f");
let rest: Vec<&String> = args.iter().skip(2).filter(|a| *a != "-v" && *a != "-f").collect();
if rest.len() != 1 {
eprintln!("Usage: {} index [-v] <directory>", args[0]);
eprintln!("Usage: {} index [-v] [-f] <directory>", args[0]);
std::process::exit(1);
}
@@ -89,7 +90,7 @@ fn cmd_index(args: &[String]) {
let artist_name = metadata::read_artist_name(&path).ok().flatten();
let display_name = artist_name.as_deref().unwrap_or(&artist_mbid);
if !already_indexed {
if !already_indexed || force {
if verbose {
println!("Indexing {display_name}...");
}
@@ -318,7 +319,7 @@ fn build_playlist(
.map(|(total, _, _, artist, path)| (total, artist, path))
.collect();
let mut selected = generate_playlist(&candidates, count);
let mut selected = generate_playlist(&candidates, count, seed_name);
if random {
selected.shuffle(&mut rand::rng());
@@ -352,6 +353,7 @@ fn build_playlist(
fn generate_playlist(
candidates: &[(f64, String, String)],
n: usize,
seed_name: &str,
) -> Vec<(f64, String, String)> {
if candidates.is_empty() {
return Vec::new();
@@ -362,6 +364,8 @@ fn generate_playlist(
let mut result: Vec<(f64, String, String)> = Vec::new();
let mut artist_counts: HashMap<String, usize> = HashMap::new();
let seed_min = (n / 10).max(1);
let distinct_artists: usize = {
let mut seen = std::collections::HashSet::new();
for (_, artist, _) in &pool {
@@ -381,12 +385,21 @@ fn generate_playlist(
let artist_cap = ((n + divisor - 1) / divisor).max(1);
while result.len() < n && !pool.is_empty() {
let seed_count = *artist_counts.get(seed_name).unwrap_or(&0);
let remaining = n - result.len();
let seed_deficit = seed_min.saturating_sub(seed_count);
let force_seed = seed_deficit > 0 && remaining <= seed_deficit;
// Find eligible tracks (artist hasn't hit cap)
let eligible: Vec<usize> = pool
.iter()
.enumerate()
.filter(|(_, (_, artist, _))| {
*artist_counts.get(artist).unwrap_or(&0) < artist_cap
if force_seed {
artist == seed_name
} else {
*artist_counts.get(artist).unwrap_or(&0) < artist_cap
}
})
.map(|(i, _)| i)
.collect();