Minimal subsonic functionality
All checks were successful
CI / check (push) Successful in 1m12s
CI / docker (push) Successful in 2m2s

This commit is contained in:
Connor Johnstone
2026-03-20 20:04:35 -04:00
parent 0496944923
commit 43f4dad038
5 changed files with 50 additions and 3 deletions

15
Cargo.lock generated
View File

@@ -2423,6 +2423,16 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "quick-xml"
version = "0.37.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "quote"
version = "1.0.45"
@@ -3333,11 +3343,15 @@ dependencies = [
"chrono",
"clap",
"dirs",
"hex",
"md-5",
"quick-xml",
"rand 0.9.2",
"reqwest",
"sea-orm",
"serde",
"serde_json",
"serde_urlencoded",
"serde_yaml",
"shanty-config",
"shanty-data",
@@ -3351,6 +3365,7 @@ dependencies = [
"shanty-watch",
"thiserror",
"tokio",
"tokio-util",
"tracing",
"tracing-actix-web",
"tracing-subscriber",

View File

@@ -38,6 +38,9 @@ pub struct AppConfig {
#[serde(default)]
pub scheduling: SchedulingConfig,
#[serde(default)]
pub subsonic: SubsonicConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -152,6 +155,26 @@ pub struct SchedulingConfig {
pub monitor_interval_hours: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SubsonicConfig {
/// Whether the Subsonic API is enabled.
#[serde(default = "default_true")]
pub enabled: bool,
/// Whether transcoding via ffmpeg is enabled.
#[serde(default = "default_true")]
pub transcoding_enabled: bool,
}
impl Default for SubsonicConfig {
fn default() -> Self {
Self {
enabled: true,
transcoding_enabled: true,
}
}
}
impl Default for SchedulingConfig {
fn default() -> Self {
Self {
@@ -179,6 +202,7 @@ impl Default for AppConfig {
indexing: IndexingConfig::default(),
metadata: MetadataConfig::default(),
scheduling: SchedulingConfig::default(),
subsonic: SubsonicConfig::default(),
}
}
}

View File

@@ -131,13 +131,21 @@ async fn main() -> anyhow::Result<()> {
.service(
actix_files::Files::new("/", static_dir.clone())
.index_file("index.html")
.prefer_utf8(true),
.prefer_utf8(true)
.guard(actix_web::guard::fn_guard(|ctx| {
!ctx.head().uri.path().starts_with("/rest")
})),
)
.default_service(web::to({
let index_path = static_dir.join("index.html");
move |req: actix_web::HttpRequest| {
let index_path = index_path.clone();
async move {
if req.path().starts_with("/rest") {
return Ok(actix_web::HttpResponse::NotFound()
.content_type("application/json")
.body(r#"{"subsonic-response":{"status":"failed","version":"1.16.1","error":{"code":0,"message":"Unknown endpoint"}}}"#));
}
actix_files::NamedFile::open_async(index_path)
.await
.map(|f| f.into_response(&req))