Add a filtering tool to only show only certain release group types #252

Merged
wojtek merged 14 commits from 161---add-a-filtering-tool-to-only-show-only-certain-release-group-types into main 2025-01-04 22:42:27 +01:00
2 changed files with 121 additions and 23 deletions
Showing only changes of commit 9e7f0d8092 - Show all commits

View File

@ -4,7 +4,7 @@ use crate::core::collection::album::{Album, AlbumOwnership, AlbumPrimaryType, Al
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct CollectionFilter { pub struct CollectionFilter {
pub include: Vec<Vec<AlbumField>>, pub include: Vec<Vec<AlbumField>>,
pub exclude: Vec<Vec<AlbumField>>, pub except: Vec<Vec<AlbumField>>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -17,8 +17,8 @@ pub enum AlbumField {
impl CollectionFilter { impl CollectionFilter {
pub fn filter_album(&self, album: &Album) -> bool { pub fn filter_album(&self, album: &Album) -> bool {
let include = Self::filter_and(&self.include, album); let include = Self::filter_and(&self.include, album);
let exclude = Self::filter_and(&self.exclude, album); let except = Self::filter_and(&self.except, album);
include && !exclude include && !except
} }
fn filter_and(group: &Vec<Vec<AlbumField>>, album: &Album) -> bool { fn filter_and(group: &Vec<Vec<AlbumField>>, album: &Album) -> bool {
@ -48,3 +48,99 @@ impl CollectionFilter {
} }
} }
} }
#[cfg(test)]
mod tests {
use crate::collection::{
album::AlbumId,
track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality},
};
use super::*;
fn test_filter() -> CollectionFilter {
CollectionFilter {
include: vec![vec![
AlbumField::PrimaryType(None),
AlbumField::PrimaryType(Some(AlbumPrimaryType::Ep)),
AlbumField::PrimaryType(Some(AlbumPrimaryType::Album)),
]],
except: vec![vec![
AlbumField::SecondaryType(AlbumSecondaryType::Compilation),
AlbumField::SecondaryType(AlbumSecondaryType::Soundtrack),
AlbumField::SecondaryType(AlbumSecondaryType::Live),
AlbumField::SecondaryType(AlbumSecondaryType::Demo),
AlbumField::Ownership(AlbumOwnership::None),
]],
}
}
fn test_track() -> Track {
Track {
id: TrackId {
title: String::from("Track"),
},
number: TrackNum(1),
artist: vec![String::from("Artist")],
quality: TrackQuality {
format: TrackFormat::Mp3,
bitrate: 320,
},
}
}
fn test_album() -> Album {
let mut album = Album::new(AlbumId::new("An Album"));
album.tracks.push(test_track());
album
}
#[test]
fn filter_primary_type() {
let filter = test_filter();
let mut album = test_album();
album.meta.info.primary_type = None;
assert!(filter.filter_album(&album));
album.meta.info.primary_type = Some(AlbumPrimaryType::Ep);
assert!(filter.filter_album(&album));
album.meta.info.primary_type = Some(AlbumPrimaryType::Album);
assert!(filter.filter_album(&album));
album.meta.info.primary_type = Some(AlbumPrimaryType::Broadcast);
assert!(!filter.filter_album(&album));
album.meta.info.primary_type = Some(AlbumPrimaryType::Other);
assert!(!filter.filter_album(&album));
}
#[test]
fn filter_secondary_type() {
let filter = test_filter()
}
#[test]
fn filter_ownership() {
let filter = test_filter();
let mut album = Album::new(AlbumId::new("An Album"));
album.tracks.clear();
assert!(!filter.filter_album(&album));
album.tracks.push(test_track());
assert_eq!(
album.get_ownership(),
AlbumOwnership::Owned(TrackFormat::Mp3)
);
assert!(filter.filter_album(&album));
album.tracks[0].quality.format = TrackFormat::Flac;
assert_eq!(
album.get_ownership(),
AlbumOwnership::Owned(TrackFormat::Flac)
);
assert!(filter.filter_album(&album));
}
}

View File

@ -6,17 +6,21 @@ use ratatui::{backend::CrosstermBackend, Terminal};
use structopt::StructOpt; use structopt::StructOpt;
use musichoard::{ use musichoard::{
collection::album::{AlbumOwnership, AlbumPrimaryType, AlbumSecondaryType}, external::{ collection::album::{AlbumOwnership, AlbumPrimaryType, AlbumSecondaryType},
external::{
database::json::{backend::JsonDatabaseFileBackend, JsonDatabase}, database::json::{backend::JsonDatabaseFileBackend, JsonDatabase},
library::beets::{ library::beets::{
executor::{ssh::BeetsLibrarySshExecutor, BeetsLibraryProcessExecutor}, executor::{ssh::BeetsLibrarySshExecutor, BeetsLibraryProcessExecutor},
BeetsLibrary, BeetsLibrary,
}, },
musicbrainz::{api::MusicBrainzClient, http::MusicBrainzHttp}, musicbrainz::{api::MusicBrainzClient, http::MusicBrainzHttp},
}, filter::{AlbumField, CollectionFilter}, interface::{ },
filter::{AlbumField, CollectionFilter},
interface::{
database::{IDatabase, NullDatabase}, database::{IDatabase, NullDatabase},
library::{ILibrary, NullLibrary}, library::{ILibrary, NullLibrary},
}, IMusicHoardBase, MusicHoardBuilder, NoDatabase, NoLibrary },
IMusicHoardBase, MusicHoardBuilder, NoDatabase, NoLibrary,
}; };
use tui::{ use tui::{
@ -74,23 +78,21 @@ fn default_filter() -> CollectionFilter {
AlbumField::PrimaryType(Some(AlbumPrimaryType::Ep)), AlbumField::PrimaryType(Some(AlbumPrimaryType::Ep)),
AlbumField::PrimaryType(Some(AlbumPrimaryType::Album)), AlbumField::PrimaryType(Some(AlbumPrimaryType::Album)),
]], ]],
exclude: vec![ except: vec![vec![
vec![AlbumField::Ownership(AlbumOwnership::None)], AlbumField::SecondaryType(AlbumSecondaryType::Compilation),
vec![ AlbumField::SecondaryType(AlbumSecondaryType::Soundtrack),
AlbumField::SecondaryType(AlbumSecondaryType::Compilation), AlbumField::SecondaryType(AlbumSecondaryType::Spokenword),
AlbumField::SecondaryType(AlbumSecondaryType::Soundtrack), AlbumField::SecondaryType(AlbumSecondaryType::Interview),
AlbumField::SecondaryType(AlbumSecondaryType::Spokenword), AlbumField::SecondaryType(AlbumSecondaryType::Audiobook),
AlbumField::SecondaryType(AlbumSecondaryType::Interview), AlbumField::SecondaryType(AlbumSecondaryType::AudioDrama),
AlbumField::SecondaryType(AlbumSecondaryType::Audiobook), AlbumField::SecondaryType(AlbumSecondaryType::Live),
AlbumField::SecondaryType(AlbumSecondaryType::AudioDrama), AlbumField::SecondaryType(AlbumSecondaryType::Remix),
AlbumField::SecondaryType(AlbumSecondaryType::Live), AlbumField::SecondaryType(AlbumSecondaryType::DjMix),
AlbumField::SecondaryType(AlbumSecondaryType::Remix), AlbumField::SecondaryType(AlbumSecondaryType::MixtapeStreet),
AlbumField::SecondaryType(AlbumSecondaryType::DjMix), AlbumField::SecondaryType(AlbumSecondaryType::Demo),
AlbumField::SecondaryType(AlbumSecondaryType::MixtapeStreet), AlbumField::SecondaryType(AlbumSecondaryType::FieldRecording),
AlbumField::SecondaryType(AlbumSecondaryType::Demo), AlbumField::Ownership(AlbumOwnership::None),
AlbumField::SecondaryType(AlbumSecondaryType::FieldRecording), ]],
],
],
} }
} }