Create NewSong type

This commit is contained in:
2025-05-04 21:35:58 +00:00
parent 9da05edcd4
commit c02363c698
9 changed files with 44 additions and 47 deletions

View File

@ -135,7 +135,7 @@ pub async fn get_songs(id: i32) -> Result<Vec<frontend::Song>, ServerFnError> {
for (album, song, artist, like, dislike) in song_list {
if let Some(song) = song {
if let Some(stored_songdata) = album_songs.get_mut(&song.id.unwrap()) {
if let Some(stored_songdata) = album_songs.get_mut(&song.id) {
// If the song is already in the map, update the artists
if let Some(artist) = artist {
stored_songdata.artists.push(artist);
@ -156,7 +156,7 @@ pub async fn get_songs(id: i32) -> Result<Vec<frontend::Song>, ServerFnError> {
);
let songdata = frontend::Song {
id: song.id.unwrap(),
id: song.id,
title: song.title,
artists: artist.map(|artist| vec![artist]).unwrap_or_default(),
album: Some(album),
@ -166,10 +166,10 @@ pub async fn get_songs(id: i32) -> Result<Vec<frontend::Song>, ServerFnError> {
song_path: song.storage_path,
image_path,
like_dislike,
added_date: song.added_date.unwrap(),
added_date: song.added_date,
};
album_songs.insert(song.id.unwrap(), songdata);
album_songs.insert(song.id, songdata);
}
}
}

View File

@ -143,11 +143,7 @@ pub async fn top_songs_by_artist(
HashMap::with_capacity(top_songs.len());
for (song, album, artist, like, dislike) in top_songs {
let song_id = song.id.ok_or(ServerFnError::ServerError::<NoCustomError>(
"Song id not found in database".to_string(),
))?;
if let Some((stored_songdata, _)) = top_songs_map.get_mut(&song_id) {
if let Some((stored_songdata, _)) = top_songs_map.get_mut(&song.id) {
// If the song is already in the map, update the artists
if let Some(artist) = artist {
stored_songdata.artists.push(artist);
@ -168,7 +164,7 @@ pub async fn top_songs_by_artist(
);
let songdata = frontend::Song {
id: song_id,
id: song.id,
title: song.title,
artists: artist.map(|artist| vec![artist]).unwrap_or_default(),
album,
@ -178,16 +174,16 @@ pub async fn top_songs_by_artist(
song_path: song.storage_path,
image_path,
like_dislike,
added_date: song.added_date.unwrap(),
added_date: song.added_date,
};
let plays = song_play_counts
.get(&song_id)
.get(&song.id)
.ok_or(ServerFnError::ServerError::<NoCustomError>(
"Song id not found in history counts".to_string(),
))?;
top_songs_map.insert(song_id, (songdata, *plays));
top_songs_map.insert(song.id, (songdata, *plays));
}
}

View File

@ -181,7 +181,7 @@ pub async fn recent_songs(
song_path: song.storage_path,
image_path,
like_dislike,
added_date: song.added_date.unwrap(),
added_date: song.added_date,
};
history_songs.insert(song_id, (history.date, songdata));
@ -277,11 +277,7 @@ pub async fn top_songs(
HashMap::with_capacity(history_counts.len());
for (song, album, artist, like, dislike) in history_songs {
let song_id = song.id.ok_or(ServerFnError::ServerError::<NoCustomError>(
"Song id not found in database".to_string(),
))?;
if let Some((_, stored_songdata)) = history_songs_map.get_mut(&song_id) {
if let Some((_, stored_songdata)) = history_songs_map.get_mut(&song.id) {
// If the song is already in the map, update the artists
if let Some(artist) = artist {
stored_songdata.artists.push(artist);
@ -302,7 +298,7 @@ pub async fn top_songs(
);
let songdata = frontend::Song {
id: song_id,
id: song.id,
title: song.title,
artists: artist.map(|artist| vec![artist]).unwrap_or_default(),
album,
@ -312,16 +308,16 @@ pub async fn top_songs(
song_path: song.storage_path,
image_path,
like_dislike,
added_date: song.added_date.unwrap(),
added_date: song.added_date,
};
let plays = history_counts
.get(&song_id)
.get(&song.id)
.ok_or(ServerFnError::ServerError::<NoCustomError>(
"Song id not found in history counts".to_string(),
))?;
history_songs_map.insert(song_id, (*plays, songdata));
history_songs_map.insert(song.id, (*plays, songdata));
}
}

View File

@ -238,7 +238,7 @@ pub async fn search_songs(
HashMap::with_capacity(song_list.len());
for (song, album, artist, like, dislike, score) in song_list {
if let Some((stored_songdata, _score)) = search_songs.get_mut(&song.id.unwrap()) {
if let Some((stored_songdata, _score)) = search_songs.get_mut(&song.id) {
// If the song is already in the map, update the artists
if let Some(artist) = artist {
stored_songdata.artists.push(artist);
@ -259,7 +259,7 @@ pub async fn search_songs(
);
let songdata = frontend::Song {
id: song.id.unwrap(),
id: song.id,
title: song.title,
artists: artist.map(|artist| vec![artist]).unwrap_or_default(),
album,
@ -269,10 +269,10 @@ pub async fn search_songs(
song_path: song.storage_path,
image_path,
like_dislike,
added_date: song.added_date.unwrap(),
added_date: song.added_date,
};
search_songs.insert(song.id.unwrap(), (songdata, score));
search_songs.insert(song.id, (songdata, score));
}
}

View File

@ -131,7 +131,7 @@ pub async fn get_song_by_id(song_id: i32) -> Result<Option<frontend::Song>, Serv
});
Ok(Some(frontend::Song {
id: song.id.unwrap(),
id: song.id,
title: song.title.clone(),
artists,
album: album.clone(),
@ -141,7 +141,7 @@ pub async fn get_song_by_id(song_id: i32) -> Result<Option<frontend::Song>, Serv
song_path: song.storage_path.clone(),
image_path,
like_dislike: Some((like.is_some(), dislike.is_some())),
added_date: song.added_date.unwrap(),
added_date: song.added_date,
}))
}
None => Ok(None),

View File

@ -298,9 +298,8 @@ pub async fn upload(data: MultipartData) -> Result<(), ServerFnError> {
}
// Create the song
use crate::models::backend::Song;
let song = Song {
id: None,
use crate::models::backend::{NewSong, Song};
let song = NewSong {
title,
album_id,
track,
@ -308,7 +307,6 @@ pub async fn upload(data: MultipartData) -> Result<(), ServerFnError> {
release_date,
storage_path: file_name,
image_path: None,
added_date: None, // Defaults to current date
};
// Save the song to the database
@ -323,12 +321,6 @@ pub async fn upload(data: MultipartData) -> Result<(), ServerFnError> {
})?;
// Save the song's artists to the database
let song_id = song.id.ok_or_else(|| {
let msg = "Error saving song to database: song id not found after insertion".to_string();
warn!("{}", msg);
ServerFnError::<NoCustomError>::ServerError(msg)
})?;
use crate::schema::song_artists;
use diesel::ExpressionMethods;
@ -336,7 +328,7 @@ pub async fn upload(data: MultipartData) -> Result<(), ServerFnError> {
.into_iter()
.map(|artist_id| {
(
song_artists::song_id.eq(song_id),
song_artists::song_id.eq(song.id),
song_artists::artist_id.eq(artist_id),
)
})

View File

@ -15,5 +15,6 @@ pub use album::Album;
pub use artist::Artist;
pub use history_entry::HistoryEntry;
pub use playlist::Playlist;
pub use song::NewSong;
pub use song::Song;
pub use user::User;

View File

@ -10,14 +10,13 @@ cfg_if! {
}
/// Model for a song
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Insertable))]
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable))]
#[cfg_attr(feature = "ssr", diesel(table_name = crate::schema::songs))]
#[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))]
#[derive(Clone, Serialize, Deserialize)]
pub struct Song {
/// A unique id for the song
#[cfg_attr(feature = "ssr", diesel(deserialize_as = i32))]
pub id: Option<i32>,
pub id: i32,
/// The song's title
pub title: String,
/// The album the song is from
@ -33,6 +32,19 @@ pub struct Song {
/// The path to the song's image file
pub image_path: Option<String>,
/// The date the song was added to the database
#[cfg_attr(feature = "ssr", diesel(deserialize_as = NaiveDateTime))]
pub added_date: Option<NaiveDateTime>,
pub added_date: NaiveDateTime,
}
/// Model for a new song. Omits automatically generated fields
#[cfg_attr(feature = "ssr", derive(Insertable))]
#[cfg_attr(feature = "ssr", diesel(table_name = crate::schema::songs))]
#[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))]
pub struct NewSong {
pub title: String,
pub album_id: Option<i32>,
pub track: Option<i32>,
pub duration: i32,
pub release_date: Option<NaiveDate>,
pub storage_path: String,
pub image_path: Option<String>,
}

View File

@ -44,7 +44,7 @@ impl TryInto<backend::Song> for Song {
/// due to the way the `image_path` data is handled.
fn try_into(self) -> Result<backend::Song, Self::Error> {
Ok(backend::Song {
id: Some(self.id),
id: self.id,
title: self.title,
album_id: self
.album
@ -67,7 +67,7 @@ impl TryInto<backend::Song> for Song {
Some(self.image_path)
},
added_date: Some(self.added_date),
added_date: self.added_date,
})
}
}