Artist indexing
This commit is contained in:
parent
ad37a14cfa
commit
0c12729983
3 changed files with 70 additions and 40 deletions
|
@ -17,15 +17,19 @@ use super::storage::fetch_song;
|
||||||
#[derive(Debug, Default, PartialEq, Eq)]
|
#[derive(Debug, Default, PartialEq, Eq)]
|
||||||
pub struct ArtistHeader {
|
pub struct ArtistHeader {
|
||||||
pub name: UniCase<String>,
|
pub name: UniCase<String>,
|
||||||
pub num_own_albums: u32,
|
pub num_albums_as_performer: u32,
|
||||||
pub num_appearances: u32,
|
pub num_albums_as_additional_performer: u32,
|
||||||
|
pub num_albums_as_composer: u32,
|
||||||
|
pub num_albums_as_lyricist: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq, Eq)]
|
#[derive(Debug, Default, PartialEq, Eq)]
|
||||||
pub struct Artist {
|
pub struct Artist {
|
||||||
pub header: ArtistHeader,
|
pub header: ArtistHeader,
|
||||||
pub albums: Vec<Album>,
|
pub albums_as_performer: Vec<Album>,
|
||||||
pub featured_on: Vec<Album>, // Albums where this artist shows up as `artist` without being `album_artist`
|
pub albums_as_additional_performer: Vec<Album>, // Albums where this artist shows up as `artist` without being `album_artist`
|
||||||
|
pub albums_as_composer: Vec<Album>,
|
||||||
|
pub albums_as_lyricist: Vec<Album>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq, Eq)]
|
#[derive(Debug, Default, PartialEq, Eq)]
|
||||||
|
@ -83,9 +87,8 @@ impl Collection {
|
||||||
self.artists.get(&artist_key).map(|a| {
|
self.artists.get(&artist_key).map(|a| {
|
||||||
let sort_albums = |a: &Album, b: &Album| (&a.year, &a.name).cmp(&(&b.year, &b.name));
|
let sort_albums = |a: &Album, b: &Album| (&a.year, &a.name).cmp(&(&b.year, &b.name));
|
||||||
|
|
||||||
let albums = {
|
let list_albums = |keys: &HashSet<AlbumKey>| {
|
||||||
let mut albums = a
|
let mut albums = keys
|
||||||
.albums
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|key| self.get_album(strings, key.clone()))
|
.filter_map(|key| self.get_album(strings, key.clone()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -93,20 +96,17 @@ impl Collection {
|
||||||
albums
|
albums
|
||||||
};
|
};
|
||||||
|
|
||||||
let featured_on = {
|
let albums_as_performer = list_albums(&a.albums_as_performer);
|
||||||
let mut albums = a
|
let albums_as_additional_performer = list_albums(&a.albums_as_additional_performer);
|
||||||
.featured_on
|
let albums_as_composer = list_albums(&a.albums_as_composer);
|
||||||
.iter()
|
let albums_as_lyricist = list_albums(&a.albums_as_lyricist);
|
||||||
.filter_map(|key| self.get_album(strings, key.clone()))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
albums.sort_by(&sort_albums);
|
|
||||||
albums
|
|
||||||
};
|
|
||||||
|
|
||||||
Artist {
|
Artist {
|
||||||
header: make_artist_header(a, strings),
|
header: make_artist_header(a, strings),
|
||||||
albums,
|
albums_as_performer,
|
||||||
featured_on,
|
albums_as_additional_performer,
|
||||||
|
albums_as_composer,
|
||||||
|
albums_as_lyricist,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -172,8 +172,10 @@ impl Collection {
|
||||||
fn make_artist_header(artist: &storage::Artist, strings: &RodeoReader) -> ArtistHeader {
|
fn make_artist_header(artist: &storage::Artist, strings: &RodeoReader) -> ArtistHeader {
|
||||||
ArtistHeader {
|
ArtistHeader {
|
||||||
name: UniCase::new(strings.resolve(&artist.name).to_owned()),
|
name: UniCase::new(strings.resolve(&artist.name).to_owned()),
|
||||||
num_own_albums: artist.albums.len() as u32,
|
num_albums_as_performer: artist.albums_as_performer.len() as u32,
|
||||||
num_appearances: artist.featured_on.len() as u32,
|
num_albums_as_additional_performer: artist.albums_as_additional_performer.len() as u32,
|
||||||
|
num_albums_as_composer: artist.albums_as_composer.len() as u32,
|
||||||
|
num_albums_as_lyricist: artist.albums_as_lyricist.len() as u32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,15 +230,27 @@ impl Builder {
|
||||||
|
|
||||||
for name in &song.album_artists {
|
for name in &song.album_artists {
|
||||||
let artist = self.get_or_create_artist(*name);
|
let artist = self.get_or_create_artist(*name);
|
||||||
artist.albums.insert(album_key.clone());
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
for name in &song.lyricists {
|
||||||
|
let artist = self.get_or_create_artist(*name);
|
||||||
|
artist.albums_as_lyricist.insert(album_key.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
for name in &song.artists {
|
for name in &song.artists {
|
||||||
let artist = self.get_or_create_artist(*name);
|
let artist = self.get_or_create_artist(*name);
|
||||||
if song.album_artists.is_empty() {
|
if song.album_artists.is_empty() {
|
||||||
artist.albums.insert(album_key.clone());
|
artist.albums_as_performer.insert(album_key.clone());
|
||||||
} else if !song.album_artists.contains(name) {
|
} else if !song.album_artists.contains(name) {
|
||||||
artist.featured_on.insert(album_key.clone());
|
artist
|
||||||
|
.albums_as_additional_performer
|
||||||
|
.insert(album_key.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,8 +261,10 @@ impl Builder {
|
||||||
.entry(artist_key)
|
.entry(artist_key)
|
||||||
.or_insert_with(|| storage::Artist {
|
.or_insert_with(|| storage::Artist {
|
||||||
name,
|
name,
|
||||||
albums: HashSet::new(),
|
albums_as_performer: HashSet::new(),
|
||||||
featured_on: HashSet::new(),
|
albums_as_additional_performer: HashSet::new(),
|
||||||
|
albums_as_composer: HashSet::new(),
|
||||||
|
albums_as_lyricist: HashSet::new(),
|
||||||
})
|
})
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
}
|
}
|
||||||
|
@ -576,15 +592,18 @@ mod test {
|
||||||
};
|
};
|
||||||
|
|
||||||
if test.expect_albums {
|
if test.expect_albums {
|
||||||
assert_eq!(names(&artist.albums), vec![album_name]);
|
assert_eq!(names(&artist.albums_as_performer), vec![album_name]);
|
||||||
} else {
|
} else {
|
||||||
assert!(names(&artist.albums).is_empty());
|
assert!(names(&artist.albums_as_performer).is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.expect_featured_on {
|
if test.expect_featured_on {
|
||||||
assert_eq!(names(&artist.featured_on), vec![album_name]);
|
assert_eq!(
|
||||||
|
names(&artist.albums_as_additional_performer),
|
||||||
|
vec![album_name]
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
assert!(names(&artist.featured_on).is_empty());
|
assert!(names(&artist.albums_as_additional_performer).is_empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -627,7 +646,7 @@ mod test {
|
||||||
|
|
||||||
let names = artist
|
let names = artist
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.albums
|
.albums_as_performer
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|a| a.name.unwrap())
|
.map(|a| a.name.unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
|
@ -19,8 +19,10 @@ pub enum File {
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Artist {
|
pub struct Artist {
|
||||||
pub name: lasso2::Spur,
|
pub name: lasso2::Spur,
|
||||||
pub albums: HashSet<AlbumKey>,
|
pub albums_as_performer: HashSet<AlbumKey>,
|
||||||
pub featured_on: HashSet<AlbumKey>,
|
pub albums_as_additional_performer: HashSet<AlbumKey>,
|
||||||
|
pub albums_as_composer: HashSet<AlbumKey>,
|
||||||
|
pub albums_as_lyricist: HashSet<AlbumKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||||
|
|
|
@ -320,16 +320,20 @@ impl From<index::File> for BrowserEntry {
|
||||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct ArtistHeader {
|
pub struct ArtistHeader {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub num_own_albums: u32,
|
pub num_albums_as_performer: u32,
|
||||||
pub num_appearances: u32,
|
pub num_albums_as_additional_performer: u32,
|
||||||
|
pub num_albums_as_composer: u32,
|
||||||
|
pub num_albums_as_lyricist: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<index::ArtistHeader> for ArtistHeader {
|
impl From<index::ArtistHeader> for ArtistHeader {
|
||||||
fn from(a: index::ArtistHeader) -> Self {
|
fn from(a: index::ArtistHeader) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: a.name.to_string(),
|
name: a.name.to_string(),
|
||||||
num_own_albums: a.num_own_albums,
|
num_albums_as_performer: a.num_albums_as_performer,
|
||||||
num_appearances: a.num_appearances,
|
num_albums_as_additional_performer: a.num_albums_as_additional_performer,
|
||||||
|
num_albums_as_composer: a.num_albums_as_composer,
|
||||||
|
num_albums_as_lyricist: a.num_albums_as_lyricist,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -338,16 +342,21 @@ impl From<index::ArtistHeader> for ArtistHeader {
|
||||||
pub struct Artist {
|
pub struct Artist {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub header: ArtistHeader,
|
pub header: ArtistHeader,
|
||||||
pub albums: Vec<AlbumHeader>,
|
pub albums_as_performer: Vec<AlbumHeader>,
|
||||||
pub featured_on: Vec<AlbumHeader>,
|
pub albums_as_additional_performer: Vec<AlbumHeader>,
|
||||||
|
pub albums_as_composer: Vec<AlbumHeader>,
|
||||||
|
pub albums_as_lyricist: Vec<AlbumHeader>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<index::Artist> for Artist {
|
impl From<index::Artist> for Artist {
|
||||||
fn from(a: index::Artist) -> Self {
|
fn from(a: index::Artist) -> Self {
|
||||||
|
let convert_albums = |a: Vec<index::Album>| a.into_iter().map(|a| a.into()).collect();
|
||||||
Self {
|
Self {
|
||||||
header: a.header.into(),
|
header: a.header.into(),
|
||||||
albums: a.albums.into_iter().map(|a| a.into()).collect(),
|
albums_as_performer: convert_albums(a.albums_as_performer),
|
||||||
featured_on: a.featured_on.into_iter().map(|a| a.into()).collect(),
|
albums_as_additional_performer: convert_albums(a.albums_as_additional_performer),
|
||||||
|
albums_as_composer: convert_albums(a.albums_as_composer),
|
||||||
|
albums_as_lyricist: convert_albums(a.albums_as_lyricist),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue