Analyse a photo listed twice once in Assisted Culling

Found while testing crates/engine/src/cmd/cull.rs:23 (analyze: ids come from Session::targets, crates/engine/src/lib.rs:1205, which does not de-duplicate)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-18 20:36:00 +00:00
co-authored by Claude Haiku 5.5
parent fb7ac08b9a
commit 1358ea61e1
2 changed files with 15 additions and 0 deletions
+3
View File
@@ -21,6 +21,9 @@ fn secs(iso: &str) -> Option<i64> {
fn analyze(s: &mut Session, p: &Value) -> Result<Value> {
let ids: Vec<PhotoId> = if p.get("ids").is_some() || s.selection.ids.len() > 1 { s.targets(p)? } else { s.visible_cloned() };
// a photo listed twice is one photo, not a burst of two look-alikes (first occurrence kept)
let mut seen = std::collections::HashSet::new();
let ids: Vec<PhotoId> = ids.into_iter().filter(|id| seen.insert(*id)).collect();
let reject_below = p.get("rejectBelow").and_then(Value::as_f64).map(|v| v as f32);
let pick_best = p.get("pickBest").and_then(Value::as_bool).unwrap_or(false);
// measure (thumbnail-level sources: fast, and enough for focus at 512 px)
+12
View File
@@ -778,6 +778,18 @@ fn assisted_culling_groups_bursts_and_scores_focus() {
let _ = std::fs::remove_dir_all(&dir);
}
/// Assisted culling: a photo listed twice is analysed once and is not a burst with itself.
#[test]
fn assisted_culling_ignores_repeated_ids() {
let mut s = Session::with_demo();
let id = s.visible_cloned()[0];
let r = s.execute("photo.analyze", &json!({"ids": [id.0, id.0]})).unwrap();
assert_eq!(r["groups"], 0, "a photo listed twice is not a burst of two: {r}");
assert_eq!(r["photos"].as_array().map(Vec::len), Some(1), "{r}");
let an = s.catalog.photo(id).unwrap().analysis.unwrap();
assert!(an.group.is_none() && !an.best, "{an:?}");
}
/// Assisted culling: two look-alike shots one second apart across midnight form a burst at the end of
/// every month, including those with fewer than 31 days.
#[test]