URL encode paths

This commit is contained in:
Sijmen 2023-05-02 11:04:08 +02:00
parent 3ec9af38e0
commit 7b9684e4fb
Signed by: vijfhoek
GPG key ID: DAF7821E067D9C48
6 changed files with 21 additions and 14 deletions

1
Cargo.lock generated
View file

@ -665,6 +665,7 @@ dependencies = [
"async-std", "async-std",
"infer 0.13.0", "infer 0.13.0",
"mpdrs", "mpdrs",
"percent-encoding",
"serde", "serde",
"serde_qs 0.12.0", "serde_qs 0.12.0",
"tide", "tide",

View file

@ -12,6 +12,7 @@ askama_tide = "0.15.0"
async-std = { version = "1.12.0", features = ["attributes"] } async-std = { version = "1.12.0", features = ["attributes"] }
infer = { version = "0.13.0", default-features = false } infer = { version = "0.13.0", default-features = false }
mpdrs = "0.1.0" mpdrs = "0.1.0"
percent-encoding = "2.2.0"
serde = { version = "1.0.160", features = ["derive"] } serde = { version = "1.0.160", features = ["derive"] }
serde_qs = "0.12.0" serde_qs = "0.12.0"
tide = "0.16.0" tide = "0.16.0"

View file

@ -1,6 +1,7 @@
use std::path::Path; use std::path::Path;
use askama::Template; use askama::Template;
use percent_encoding::percent_decode_str;
use serde::Deserialize; use serde::Deserialize;
mod mpd; mod mpd;
@ -74,10 +75,11 @@ struct BrowserTemplate {
async fn get_browser(req: tide::Request<()>) -> tide::Result { async fn get_browser(req: tide::Request<()>) -> tide::Result {
let query: IndexQuery = req.query()?; let query: IndexQuery = req.query()?;
let entries = mpd::ls(&query.path)?; let path = percent_decode_str(&query.path).decode_utf8_lossy();
let entries = mpd::ls(&path)?;
let template = BrowserTemplate { let template = BrowserTemplate {
path: Path::new(&query.path) path: Path::new(&*path)
.iter() .iter()
.map(|s| s.to_string_lossy().to_string()) .map(|s| s.to_string_lossy().to_string())
.collect(), .collect(),
@ -94,7 +96,8 @@ struct PostQueueQuery {
async fn post_queue(req: tide::Request<()>) -> tide::Result { async fn post_queue(req: tide::Request<()>) -> tide::Result {
let query: PostQueueQuery = req.query()?; let query: PostQueueQuery = req.query()?;
mpd::connect()?.add(&query.path)?; let path = percent_decode_str(&query.path).decode_utf8_lossy();
mpd::connect()?.add(&path)?;
Ok("".into()) Ok("".into())
} }
@ -141,7 +144,8 @@ async fn post_queue_move(mut req: tide::Request<()>) -> tide::Result {
async fn get_art(req: tide::Request<()>) -> tide::Result { async fn get_art(req: tide::Request<()>) -> tide::Result {
let query: IndexQuery = req.query()?; let query: IndexQuery = req.query()?;
let resp = if let Ok(art) = mpd::connect()?.albumart(&query.path) { let path = percent_decode_str(&query.path).decode_utf8_lossy();
let resp = if let Ok(art) = mpd::connect()?.albumart(&path) {
let mime = infer::get(&art) let mime = infer::get(&art)
.map(|k| k.mime_type()) .map(|k| k.mime_type())
.unwrap_or("application/octet-stream"); .unwrap_or("application/octet-stream");

View file

@ -15,10 +15,11 @@
{{ component }} {{ component }}
{% else %} {% else %}
<a <a
href="/?path={{ path[..i + 1].join("/") }}" {% let encoded = path[..i + 1].join("/")|urlencode %}
hx-replace-url="/?path={{ path[..i + 1].join("/") }}" href="/?path={{ encoded }}"
hx-replace-url="/?path={{ encoded }}"
hx-get="/browser" hx-get="/browser"
hx-vals='{"path": "{{ path[..i + 1].join("/") }}"}' hx-vals='{"path": "{{ encoded }}"}'
hx-target=".browser" hx-target=".browser"
>{{ component }}</a> >{{ component }}</a>
{% endif %} {% endif %}
@ -49,20 +50,20 @@
{% when mpd::Entry::Directory with { name, path } %} {% when mpd::Entry::Directory with { name, path } %}
<li <li
hx-get="/browser" hx-get="/browser"
hx-vals='{"path": "{{ path }}"}' hx-vals='{"path": "{{ path|urlencode }}"}'
hx-replace-url="/?path={{ path }}" hx-replace-url="/?path={{ path|urlencode }}"
hx-target=".browser" hx-target=".browser"
role="link" role="link"
> >
<span class="material-symbols-outlined" title="Directory">folder</span> <span class="material-symbols-outlined" title="Directory">folder</span>
<div class="song__name"> <div class="song__name">
<a href="/?path={{ path }}" hx-get="/browser" hx-sync="closest li:abort"> <a href="/?path={{ path|urlencode }}" hx-get="/browser" hx-sync="closest li:abort">
{{ name }} {{ name }}
</a> </a>
</div> </div>
</li> </li>
{% when mpd::Entry::Playlist with { name, path } %} {% when mpd::Entry::Playlist with { name, path } %}
<li hx-post="/queue?path={{ path }}" hx-swap="none" role="button" > <li hx-post="/queue?path={{ path|urlencode }}" hx-swap="none" role="button" >
<span class="material-symbols-outlined" title="Playlist">playlist_play</span> <span class="material-symbols-outlined" title="Playlist">playlist_play</span>
<div class="song"> <div class="song">
<div class="song__name">{{ name }}</div> <div class="song__name">{{ name }}</div>

View file

@ -5,9 +5,9 @@
<div class="current"> <div class="current">
{% if let Some(song) = song %} {% if let Some(song) = song %}
<div class="albumart"> <div class="albumart">
<a href="/art?path={{ song.file }}" target="_blank"> <a href="/art?path={{ song.file|urlencode }}" target="_blank">
<img <img
src="/art?path={{ song.file }}" src="/art?path={{ song.file|urlencode }}"
onerror="this.style.opacity = 0" onerror="this.style.opacity = 0"
alt="Album art" alt="Album art"
title="Album art" title="Album art"

View file

@ -14,7 +14,7 @@
<li {% if item.playing %}class="playing"{% endif %}> <li {% if item.playing %}class="playing"{% endif %}>
<div class="albumart"> <div class="albumart">
<img <img
src="/art?path={{ item.file }}" src="/art?path={{ item.file|urlencode }}"
onerror="this.style.opacity = 0" onerror="this.style.opacity = 0"
alt="Album art" alt="Album art"
title="Album art" title="Album art"