diff --git a/src/scanner.rs b/src/scanner.rs index 1077c63..9c9e92c 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -18,7 +18,7 @@ use crate::util::walk_dir; use crate::Cache; use crate::{Config, TaggedFile, TaggedFileCollection}; use futures::FutureExt; -use regex::Regex; +use regex::RegexBuilder; use std::collections::{HashMap, HashSet}; use std::path::PathBuf; use tokio::runtime::{Builder, Runtime}; @@ -138,7 +138,10 @@ impl Drop for Scanner { /// Find track collections in the given path. fn find_track_paths(input_path: PathBuf) -> impl Iterator)> { let supported_extensions = HashSet::from(["mp3", "flac"]); - let disc_pattern = Regex::new(r"^(?:CD|Disc)\s*\d+$").unwrap(); + let disc_pattern = RegexBuilder::new(r"^(?:CD|Disc)\s*\d+$") + .case_insensitive(true) + .build() + .unwrap(); let mut grouped_tracks: HashMap> = HashMap::new(); diff --git a/src/taggedfilecollection.rs b/src/taggedfilecollection.rs index 3dbe403..26a5f6b 100644 --- a/src/taggedfilecollection.rs +++ b/src/taggedfilecollection.rs @@ -19,6 +19,7 @@ use crate::util; use crate::Config; use crate::TaggedFile; use itertools::Itertools; +use regex::{Regex, RegexBuilder}; use std::borrow::Cow; use std::collections::HashMap; @@ -117,6 +118,23 @@ fn find_most_common_tag_value<'a>( MostCommonItem::find(tracks.filter_map(|tagged_file| tagged_file.first_tag_value(key))) } +/// Strip disc suffix from the end of the `Cow` string. +fn strip_disc_suffix<'a>(title: Cow<'a, str>, pattern: &Regex) -> Cow<'a, str> { + match pattern.find(&title) { + Some(m) => { + let start = m.start(); + match title { + Cow::Borrowed(s) => Cow::Borrowed(&s[..start]), + Cow::Owned(mut s) => { + s.truncate(start); + Cow::Owned(s) + } + } + } + None => title, + } +} + /// A collection of tracks on the local disk. #[derive(Debug)] pub struct TaggedFileCollection { @@ -342,7 +360,19 @@ impl FromIterator for TaggedFileCollection { impl ReleaseLike for TaggedFileCollection { fn release_title(&self) -> Option> { - self.find_consensual_tag_value(&TagKey::Album) + let disc_pattern = RegexBuilder::new(r"\s*[(\[-]\s*(?:CD|Disc)\s*\d+\s*[)\]]?\s*$") + .case_insensitive(true) + .build() + .unwrap(); + + MostCommonItem::find( + self.media + .iter() + .flat_map(|media| media.tracks.iter()) + .filter_map(|tagged_file| tagged_file.first_tag_value(&TagKey::Album)) + .map(|title| strip_disc_suffix(title, &disc_pattern)), + ) + .and_then(MostCommonItem::into_concensus) } fn release_artist(&self) -> Option> {