diff --git a/src/queries/tracks.rs b/src/queries/tracks.rs index bb37cca..25cdae2 100644 --- a/src/queries/tracks.rs +++ b/src/queries/tracks.rs @@ -184,6 +184,35 @@ pub async fn delete_by_artist(db: &DatabaseConnection, artist_id: i32) -> DbResu Ok(result.rows_affected) } +/// Get tracks that have been tagged but have no corresponding wanted_item. +/// These are files that went through the pipeline but aren't part of any watched content. +pub async fn get_unwanted(db: &DatabaseConnection) -> DbResult> { + let all_tagged = Tracks::find() + .filter(track::Column::Tagged.eq(true)) + .all(db) + .await?; + + let all_wanted = crate::entities::wanted_item::Entity::find().all(db).await?; + + let wanted_mbids: std::collections::HashSet<&str> = all_wanted + .iter() + .filter_map(|w| w.musicbrainz_id.as_deref()) + .collect(); + + let wanted_track_ids: std::collections::HashSet = + all_wanted.iter().filter_map(|w| w.track_id).collect(); + + Ok(all_tagged + .into_iter() + .filter(|t| { + // Not linked by track_id + !wanted_track_ids.contains(&t.id) + // Not linked by MBID + && !t.musicbrainz_id.as_deref().is_some_and(|mbid| wanted_mbids.contains(mbid)) + }) + .collect()) +} + /// Delete tracks whose files no longer exist on disk. pub async fn delete_orphaned(db: &DatabaseConnection) -> DbResult { let all = Tracks::find().all(db).await?;