mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-21 22:15:40 +00:00
feat(song-info): show absolute file path on Navidrome via native API (#504)
* feat(song-info): show absolute file path on Navidrome via native API
Subsonic's `getSong.view` returns at most a relative path (or none on
Navidrome), so the Path row in the Song Info modal stayed empty for
most users. Feishin and the Navidrome web client surface the full
server-side path by hitting Navidrome's native `/api/song/{id}` instead.
Added an `nd_get_song_path` Tauri command that logs in to the native
API with the active server's credentials, fetches the song, and returns
the `path` string. Wired it into `SongInfoModal`: the Subsonic
`getSong` call still drives the rest of the dialog, and the native call
runs in parallel only when the active server's identity is
"navidrome". When it returns a path, that absolute path replaces the
relative Subsonic value; native-API failures are silent and the modal
falls back to whatever Subsonic provided.
No token cache yet — the modal is opened occasionally enough that one
fresh login per call is fine.
Closes discussion #479.
* docs: changelog entry for PR #504
Logs the Navidrome native-API absolute file path support for the
Song Info dialog in v1.46.0 "## Added".
* docs: settings contributor entry for PR #504, drop competitor mention
Adds the song-info absolute path bullet to Psychotoxical's contributors
list in Settings, and rewords the existing CHANGELOG entry so neither
text references competing clients.
This commit is contained in:
committed by
GitHub
parent
726f3f0ff2
commit
a41e3a624a
@@ -946,6 +946,7 @@ pub fn run() {
|
||||
nd_update_playlist,
|
||||
nd_get_playlist,
|
||||
nd_delete_playlist,
|
||||
nd_get_song_path,
|
||||
search_radio_browser,
|
||||
get_top_radio_stations,
|
||||
fetch_url_bytes,
|
||||
|
||||
@@ -619,3 +619,37 @@ pub(crate) async fn nd_delete_playlist(
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// GET `/api/song/{id}` and return the absolute filesystem `path` field.
|
||||
///
|
||||
/// Subsonic `getSong.view` returns at most a relative path (`Artist/Album/track.flac`),
|
||||
/// or nothing at all on Navidrome. The Navidrome native API exposes the absolute
|
||||
/// path the server stores the file at — same source Feishin and the Navidrome web
|
||||
/// client use for their "show file location" feature. Logs in fresh (no token
|
||||
/// cache yet); the call is occasional (Song Info modal open) so the extra
|
||||
/// roundtrip is acceptable.
|
||||
///
|
||||
/// Returns `Ok(None)` when the response has no `path` field — Navidrome can omit
|
||||
/// it for non-admin users on some configurations.
|
||||
#[tauri::command]
|
||||
pub(crate) async fn nd_get_song_path(
|
||||
server_url: String,
|
||||
username: String,
|
||||
password: String,
|
||||
id: String,
|
||||
) -> Result<Option<String>, String> {
|
||||
let token = navidrome_token(&server_url, &username, &password).await?;
|
||||
let url = format!("{}/api/song/{}", server_url, id);
|
||||
let resp = nd_retry(|| {
|
||||
nd_http_client()
|
||||
.get(&url)
|
||||
.header("X-ND-Authorization", format!("Bearer {}", token))
|
||||
.send()
|
||||
})
|
||||
.await?;
|
||||
if !resp.status().is_success() {
|
||||
return Err(format!("HTTP {}", resp.status()));
|
||||
}
|
||||
let data: serde_json::Value = resp.json().await.map_err(nd_err)?;
|
||||
Ok(data["path"].as_str().map(|s| s.to_string()).filter(|s| !s.is_empty()))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user