Track num_songs_by_genre

This commit is contained in:
Antoine Gersant 2024-09-06 01:34:41 -07:00
parent c1f24ce96b
commit 07324ccca6
3 changed files with 50 additions and 20 deletions
src
app/index
server/dto

View file

@ -7,6 +7,7 @@ use std::{
use lasso2::{Rodeo, RodeoReader, Spur};
use rand::{rngs::ThreadRng, seq::IteratorRandom};
use serde::{Deserialize, Serialize};
use tinyvec::TinyVec;
use unicase::UniCase;
use crate::app::index::storage::{self, store_song, AlbumKey, ArtistKey, SongKey};
@ -21,6 +22,7 @@ pub struct ArtistHeader {
pub num_albums_as_additional_performer: u32,
pub num_albums_as_composer: u32,
pub num_albums_as_lyricist: u32,
pub num_songs_by_genre: HashMap<String, u32>,
}
#[derive(Debug, Default, PartialEq, Eq)]
@ -176,6 +178,11 @@ fn make_artist_header(artist: &storage::Artist, strings: &RodeoReader) -> Artist
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,
num_songs_by_genre: artist
.num_songs_by_genre
.iter()
.map(|(genre, num)| (strings.resolve(genre).to_string(), *num))
.collect(),
}
}
@ -198,7 +205,7 @@ impl Builder {
};
self.add_song_to_album(&song);
self.add_album_to_artists(&song);
self.add_song_to_artists(&song);
self.songs.insert(
SongKey {
@ -225,26 +232,32 @@ impl Builder {
}
}
fn add_album_to_artists(&mut self, song: &storage::Song) {
fn add_song_to_artists(&mut self, song: &storage::Song) {
let album_key: AlbumKey = 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);
}
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);
}
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);
}
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) {
@ -253,6 +266,17 @@ impl Builder {
.insert(album_key.clone());
}
}
for name in all_artists {
let artist = self.get_or_create_artist(name);
for genre in &song.genres {
*artist
.num_songs_by_genre
.entry(*genre)
.or_default()
.borrow_mut() += 1;
}
}
}
fn get_or_create_artist(&mut self, name: lasso2::Spur) -> &mut storage::Artist {
@ -265,6 +289,7 @@ impl Builder {
albums_as_additional_performer: HashSet::new(),
albums_as_composer: HashSet::new(),
albums_as_lyricist: HashSet::new(),
num_songs_by_genre: HashMap::new(),
})
.borrow_mut()
}

View file

@ -18,18 +18,19 @@ pub enum File {
#[derive(Serialize, Deserialize)]
pub struct Artist {
pub name: lasso2::Spur,
pub name: Spur,
pub albums_as_performer: HashSet<AlbumKey>,
pub albums_as_additional_performer: HashSet<AlbumKey>,
pub albums_as_composer: HashSet<AlbumKey>,
pub albums_as_lyricist: HashSet<AlbumKey>,
pub num_songs_by_genre: HashMap<Spur, u32>,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Album {
pub name: Option<lasso2::Spur>,
pub name: Option<Spur>,
pub artwork: Option<PathKey>,
pub artists: Vec<lasso2::Spur>,
pub artists: TinyVec<[Spur; 1]>,
pub year: Option<i64>,
pub date_added: i64,
pub songs: HashSet<SongKey>,
@ -41,35 +42,37 @@ pub struct Song {
pub virtual_path: PathKey,
pub track_number: Option<i64>,
pub disc_number: Option<i64>,
pub title: Option<lasso2::Spur>,
pub artists: Vec<lasso2::Spur>,
pub album_artists: Vec<lasso2::Spur>,
pub title: Option<Spur>,
pub artists: TinyVec<[Spur; 1]>,
pub album_artists: TinyVec<[Spur; 1]>,
pub year: Option<i64>,
pub album: Option<lasso2::Spur>,
pub album: Option<Spur>,
pub artwork: Option<PathKey>,
pub duration: Option<i64>,
pub lyricists: Vec<lasso2::Spur>,
pub composers: Vec<lasso2::Spur>,
pub genres: Vec<lasso2::Spur>,
pub labels: Vec<lasso2::Spur>,
pub lyricists: TinyVec<[Spur; 0]>,
pub composers: TinyVec<[Spur; 0]>,
pub genres: TinyVec<[Spur; 1]>,
pub labels: TinyVec<[Spur; 0]>,
pub date_added: i64,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub struct PathKey(pub lasso2::Spur);
#[derive(
Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize,
)]
pub struct PathKey(pub Spur);
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ArtistKey {
pub name: Option<lasso2::Spur>,
pub name: Option<Spur>,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct AlbumKey {
pub artists: TinyVec<[lasso2::Spur; 4]>,
pub name: Option<lasso2::Spur>,
pub artists: TinyVec<[Spur; 4]>,
pub name: Option<Spur>,
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct SongKey {
pub virtual_path: PathKey,
}

View file

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use crate::app::{config, ddns, index, peaks, settings, thumbnail, user, vfs};
use std::{convert::From, path::PathBuf};
use std::{collections::HashMap, convert::From, path::PathBuf};
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct Version {
@ -324,6 +324,7 @@ pub struct ArtistHeader {
pub num_albums_as_additional_performer: u32,
pub num_albums_as_composer: u32,
pub num_albums_as_lyricist: u32,
pub num_songs_by_genre: HashMap<String, u32>,
}
impl From<index::ArtistHeader> for ArtistHeader {
@ -334,6 +335,7 @@ impl From<index::ArtistHeader> for ArtistHeader {
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,
num_songs_by_genre: a.num_songs_by_genre,
}
}
}