Drop support for blank album names

This commit is contained in:
Antoine Gersant 2024-09-07 16:22:39 -07:00
parent 4072e3b07d
commit 7be9f25cb3
6 changed files with 70 additions and 84 deletions

View file

@ -140,21 +140,21 @@ impl Manager {
.unwrap()
}
pub async fn get_album(
&self,
artists: Vec<String>,
name: Option<String>,
) -> Result<Album, Error> {
pub async fn get_album(&self, artists: Vec<String>, name: String) -> Result<Album, Error> {
spawn_blocking({
let index_manager = self.clone();
move || {
let index = index_manager.index.read().unwrap();
let name = index
.strings
.get(&name)
.ok_or_else(|| Error::AlbumNotFound)?;
let album_key = AlbumKey {
artists: artists
.into_iter()
.filter_map(|a| index.strings.get(a))
.collect(),
name: name.and_then(|n| index.strings.get(n)),
name,
};
index
.collection

View file

@ -38,7 +38,7 @@ pub struct Artist {
#[derive(Debug, Default, PartialEq, Eq)]
pub struct Album {
pub name: Option<String>,
pub name: String,
pub artwork: Option<PathBuf>,
pub artists: Vec<String>,
pub year: Option<i64>,
@ -140,7 +140,7 @@ impl Collection {
songs.sort_by_key(|s| (s.disc_number.unwrap_or(-1), s.track_number.unwrap_or(-1)));
Album {
name: a.name.map(|s| strings.resolve(&s).to_string()),
name: strings.resolve(&a.name).to_string(),
artwork: a
.artwork
.as_ref()
@ -243,37 +243,45 @@ impl Builder {
}
fn add_song_to_artists(&mut self, song: &storage::Song) {
let album_key: AlbumKey = song.album_key();
let album_key = song.album_key();
let mut all_artists = TinyVec::<[Spur; 8]>::new();
for name in &song.album_artists {
let artist = self.get_or_create_artist(*name);
artist.albums_as_performer.insert(album_key.clone());
all_artists.push(*name);
if let Some(album_key) = &album_key {
let artist = self.get_or_create_artist(*name);
artist.albums_as_performer.insert(album_key.clone());
}
}
for name in &song.composers {
let artist = self.get_or_create_artist(*name);
artist.albums_as_composer.insert(album_key.clone());
all_artists.push(*name);
if let Some(album_key) = &album_key {
let artist = self.get_or_create_artist(*name);
artist.albums_as_composer.insert(album_key.clone());
}
}
for name in &song.lyricists {
let artist = self.get_or_create_artist(*name);
artist.albums_as_lyricist.insert(album_key.clone());
all_artists.push(*name);
if let Some(album_key) = &album_key {
let artist = self.get_or_create_artist(*name);
artist.albums_as_lyricist.insert(album_key.clone());
}
}
for name in &song.artists {
let artist = self.get_or_create_artist(*name);
all_artists.push(*name);
if song.album_artists.is_empty() {
artist.albums_as_performer.insert(album_key.clone());
} else if !song.album_artists.contains(name) {
artist
.albums_as_additional_performer
.insert(album_key.clone());
if let Some(album_key) = &album_key {
let artist = self.get_or_create_artist(*name);
if song.album_artists.is_empty() {
artist.albums_as_performer.insert(album_key.clone());
} else if !song.album_artists.contains(name) {
artist
.albums_as_additional_performer
.insert(album_key.clone());
}
}
}
@ -307,12 +315,13 @@ impl Builder {
}
fn add_song_to_album(&mut self, song: &storage::Song) {
let album_key = song.album_key();
let album = self.albums.entry(album_key).or_default().borrow_mut();
let Some(album_key) = song.album_key() else {
return;
};
if album.name.is_none() {
album.name = song.album;
}
let name = album_key.name;
let album = self.albums.entry(album_key).or_default().borrow_mut();
album.name = name;
if album.artwork.is_none() {
album.artwork = song.artwork;
@ -500,10 +509,7 @@ mod test {
assert_eq!(albums.len(), 2);
assert_eq!(
albums
.into_iter()
.map(|a| a.name.unwrap())
.collect::<HashSet<_>>(),
albums.into_iter().map(|a| a.name).collect::<HashSet<_>>(),
HashSet::from_iter(["ISDN".to_owned(), "Lifeforms".to_owned()])
);
}
@ -527,10 +533,7 @@ mod test {
assert_eq!(albums.len(), 2);
assert_eq!(
albums
.into_iter()
.map(|a| a.name.unwrap())
.collect::<Vec<_>>(),
albums.into_iter().map(|a| a.name).collect::<Vec<_>>(),
vec!["ISDN".to_owned(), "Lifeforms".to_owned()]
);
}
@ -617,11 +620,7 @@ mod test {
};
let artist = collection.get_artist(&strings, artist_key).unwrap();
let names = |a: &Vec<Album>| {
a.iter()
.map(|a| a.name.to_owned().unwrap())
.collect::<Vec<_>>()
};
let names = |a: &Vec<Album>| a.iter().map(|a| a.name.to_owned()).collect::<Vec<_>>();
if test.expect_performer {
assert_eq!(names(&artist.albums_as_performer), vec![album_name]);
@ -692,7 +691,7 @@ mod test {
.unwrap()
.albums_as_performer
.into_iter()
.map(|a| a.name.unwrap())
.map(|a| a.name)
.collect::<Vec<_>>();
assert_eq!(
@ -747,7 +746,7 @@ mod test {
&strings,
AlbumKey {
artists: TinyVec::new(),
name: strings.get("Lifeforms"),
name: strings.get("Lifeforms").unwrap(),
},
);

View file

@ -29,7 +29,7 @@ pub struct Artist {
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Album {
pub name: Option<Spur>,
pub name: Spur,
pub artwork: Option<PathKey>,
pub artists: TinyVec<[Spur; 1]>,
pub year: Option<i64>,
@ -70,7 +70,7 @@ pub struct ArtistKey {
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct AlbumKey {
pub artists: TinyVec<[Spur; 4]>,
pub name: Option<Spur>,
pub name: Spur,
}
#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, Serialize, Deserialize)]
@ -79,15 +79,18 @@ pub struct SongKey {
}
impl Song {
pub fn album_key(&self) -> AlbumKey {
pub fn album_key(&self) -> Option<AlbumKey> {
let album_artists = match self.album_artists.is_empty() {
true => &self.artists,
false => &self.album_artists,
};
AlbumKey {
artists: album_artists.iter().cloned().collect(),
name: self.album.clone(),
match self.album {
None => None,
Some(name) => Some(AlbumKey {
artists: album_artists.iter().cloned().collect(),
name,
}),
}
}
}
@ -119,10 +122,15 @@ pub fn store_song(
' ' | '_' | '-' | '\'' => false,
_ => true,
});
minuscules
.entry(cleaned.to_lowercase())
.or_insert_with(|| strings.get_or_intern(s))
.to_owned()
match cleaned.is_empty() {
true => None,
false => Some(
minuscules
.entry(cleaned.to_lowercase())
.or_insert_with(|| strings.get_or_intern(s))
.to_owned(),
),
}
};
Some(Song {
@ -130,47 +138,29 @@ pub fn store_song(
virtual_path,
track_number: song.track_number,
disc_number: song.disc_number,
title: song.title.as_ref().map(&mut canonicalize),
artists: song
.artists
.iter()
.filter(|s| s.len() > 0)
.map(&mut canonicalize)
.collect(),
title: song.title.as_ref().and_then(&mut canonicalize),
artists: song.artists.iter().filter_map(&mut canonicalize).collect(),
album_artists: song
.album_artists
.iter()
.filter(|s| s.len() > 0)
.map(&mut canonicalize)
.filter_map(&mut canonicalize)
.collect(),
year: song.year,
album: song.album.as_ref().map(&mut canonicalize),
album: song.album.as_ref().and_then(&mut canonicalize),
artwork: artwork,
duration: song.duration,
lyricists: song
.lyricists
.iter()
.filter(|s| s.len() > 0)
.map(&mut canonicalize)
.filter_map(&mut canonicalize)
.collect(),
composers: song
.composers
.iter()
.filter(|s| s.len() > 0)
.map(&mut canonicalize)
.collect(),
genres: song
.genres
.iter()
.filter(|s| s.len() > 0)
.map(&mut canonicalize)
.collect(),
labels: song
.labels
.iter()
.filter(|s| s.len() > 0)
.map(&mut canonicalize)
.filter_map(&mut canonicalize)
.collect(),
genres: song.genres.iter().filter_map(&mut canonicalize).collect(),
labels: song.labels.iter().filter_map(&mut canonicalize).collect(),
date_added: song.date_added,
})
}

View file

@ -419,9 +419,7 @@ async fn get_album(
.split(API_ARRAY_SEPARATOR)
.map(str::to_owned)
.collect::<Vec<_>>();
Ok(Json(
index_manager.get_album(artists, Some(name)).await?.into(),
))
Ok(Json(index_manager.get_album(artists, name).await?.into()))
}
async fn get_songs(

View file

@ -363,7 +363,7 @@ impl From<index::Album> for Directory {
false => Some(album.artists.join("")),
},
year: album.year,
album: album.name,
album: Some(album.name),
artwork: album.artwork,
}
}

View file

@ -368,8 +368,7 @@ impl From<index::Artist> for Artist {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct AlbumHeader {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub artwork: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]