6 Commits

Author SHA1 Message Date
1a9ef41962 Merge pull request 'feat/filesystem_viewer' (#70) from feat/filesystem_viewer into main
All checks were successful
Build RPi Pico firmware image / Build-Firmware (push) Successful in 4m51s
Check code formatting / Check-C-Format (push) Successful in 7s
Check code formatting / Check-Python-Flake8 (push) Successful in 10s
Check code formatting / Check-Bash-Shellcheck (push) Successful in 5s
Run unit tests on host / Run-Unit-Tests (push) Successful in 8s
Run pytests / Check-Pytest (push) Successful in 11s
Reviewed-on: #70
Reviewed-by: Matthias Blankertz <matthias@blankertz.org>
2026-01-27 19:26:59 +00:00
69fbb15bca feat: unify bottom margin between scroll container and buttons
All checks were successful
Build RPi Pico firmware image / Build-Firmware (push) Successful in 4m56s
Check code formatting / Check-C-Format (push) Successful in 8s
Check code formatting / Check-Python-Flake8 (push) Successful in 10s
Check code formatting / Check-Bash-Shellcheck (push) Successful in 5s
Run unit tests on host / Run-Unit-Tests (push) Successful in 8s
Run pytests / Check-Pytest (push) Successful in 10s
2026-01-27 20:20:22 +01:00
f9a82c121e feat: make intents explicit and rename screen accordingly 2026-01-27 20:19:07 +01:00
245b76e04e Merge pull request 'fix: frontend: Correctly escape filenames in URL parameters' (#69) from fix-url-filenames into main
All checks were successful
Build RPi Pico firmware image / Build-Firmware (push) Successful in 4m51s
Check code formatting / Check-C-Format (push) Successful in 7s
Check code formatting / Check-Python-Flake8 (push) Successful in 10s
Check code formatting / Check-Bash-Shellcheck (push) Successful in 5s
Run unit tests on host / Run-Unit-Tests (push) Successful in 8s
Run pytests / Check-Pytest (push) Successful in 10s
Reviewed-on: #69
2026-01-27 18:39:32 +00:00
fa4d8debd0 fix: webserver: catch and report exceptions from open and mkdir, too
All checks were successful
Build RPi Pico firmware image / Build-Firmware (push) Successful in 4m49s
Check code formatting / Check-C-Format (push) Successful in 8s
Check code formatting / Check-Python-Flake8 (push) Successful in 9s
Check code formatting / Check-Bash-Shellcheck (push) Successful in 4s
Run unit tests on host / Run-Unit-Tests (push) Successful in 8s
Run pytests / Check-Pytest (push) Successful in 10s
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
2026-01-27 19:11:47 +01:00
0a20b70478 fix: frontend: Correctly escape filenames in URL parameters
All checks were successful
Build RPi Pico firmware image / Build-Firmware (push) Successful in 4m56s
Check code formatting / Check-C-Format (push) Successful in 8s
Check code formatting / Check-Python-Flake8 (push) Successful in 10s
Check code formatting / Check-Bash-Shellcheck (push) Successful in 5s
Run unit tests on host / Run-Unit-Tests (push) Successful in 9s
Run pytests / Check-Pytest (push) Successful in 11s
Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
2026-01-27 18:15:15 +01:00
2 changed files with 16 additions and 13 deletions

View File

@@ -147,7 +147,7 @@
<button onclick="showScreen('menu')">🏠 Main Menu</button>
<button onclick="showScreen('config')">⚙️ Config Editor</button>
<button onclick="showScreen('playlist')">🖹 Playlist Editor</button>
<button onclick="showScreen('playlist_filebrowser', 'filesystem')">📂 Filesystem</button>
<button onclick="showScreen('filebrowser', 'filesystem')">📂 Filesystem</button>
</nav>
<!-- MAIN MENU -->
@@ -243,10 +243,10 @@
</div>
<!-- PLAYLIST EDITOR SCREEN 3: file browser -->
<div id="screen-playlist_filebrowser" class="screen">
<div id="screen-filebrowser" class="screen">
<h2 id="playlist-filebrowser-title">Playlist Editor</h2>
<div id="playlist-filebrowser-container">
<div class="scroll-container">
<div class="scroll-container" style="margin-bottom: 10px">
<div class="tree" id="playlist-filebrowser-tree">
<ul><li>Loading...</li></ul>
</div>
@@ -655,7 +655,7 @@
document.getElementById('playlist-edit-removetrack').addEventListener("click", (e) => deleteSelectedTracks());
document.getElementById('playlist-edit-back').addEventListener("click", (e) => showScreen('playlist'));
document.getElementById('playlist-edit-addtrack').addEventListener("click", (e) => {
showScreen("playlist_filebrowser");
showScreen("filebrowser", "playlist");
});
document.getElementById('playlist-edit-save').addEventListener("click", (e) => save());
}
@@ -787,7 +787,7 @@
/* ----------------------------------------
PLAYLIST EDITOR LOGIC - ADD FILES SCREEN
------------------------------------------- */
Screens.playlist_filebrowser = (() => {
Screens.filebrowser = (() => {
let isFilesystemMode = false;
function init() {
@@ -960,7 +960,7 @@
}
}
};
xhr.open("POST", `/api/v1/audiofiles?type=file&location=${location}`);
xhr.open("POST", `/api/v1/audiofiles?type=file&location=${encodeURIComponent(location)}`);
xhr.overrideMimeType("audio/mpeg");
xhr.send(files[0]);
}
@@ -978,7 +978,7 @@
const location = selectedNodes.length === 1
? selectedNodes[0].getAttribute('data-path') + '/' + name.value
: '/' + name.value;
const saveRes = await fetch(`/api/v1/audiofiles?type=directory&location=${location}`,
const saveRes = await fetch(`/api/v1/audiofiles?type=directory&location=${encodeURIComponent(location)}`,
{method: 'POST'});
// Reload file list from device
onShow('refresh');
@@ -995,7 +995,7 @@
items.sort();
items.reverse();
for (const item of items) {
const saveRes = await fetch(`/api/v1/audiofiles?location=${item}`,
const saveRes = await fetch(`/api/v1/audiofiles?location=${encodeURIComponent(item)}`,
{method: 'DELETE'});
if (!saveRes.ok) {
alert(`Failed to delete item ${item}: ${await saveRes.text()}`);

View File

@@ -235,16 +235,19 @@ async def audiofile_upload(request):
if type_ == 'directory':
if length != 0:
return 'directory request may not have content', 400
os.mkdir(path)
return '', 204
with open(path, 'wb') as newfile:
try:
os.mkdir(path)
except OSError as ex:
return f'error creating directory: {ex}', 500
return '', 204
try:
with open(path, 'wb') as newfile:
if length > Request.max_body_length:
bytes_copied = await stream_to_file(request.stream, newfile, length)
else:
bytes_copied = newfile.write(request.body)
except OSError as ex:
return f'error writing data to file: {ex}', 500
except OSError as ex:
return f'error writing data to file: {ex}', 500
if bytes_copied == length:
return '', 204
else: