A round of updates
This commit is contained in:
parent
9d5373797c
commit
551459494d
22 changed files with 1030 additions and 493 deletions
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
|
|
@ -1,4 +1,9 @@
|
||||||
{
|
{
|
||||||
"sqltools.useNodeRuntime": true,
|
"sqltools.useNodeRuntime": true,
|
||||||
"sqltools.connections": []
|
"sqltools.connections": [],
|
||||||
}
|
"cSpell.words": [
|
||||||
|
"appender",
|
||||||
|
"audiotags",
|
||||||
|
"powi"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
||||||
1409
Cargo.lock
generated
1409
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,4 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
|
||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
|
||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
|
||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
|
||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
|
||||||
|
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
|
||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
|
||||||
|
|
||||||
pub use super::album::Entity as Album;
|
pub use super::album::Entity as Album;
|
||||||
pub use super::artist::Entity as Artist;
|
pub use super::artist::Entity as Artist;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
|
||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
|
||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6
|
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
|
||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ impl MigrationTrait for Migration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::enum_variant_names)]
|
||||||
#[derive(DeriveIden)]
|
#[derive(DeriveIden)]
|
||||||
pub enum Artist {
|
pub enum Artist {
|
||||||
Table,
|
Table,
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,7 @@ impl MigrationTrait for Migration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::enum_variant_names)]
|
||||||
#[derive(DeriveIden)]
|
#[derive(DeriveIden)]
|
||||||
pub enum Track {
|
pub enum Track {
|
||||||
Table,
|
Table,
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,16 @@ default-run = "rave"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0"
|
||||||
color-eyre = "0.6"
|
color-eyre = "0.6"
|
||||||
md5 = "0.7"
|
md5 = "0.7"
|
||||||
poem = { version = "1.3", features = [
|
poem = { version = "2.0", features = [
|
||||||
"compression",
|
"compression",
|
||||||
"cookie",
|
"cookie",
|
||||||
"session",
|
"session",
|
||||||
"static-files",
|
"static-files",
|
||||||
"xml",
|
"xml",
|
||||||
"tower-compat",
|
"tower-compat",
|
||||||
] }
|
] }
|
||||||
quick-xml = { version = "0.31", features = ["serialize"] }
|
quick-xml = { version = "0.31", features = ["serialize"] }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
|
|
@ -26,11 +26,11 @@ time = { workspace = true, features = ["local-offset"] }
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
tracing-subscriber = { version = "0.3", features = [
|
tracing-subscriber = { version = "0.3", features = [
|
||||||
"env-filter",
|
"env-filter",
|
||||||
"tracing",
|
"tracing",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"time",
|
"time",
|
||||||
"json",
|
"json",
|
||||||
] }
|
] }
|
||||||
url = { version = "2.5", features = ["serde"] }
|
url = { version = "2.5", features = ["serde"] }
|
||||||
url-escape = "0.1"
|
url-escape = "0.1"
|
||||||
|
|
@ -39,10 +39,10 @@ entities = { workspace = true }
|
||||||
migration = { workspace = true }
|
migration = { workspace = true }
|
||||||
once_cell = { version = "1", features = ["parking_lot"] }
|
once_cell = { version = "1", features = ["parking_lot"] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
audiotags = "0.4"
|
audiotags = "0.5"
|
||||||
tracing-appender = "0.2"
|
tracing-appender = "0.2"
|
||||||
blake3 = "1.5"
|
blake3 = "1.5"
|
||||||
image = "0.24"
|
image = "0.25"
|
||||||
nate = "0.4"
|
nate = "0.4"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
http-range = "0.1"
|
http-range = "0.1"
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,7 @@
|
||||||
|
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use migration::{Migrator, MigratorTrait};
|
use migration::{Migrator, MigratorTrait};
|
||||||
use poem::{
|
use poem::{http::StatusCode, listener::TcpListener, middleware, Endpoint, EndpointExt, Route};
|
||||||
http::StatusCode,
|
|
||||||
listener::TcpListener,
|
|
||||||
middleware,
|
|
||||||
web::{CompressionAlgo, CompressionLevel},
|
|
||||||
Endpoint, EndpointExt, Route,
|
|
||||||
};
|
|
||||||
use sea_orm::{ConnectOptions, Database, DatabaseConnection};
|
use sea_orm::{ConnectOptions, Database, DatabaseConnection};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use tracing_appender::non_blocking::WorkerGuard;
|
use tracing_appender::non_blocking::WorkerGuard;
|
||||||
|
|
@ -74,11 +68,6 @@ fn create_route() -> Box<dyn Endpoint<Output = poem::Response>> {
|
||||||
.nest("/", ui::build())
|
.nest("/", ui::build())
|
||||||
.nest("/rest", rest::build())
|
.nest("/rest", rest::build())
|
||||||
.with(middleware::CatchPanic::new())
|
.with(middleware::CatchPanic::new())
|
||||||
.with(
|
|
||||||
middleware::Compression::new()
|
|
||||||
.algorithms([CompressionAlgo::BR, CompressionAlgo::GZIP])
|
|
||||||
.with_quality(CompressionLevel::Default),
|
|
||||||
)
|
|
||||||
.with(middleware::Tracing)
|
.with(middleware::Tracing)
|
||||||
.with(middleware::CookieJarManager::new())
|
.with(middleware::CookieJarManager::new())
|
||||||
.with(middleware::NormalizePath::new(
|
.with(middleware::NormalizePath::new(
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,7 @@ async fn album_to_album_id3(conn: DbTxn, album: &album::Model) -> Result<AlbumId
|
||||||
Ok(AlbumId3::new(album.clone(), artist, genre))
|
Ok(AlbumId3::new(album.clone(), artist, genre))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::no_effect_underscore_binding)]
|
||||||
#[instrument(skip(_conn, _params))]
|
#[instrument(skip(_conn, _params))]
|
||||||
async fn get_album_list_random(
|
async fn get_album_list_random(
|
||||||
_conn: DbTxn,
|
_conn: DbTxn,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use std::{io::Cursor, path::PathBuf};
|
||||||
|
|
||||||
use crate::{json_or_xml, utils::db::DbTxn};
|
use crate::{json_or_xml, utils::db::DbTxn};
|
||||||
use entities::prelude::CoverArt;
|
use entities::prelude::CoverArt;
|
||||||
|
use image::ImageFormat;
|
||||||
use poem::{
|
use poem::{
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
web::{Data, Query},
|
web::{Data, Query},
|
||||||
|
|
@ -134,9 +135,9 @@ pub async fn get_cover_art(
|
||||||
let res = resize.write_to(
|
let res = resize.write_to(
|
||||||
&mut buf,
|
&mut buf,
|
||||||
match ext {
|
match ext {
|
||||||
"jpg" => image::ImageOutputFormat::Jpeg(100),
|
"jpg" => ImageFormat::Jpeg,
|
||||||
"png" => image::ImageOutputFormat::Png,
|
"png" => ImageFormat::Png,
|
||||||
"gif" => image::ImageOutputFormat::Gif,
|
"gif" => ImageFormat::Gif,
|
||||||
_ => {
|
_ => {
|
||||||
return json_or_xml!(auth, SubsonicResponse::new_error(Error::Generic(None)));
|
return json_or_xml!(auth, SubsonicResponse::new_error(Error::Generic(None)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,13 +62,8 @@ pub async fn handle(
|
||||||
am.suffix = Set("flac".to_string());
|
am.suffix = Set("flac".to_string());
|
||||||
am.path = Set(path.to_string_lossy().to_string());
|
am.path = Set(path.to_string_lossy().to_string());
|
||||||
am.is_dir = Set(false);
|
am.is_dir = Set(false);
|
||||||
am.track_number = Set(tag
|
am.track_number = Set(tag.track_number().map(i32::from));
|
||||||
.track_number()
|
if let Some(disc_number) = tag.disc_number().map(i32::from) {
|
||||||
.map(|v| i32::try_from(v).expect("failed to convert track to i32")));
|
|
||||||
if let Some(disc_number) = tag
|
|
||||||
.disc_number()
|
|
||||||
.map(|v| i32::try_from(v).expect("failed to convert disc to i32"))
|
|
||||||
{
|
|
||||||
am.disc_number = Set(disc_number);
|
am.disc_number = Set(disc_number);
|
||||||
}
|
}
|
||||||
am.is_video = Set(false);
|
am.is_video = Set(false);
|
||||||
|
|
@ -165,10 +160,7 @@ async fn find_album(
|
||||||
am.genre_ids = Set(Some(vec![genre_id]));
|
am.genre_ids = Set(Some(vec![genre_id]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
am.song_count = Set(tag
|
am.song_count = Set(tag.total_tracks().map(i64::from).unwrap_or_default());
|
||||||
.total_tracks()
|
|
||||||
.map(|v| i64::try_from(v).expect("Failed to convert total tracks to i32"))
|
|
||||||
.unwrap_or_default());
|
|
||||||
am.duration = Set(tag
|
am.duration = Set(tag
|
||||||
.duration()
|
.duration()
|
||||||
.map(|c| c.round().rem_euclid(2f64.powi(32)) as i64) // TODO: figure out how to do this properly
|
.map(|c| c.round().rem_euclid(2f64.powi(32)) as i64) // TODO: figure out how to do this properly
|
||||||
|
|
|
||||||
|
|
@ -62,13 +62,8 @@ pub async fn handle(
|
||||||
am.suffix = Set("mp3".to_string());
|
am.suffix = Set("mp3".to_string());
|
||||||
am.path = Set(path.to_string_lossy().to_string());
|
am.path = Set(path.to_string_lossy().to_string());
|
||||||
am.is_dir = Set(false);
|
am.is_dir = Set(false);
|
||||||
am.track_number = Set(tag
|
am.track_number = Set(tag.track_number().map(i32::from));
|
||||||
.track_number()
|
if let Some(disc_number) = tag.disc_number().map(i32::from) {
|
||||||
.map(|v| i32::try_from(v).expect("failed to convert track to i32")));
|
|
||||||
if let Some(disc_number) = tag
|
|
||||||
.disc_number()
|
|
||||||
.map(|v| i32::try_from(v).expect("failed to convert disc to i32"))
|
|
||||||
{
|
|
||||||
am.disc_number = Set(disc_number);
|
am.disc_number = Set(disc_number);
|
||||||
}
|
}
|
||||||
am.is_video = Set(false);
|
am.is_video = Set(false);
|
||||||
|
|
@ -165,10 +160,7 @@ async fn find_album(
|
||||||
am.genre_ids = Set(Some(vec![genre_id]));
|
am.genre_ids = Set(Some(vec![genre_id]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
am.song_count = Set(tag
|
am.song_count = Set(tag.total_tracks().map(i64::from).unwrap_or_default());
|
||||||
.total_tracks()
|
|
||||||
.map(|v| i64::try_from(v).expect("Failed to convert total tracks to i32"))
|
|
||||||
.unwrap_or_default());
|
|
||||||
am.duration = Set(tag
|
am.duration = Set(tag
|
||||||
.duration()
|
.duration()
|
||||||
.map(|c| c.round().rem_euclid(2f64.powi(32)) as i64) // TODO: figure out how to do this properly
|
.map(|c| c.round().rem_euclid(2f64.powi(32)) as i64) // TODO: figure out how to do this properly
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use entities::artist;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use time::format_description::well_known::Iso8601;
|
use time::format_description::well_known::Iso8601;
|
||||||
|
|
||||||
|
#[allow(clippy::struct_field_names)]
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct Artist {
|
pub struct Artist {
|
||||||
#[serde(rename = "id")]
|
#[serde(rename = "id")]
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use time::format_description::well_known::Iso8601;
|
||||||
|
|
||||||
use crate::subsonic::{Album, Artist};
|
use crate::subsonic::{Album, Artist};
|
||||||
|
|
||||||
|
#[allow(clippy::struct_field_names)]
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct Child {
|
pub struct Child {
|
||||||
#[serde(rename = "id")]
|
#[serde(rename = "id")]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue