Hardened the indexing for blink-182
This commit is contained in:
25
src/main.rs
25
src/main.rs
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user