fix(qbz-qt): decode local artwork file URIs

cx
This commit is contained in:
vicrodh committed 2026-08-25 22:27:27 -06:00
1 parent 2d31244a7a
commit 24d778e9cf
3 files changed
+42 -5

No files matched your search

+8 -2
View File
@@ -162,8 +162,12 @@ pub fn classify(url: &str) -> ArtUrl {
}
// A `file://` url is ALREADY on disk — reqwest cannot even build a
// request for it ("builder error for url"), so it must never be fetched.
if let Some(path) = url.strip_prefix("file://") {
return ArtUrl::LocalFile(path.to_string());
if url.starts_with("file://") {
// `local_queue_track` escapes `%`, `#` and `?` before this value
// reaches QML. The filesystem probe needs the inverse, otherwise a
// real `Disc 01 - Soundtrack #01/cover.jpg` is stat'ed as a literal
// `...%2301/cover.jpg` and every queue-owned surface gets a miss.
return ArtUrl::LocalFile(local_path(url));
}
// A SOURCE-TAGGED token (`jellyfin:<albumId>/<tag>`,
// `subsonic:al-<id>_<hash>`), stamped by `local_queue_track` for a media
@@ -892,6 +896,8 @@ mod tests {
classify("/home/u/Music/Album/cover.jpg"),
ArtUrl::LocalFile("/home/u/Music/Album/cover.jpg".into())
);
let raw = "/mnt/music/Disc 01 - Soundtrack #01/100%? cover.jpg";
assert_eq!(classify(&file_url(raw)), ArtUrl::LocalFile(raw.into()));
}
#[test]
+9 -1
View File
@@ -966,7 +966,10 @@ mod tests {
.as_nanos();
let box_dir =
std::env::temp_dir().join(format!("qbz-queue-disc-art-{}-{nonce}", std::process::id()));
let disc_one = box_dir.join("Disc 01 - Sanctuary");
// `#` is the exact seam this fixture protects: QueueTrack carries a
// file URI (`%23`), while the NPB/queue resolver must stat the decoded
// filesystem path and MPRIS must not publish a double-escaped `%2523`.
let disc_one = box_dir.join("Disc 01 - TV Series Soundtrack #01");
let disc_five = box_dir.join("Disc 05 - Movie OST");
std::fs::create_dir_all(&disc_one).unwrap();
std::fs::create_dir_all(&disc_five).unwrap();
@@ -998,6 +1001,11 @@ mod tests {
assert_ne!(one.artwork_url, five.artwork_url);
assert!(one.artwork_url.as_deref().unwrap().contains("Disc 01"));
assert!(five.artwork_url.as_deref().unwrap().contains("Disc 05"));
let one_resolved = crate::artwork_qt::cached_path(one.artwork_url.as_deref().unwrap());
assert_eq!(
crate::artwork_qt::local_path(&one_resolved),
disc_one.join("cover.jpg").to_string_lossy()
);
std::fs::remove_dir_all(&box_dir).unwrap();
}