From b18d0dd747d8c8defb0dd37264231aa567bcd93c Mon Sep 17 00:00:00 2001 From: Lyssieth Date: Mon, 9 Oct 2023 22:24:32 +0300 Subject: [PATCH] refactor: app -> rave; and some other poking --- Cargo.toml | 2 +- app/src/rest/get_album.rs | 30 ----- entities/src/album.rs | 25 +++- entities/src/artist.rs | 24 +++- entities/src/cover_art.rs | 42 ++++++ entities/src/lib.rs | 2 + entities/src/prelude.rs | 2 + entities/src/track.rs | 72 ++++++++++ migration/src/lib.rs | 8 +- .../src/m20231009_181104_create_cover_art.rs | 40 ++++++ ...t.rs => m20231009_181204_create_artist.rs} | 22 +++- .../src/m20231009_181346_create_album.rs | 21 ++- .../src/m20231009_185712_create_track.rs | 124 ++++++++++++++++++ {app => rave}/Cargo.toml | 1 + {app => rave}/src/authentication.rs | 0 {app => rave}/src/authentication/de.rs | 0 {app => rave}/src/main.rs | 0 {app => rave}/src/random_types.rs | 0 {app => rave}/src/random_types/sort_type.rs | 0 rave/src/rest/get_album.rs | 56 ++++++++ {app => rave}/src/rest/get_album_list.rs | 27 +++- {app => rave}/src/rest/get_license.rs | 0 {app => rave}/src/rest/get_music_folders.rs | 0 {app => rave}/src/rest/mod.rs | 0 {app => rave}/src/rest/ping.rs | 0 {app => rave}/src/rest/stream.rs | 0 {app => rave}/src/subsonic.rs | 6 +- {app => rave}/src/ui/mod.rs | 0 {app => rave}/src/utils.rs | 0 29 files changed, 453 insertions(+), 51 deletions(-) delete mode 100644 app/src/rest/get_album.rs create mode 100644 entities/src/cover_art.rs create mode 100644 entities/src/track.rs create mode 100644 migration/src/m20231009_181104_create_cover_art.rs rename migration/src/{m20231009_181104_create_artist.rs => m20231009_181204_create_artist.rs} (75%) create mode 100644 migration/src/m20231009_185712_create_track.rs rename {app => rave}/Cargo.toml (97%) rename {app => rave}/src/authentication.rs (100%) rename {app => rave}/src/authentication/de.rs (100%) rename {app => rave}/src/main.rs (100%) rename {app => rave}/src/random_types.rs (100%) rename {app => rave}/src/random_types/sort_type.rs (100%) create mode 100644 rave/src/rest/get_album.rs rename {app => rave}/src/rest/get_album_list.rs (91%) rename {app => rave}/src/rest/get_license.rs (100%) rename {app => rave}/src/rest/get_music_folders.rs (100%) rename {app => rave}/src/rest/mod.rs (100%) rename {app => rave}/src/rest/ping.rs (100%) rename {app => rave}/src/rest/stream.rs (100%) rename {app => rave}/src/subsonic.rs (98%) rename {app => rave}/src/ui/mod.rs (100%) rename {app => rave}/src/utils.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index f5297dc..862a8ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["app", "entities", "migration"] +members = ["rave", "entities", "migration"] resolver = "2" [workspace.dependencies] diff --git a/app/src/rest/get_album.rs b/app/src/rest/get_album.rs deleted file mode 100644 index 986e746..0000000 --- a/app/src/rest/get_album.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::{ - authentication::Authentication, - subsonic::SubsonicResponse, - utils::{self}, -}; - -use poem::web::{Data, Query}; -use poem_ext::db::DbTxn; -use serde::Deserialize; - -#[poem::handler] -pub async fn get_album( - Data(txn): Data<&DbTxn>, - auth: Authentication, - Query(params): Query, -) -> SubsonicResponse { - let u = utils::verify_user(txn.clone(), auth).await; - - match u { - Ok(_) => {} - Err(e) => return e, - } - - todo!("get_album not implemented"); -} - -#[derive(Debug, Clone, Deserialize)] -pub struct GetAlbumParams { - pub id: i32, -} diff --git a/entities/src/album.rs b/entities/src/album.rs index a555eb5..54fbcab 100644 --- a/entities/src/album.rs +++ b/entities/src/album.rs @@ -9,9 +9,8 @@ pub struct Model { #[sea_orm(primary_key)] pub id: i64, pub name: String, - pub artist: Option, pub artist_id: Option, - pub cover_art: Option, + pub cover_art_id: Option, pub song_count: i32, pub duration: i64, pub play_count: i64, @@ -32,6 +31,14 @@ pub enum Relation { on_delete = "SetNull" )] Artist, + #[sea_orm( + belongs_to = "super::cover_art::Entity", + from = "Column::CoverArtId", + to = "super::cover_art::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + CoverArt, #[sea_orm( belongs_to = "super::music_folder::Entity", from = "Column::MusicFolderId", @@ -40,6 +47,8 @@ pub enum Relation { on_delete = "Cascade" )] MusicFolder, + #[sea_orm(has_many = "super::track::Entity")] + Track, } impl Related for Entity { @@ -48,10 +57,22 @@ impl Related for Entity { } } +impl Related for Entity { + fn to() -> RelationDef { + Relation::CoverArt.def() + } +} + impl Related for Entity { fn to() -> RelationDef { Relation::MusicFolder.def() } } +impl Related for Entity { + fn to() -> RelationDef { + Relation::Track.def() + } +} + impl ActiveModelBehavior for ActiveModel {} diff --git a/entities/src/artist.rs b/entities/src/artist.rs index 8a1a689..09513b1 100644 --- a/entities/src/artist.rs +++ b/entities/src/artist.rs @@ -10,7 +10,7 @@ pub struct Model { pub id: i64, #[sea_orm(unique)] pub name: String, - pub cover_art: Option, + pub cover_art_id: Option, pub artist_image_url: Option, pub album_count: i32, pub starred: bool, @@ -20,6 +20,16 @@ pub struct Model { pub enum Relation { #[sea_orm(has_many = "super::album::Entity")] Album, + #[sea_orm( + belongs_to = "super::cover_art::Entity", + from = "Column::CoverArtId", + to = "super::cover_art::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + CoverArt, + #[sea_orm(has_many = "super::track::Entity")] + Track, } impl Related for Entity { @@ -28,4 +38,16 @@ impl Related for Entity { } } +impl Related for Entity { + fn to() -> RelationDef { + Relation::CoverArt.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Track.def() + } +} + impl ActiveModelBehavior for ActiveModel {} diff --git a/entities/src/cover_art.rs b/entities/src/cover_art.rs new file mode 100644 index 0000000..48ecdfe --- /dev/null +++ b/entities/src/cover_art.rs @@ -0,0 +1,42 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3 + +use sea_orm::entity::prelude::*; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] +#[sea_orm(table_name = "cover_art")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub path: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::album::Entity")] + Album, + #[sea_orm(has_many = "super::artist::Entity")] + Artist, + #[sea_orm(has_many = "super::track::Entity")] + Track, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Album.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Artist.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Track.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/entities/src/lib.rs b/entities/src/lib.rs index 986f8c1..4212510 100644 --- a/entities/src/lib.rs +++ b/entities/src/lib.rs @@ -4,5 +4,7 @@ pub mod prelude; pub mod album; pub mod artist; +pub mod cover_art; pub mod music_folder; +pub mod track; pub mod user; diff --git a/entities/src/prelude.rs b/entities/src/prelude.rs index 72c6250..4030456 100644 --- a/entities/src/prelude.rs +++ b/entities/src/prelude.rs @@ -2,5 +2,7 @@ pub use super::album::Entity as Album; pub use super::artist::Entity as Artist; +pub use super::cover_art::Entity as CoverArt; pub use super::music_folder::Entity as MusicFolder; +pub use super::track::Entity as Track; pub use super::user::Entity as User; diff --git a/entities/src/track.rs b/entities/src/track.rs new file mode 100644 index 0000000..3d7c2dd --- /dev/null +++ b/entities/src/track.rs @@ -0,0 +1,72 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3 + +use sea_orm::entity::prelude::*; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] +#[sea_orm(table_name = "track")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i64, + pub title: String, + pub album_id: Option, + pub artist_id: Option, + pub is_dir: bool, + pub cover_art_id: Option, + pub created: DateTimeWithTimeZone, + pub duration: i64, + pub bit_rate: i64, + pub size: i64, + pub suffix: String, + pub content_type: String, + pub is_video: bool, + pub path: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::album::Entity", + from = "Column::AlbumId", + to = "super::album::Column::Id", + on_update = "Cascade", + on_delete = "Cascade" + )] + Album, + #[sea_orm( + belongs_to = "super::artist::Entity", + from = "Column::ArtistId", + to = "super::artist::Column::Id", + on_update = "Cascade", + on_delete = "Cascade" + )] + Artist, + #[sea_orm( + belongs_to = "super::cover_art::Entity", + from = "Column::CoverArtId", + to = "super::cover_art::Column::Id", + on_update = "Cascade", + on_delete = "Cascade" + )] + CoverArt, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Album.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Artist.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::CoverArt.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 0b1424e..8ac29f6 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -2,8 +2,10 @@ pub use sea_orm_migration::prelude::*; mod m20220101_000001_create_user; mod m20231009_181004_create_music_folder; -mod m20231009_181104_create_artist; +mod m20231009_181104_create_cover_art; +mod m20231009_181204_create_artist; mod m20231009_181346_create_album; +mod m20231009_185712_create_track; pub struct Migrator; @@ -13,8 +15,10 @@ impl MigratorTrait for Migrator { vec![ Box::new(m20220101_000001_create_user::Migration), Box::new(m20231009_181004_create_music_folder::Migration), - Box::new(m20231009_181104_create_artist::Migration), + Box::new(m20231009_181104_create_cover_art::Migration), + Box::new(m20231009_181204_create_artist::Migration), Box::new(m20231009_181346_create_album::Migration), + Box::new(m20231009_185712_create_track::Migration), ] } } diff --git a/migration/src/m20231009_181104_create_cover_art.rs b/migration/src/m20231009_181104_create_cover_art.rs new file mode 100644 index 0000000..100e8ed --- /dev/null +++ b/migration/src/m20231009_181104_create_cover_art.rs @@ -0,0 +1,40 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(CoverArt::Table) + .if_not_exists() + .col( + ColumnDef::new(CoverArt::Id) + .integer() + .not_null() + .auto_increment() + .primary_key() + .unique_key(), + ) + .col(ColumnDef::new(CoverArt::Path).string().not_null()) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(CoverArt::Table).to_owned()) + .await + } +} + +#[derive(DeriveIden)] +pub enum CoverArt { + Table, + Id, + Path, +} diff --git a/migration/src/m20231009_181104_create_artist.rs b/migration/src/m20231009_181204_create_artist.rs similarity index 75% rename from migration/src/m20231009_181104_create_artist.rs rename to migration/src/m20231009_181204_create_artist.rs index a8fc2ef..c143091 100644 --- a/migration/src/m20231009_181104_create_artist.rs +++ b/migration/src/m20231009_181204_create_artist.rs @@ -1,5 +1,7 @@ use sea_orm_migration::prelude::*; +use crate::m20231009_181104_create_cover_art::CoverArt; + #[derive(DeriveMigrationName)] pub struct Migration; @@ -25,7 +27,7 @@ impl MigrationTrait for Migration { .not_null() .unique_key(), ) - .col(ColumnDef::new(Artist::CoverArt).string().null()) + .col(ColumnDef::new(Artist::CoverArtId).big_integer().null()) .col(ColumnDef::new(Artist::ArtistImageUrl).string().null()) .col( ColumnDef::new(Artist::AlbumCount) @@ -41,7 +43,21 @@ impl MigrationTrait for Migration { ) .to_owned(), ) - .await + .await?; + + manager + .create_foreign_key( + ForeignKey::create() + .from_tbl(Artist::Table) + .from_col(Artist::CoverArtId) + .to_tbl(CoverArt::Table) + .to_col(CoverArt::Id) + .on_delete(ForeignKeyAction::SetNull) + .to_owned(), + ) + .await?; + + Ok(()) } async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { @@ -56,7 +72,7 @@ pub enum Artist { Table, Id, Name, - CoverArt, + CoverArtId, ArtistImageUrl, AlbumCount, Starred, diff --git a/migration/src/m20231009_181346_create_album.rs b/migration/src/m20231009_181346_create_album.rs index 3e281c6..de89305 100644 --- a/migration/src/m20231009_181346_create_album.rs +++ b/migration/src/m20231009_181346_create_album.rs @@ -1,7 +1,8 @@ use sea_orm_migration::prelude::*; use crate::{ - m20231009_181004_create_music_folder::MusicFolder, m20231009_181104_create_artist::Artist, + m20231009_181004_create_music_folder::MusicFolder, m20231009_181104_create_cover_art::CoverArt, + m20231009_181204_create_artist::Artist, }; #[derive(DeriveMigrationName)] @@ -23,9 +24,8 @@ impl MigrationTrait for Migration { .primary_key(), ) .col(ColumnDef::new(Album::Name).string().not_null()) - .col(ColumnDef::new(Album::Artist).string().null()) .col(ColumnDef::new(Album::ArtistId).big_integer().null()) - .col(ColumnDef::new(Album::CoverArt).string().null()) + .col(ColumnDef::new(Album::CoverArtId).big_integer().null()) .col(ColumnDef::new(Album::SongCount).integer().not_null()) .col(ColumnDef::new(Album::Duration).big_integer().not_null()) .col( @@ -75,6 +75,18 @@ impl MigrationTrait for Migration { ) .await?; + manager + .create_foreign_key( + ForeignKey::create() + .from_tbl(Album::Table) + .from_col(Album::CoverArtId) + .to_tbl(CoverArt::Table) + .to_col(CoverArt::Id) + .on_delete(ForeignKeyAction::SetNull) + .to_owned(), + ) + .await?; + Ok(()) } @@ -90,9 +102,8 @@ pub enum Album { Table, Id, Name, - Artist, ArtistId, - CoverArt, + CoverArtId, SongCount, Duration, PlayCount, diff --git a/migration/src/m20231009_185712_create_track.rs b/migration/src/m20231009_185712_create_track.rs new file mode 100644 index 0000000..7e8dd9a --- /dev/null +++ b/migration/src/m20231009_185712_create_track.rs @@ -0,0 +1,124 @@ +use sea_orm_migration::prelude::*; + +use crate::{ + m20231009_181104_create_cover_art::CoverArt, m20231009_181204_create_artist::Artist, + m20231009_181346_create_album::Album, +}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(Track::Table) + .if_not_exists() + .col( + ColumnDef::new(Track::Id) + .big_integer() + .not_null() + .auto_increment() + .primary_key() + .unique_key(), + ) + .col(ColumnDef::new(Track::Title).string().not_null()) + .col(ColumnDef::new(Track::AlbumId).big_integer().null()) + .col(ColumnDef::new(Track::ArtistId).big_integer().null()) + .col( + ColumnDef::new(Track::IsDir) + .boolean() + .not_null() + .default(false), + ) + .col(ColumnDef::new(Track::CoverArtId).big_integer().null()) + .col( + ColumnDef::new(Track::Created) + .timestamp_with_time_zone() + .not_null(), + ) + .col(ColumnDef::new(Track::Duration).big_integer().not_null()) + .col(ColumnDef::new(Track::BitRate).big_integer().not_null()) + .col(ColumnDef::new(Track::Size).big_integer().not_null()) + .col(ColumnDef::new(Track::Suffix).string().not_null()) + .col(ColumnDef::new(Track::ContentType).string().not_null()) + .col( + ColumnDef::new(Track::IsVideo) + .boolean() + .not_null() + .default(false), + ) + .col(ColumnDef::new(Track::Path).string().not_null()) + .to_owned(), + ) + .await?; + + manager + .create_foreign_key( + ForeignKey::create() + .from_tbl(Track::Table) + .from_col(Track::AlbumId) + .to_tbl(Album::Table) + .to_col(Album::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) + .to_owned(), + ) + .await?; + + manager + .create_foreign_key( + ForeignKey::create() + .from_tbl(Track::Table) + .from_col(Track::ArtistId) + .to_tbl(Artist::Table) + .to_col(Artist::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) + .to_owned(), + ) + .await?; + + manager + .create_foreign_key( + ForeignKey::create() + .from_tbl(Track::Table) + .from_col(Track::CoverArtId) + .to_tbl(CoverArt::Table) + .to_col(CoverArt::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) + .to_owned(), + ) + .await?; + + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Track::Table).to_owned()) + .await + } +} + +#[derive(DeriveIden)] +pub enum Track { + Table, + Id, + Title, + AlbumId, + ArtistId, + IsDir, + CoverArtId, + Created, + Duration, + BitRate, + Size, + Suffix, + ContentType, + IsVideo, + Path, +} diff --git a/app/Cargo.toml b/rave/Cargo.toml similarity index 97% rename from app/Cargo.toml rename to rave/Cargo.toml index 0b4a9ae..062eed7 100644 --- a/app/Cargo.toml +++ b/rave/Cargo.toml @@ -3,6 +3,7 @@ name = "rave" version = "0.1.0" edition = "2021" publish = ["forge-lys-ee"] +default-run = "rave" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/app/src/authentication.rs b/rave/src/authentication.rs similarity index 100% rename from app/src/authentication.rs rename to rave/src/authentication.rs diff --git a/app/src/authentication/de.rs b/rave/src/authentication/de.rs similarity index 100% rename from app/src/authentication/de.rs rename to rave/src/authentication/de.rs diff --git a/app/src/main.rs b/rave/src/main.rs similarity index 100% rename from app/src/main.rs rename to rave/src/main.rs diff --git a/app/src/random_types.rs b/rave/src/random_types.rs similarity index 100% rename from app/src/random_types.rs rename to rave/src/random_types.rs diff --git a/app/src/random_types/sort_type.rs b/rave/src/random_types/sort_type.rs similarity index 100% rename from app/src/random_types/sort_type.rs rename to rave/src/random_types/sort_type.rs diff --git a/rave/src/rest/get_album.rs b/rave/src/rest/get_album.rs new file mode 100644 index 0000000..8d145f2 --- /dev/null +++ b/rave/src/rest/get_album.rs @@ -0,0 +1,56 @@ +use crate::{ + authentication::Authentication, + subsonic::{Error, SubsonicResponse}, + utils, +}; + +use entities::prelude::{Album, Track}; +use poem::web::{Data, Query}; +use poem_ext::db::DbTxn; +use sea_orm::{EntityTrait, ModelTrait}; +use serde::Deserialize; +use tracing::warn; + +#[poem::handler] +pub async fn get_album( + Data(txn): Data<&DbTxn>, + auth: Authentication, + Query(params): Query, +) -> SubsonicResponse { + let txn = txn.clone(); + let u = utils::verify_user(txn.clone(), auth).await; + + match u { + Ok(_) => {} + Err(e) => return e, + } + + let album = Album::find_by_id(params.id).one(&*txn).await; + let Ok(Some(album)) = album else { + match album { + Ok(Some(_)) => unreachable!("Some(album) covered by `let .. else`"), + Ok(None) => return SubsonicResponse::new_error(Error::RequestedDataWasNotFound(None)), + Err(e) => { + warn!("Error getting album: {}", e); + return SubsonicResponse::new_error(Error::Generic(None)); + } + } + }; + + let tracks = album.find_related(Track).all(&*txn).await; + + let tracks = match tracks { + Ok(t) => t, + Err(e) => { + warn!("Error getting tracks: {}", e); + return SubsonicResponse::new_error(Error::Generic(None)); + } + }; + + SubsonicResponse::new_album(album, tracks) +} + +#[derive(Debug, Clone, Deserialize)] +pub struct GetAlbumParams { + pub id: i32, +} diff --git a/app/src/rest/get_album_list.rs b/rave/src/rest/get_album_list.rs similarity index 91% rename from app/src/rest/get_album_list.rs rename to rave/src/rest/get_album_list.rs index b53cdda..cffe607 100644 --- a/app/src/rest/get_album_list.rs +++ b/rave/src/rest/get_album_list.rs @@ -1,10 +1,17 @@ #![allow(clippy::unused_async)] // todo: remove -use entities::{album, prelude::Album}; -use poem::web::{Data, Query}; +use entities::{ + album, artist, + prelude::{Album, Artist}, +}; +use poem::{ + web::{Data, Query}, + Request, +}; use poem_ext::db::DbTxn; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter, QueryOrder, QuerySelect}; use serde::Deserialize; +use tracing::debug; use crate::{ authentication::Authentication, @@ -24,6 +31,7 @@ macro_rules! error_or { #[poem::handler] pub async fn get_album_list( + req: &Request, Data(txn): Data<&DbTxn>, auth: Authentication, Query(params): Query, @@ -55,7 +63,14 @@ pub async fn get_album_list( }; match album_list { - Ok(a) => SubsonicResponse::new_album_list(a), + Ok(a) => { + debug!("uri path: {}", req.uri().path()); + if req.uri().path().contains("getAlbumList2") { + SubsonicResponse::new_album_list2(a) + } else { + SubsonicResponse::new_album_list(a) + } + } Err(e) => SubsonicResponse::new_error(e), } } @@ -141,12 +156,16 @@ async fn get_album_list_alphabetical_by_artist( params: GetAlbumListParams, ) -> Result, Error> { let albums = Album::find() - .order_by_desc(album::Column::Artist) + .filter(album::Column::ArtistId.is_not_null()) + .find_also_related(Artist) + .order_by_desc(artist::Column::Name) .limit(params.size) .offset(params.offset) .all(&*conn) .await; + let albums = albums.map(|c| c.into_iter().map(|c| c.0).collect()); + error_or!(albums) } diff --git a/app/src/rest/get_license.rs b/rave/src/rest/get_license.rs similarity index 100% rename from app/src/rest/get_license.rs rename to rave/src/rest/get_license.rs diff --git a/app/src/rest/get_music_folders.rs b/rave/src/rest/get_music_folders.rs similarity index 100% rename from app/src/rest/get_music_folders.rs rename to rave/src/rest/get_music_folders.rs diff --git a/app/src/rest/mod.rs b/rave/src/rest/mod.rs similarity index 100% rename from app/src/rest/mod.rs rename to rave/src/rest/mod.rs diff --git a/app/src/rest/ping.rs b/rave/src/rest/ping.rs similarity index 100% rename from app/src/rest/ping.rs rename to rave/src/rest/ping.rs diff --git a/app/src/rest/stream.rs b/rave/src/rest/stream.rs similarity index 100% rename from app/src/rest/stream.rs rename to rave/src/rest/stream.rs diff --git a/app/src/subsonic.rs b/rave/src/subsonic.rs similarity index 98% rename from app/src/subsonic.rs rename to rave/src/subsonic.rs index 6d9fc4f..5818494 100644 --- a/app/src/subsonic.rs +++ b/rave/src/subsonic.rs @@ -2,7 +2,7 @@ use std::fmt::Display; -use entities::album; +use entities::{album, track}; use poem::{http::StatusCode, IntoResponse, Response}; use serde::{ser::SerializeStruct, Serialize}; use time::OffsetDateTime; @@ -51,7 +51,7 @@ impl SubsonicResponse { Self::new(SubResponseType::AlbumList2 { albums }) } - pub fn new_album(album: album::Model, songs: Vec) -> Self { + pub fn new_album(album: album::Model, songs: Vec) -> Self { Self::new(SubResponseType::Album { album, songs }) } @@ -98,7 +98,7 @@ pub enum SubResponseType { #[serde(flatten)] album: album::Model, #[serde(flatten)] - songs: Vec, + songs: Vec, }, Empty, } diff --git a/app/src/ui/mod.rs b/rave/src/ui/mod.rs similarity index 100% rename from app/src/ui/mod.rs rename to rave/src/ui/mod.rs diff --git a/app/src/utils.rs b/rave/src/utils.rs similarity index 100% rename from app/src/utils.rs rename to rave/src/utils.rs