From c9b44dea435293aed835cef202a68b3171cb6e7d Mon Sep 17 00:00:00 2001 From: Josh Patra Date: Sat, 7 Feb 2026 00:32:22 -0500 Subject: [PATCH] Fix delete endpoint to work with kept folder and clean up empty directories - Changed delete endpoint from Library:DownloadPath to /app/kept - Now properly deletes empty Album and Artist folders after file deletion - Added debug logging for deletion operations - Structure: Artist/Album/Track.flac --- allstarr/Controllers/AdminController.cs | 29 +++++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/allstarr/Controllers/AdminController.cs b/allstarr/Controllers/AdminController.cs index 0085e8f..e8c3a4b 100644 --- a/allstarr/Controllers/AdminController.cs +++ b/allstarr/Controllers/AdminController.cs @@ -3402,7 +3402,7 @@ public class LinkPlaylistRequest /// /// DELETE /api/admin/downloads - /// Deletes a specific downloaded file + /// Deletes a specific kept file and cleans up empty folders /// [HttpDelete("downloads")] public IActionResult DeleteDownload([FromQuery] string path) @@ -3414,47 +3414,52 @@ public class LinkPlaylistRequest return BadRequest(new { error = "Path is required" }); } - var downloadPath = _configuration["Library:DownloadPath"] ?? "./downloads"; - var fullPath = Path.Combine(downloadPath, path); + var keptPath = "/app/kept"; + var fullPath = Path.Combine(keptPath, path); - // Security: Ensure the path is within the download directory + _logger.LogInformation("🗑️ Delete request for: {Path}", fullPath); + + // Security: Ensure the path is within the kept directory var normalizedFullPath = Path.GetFullPath(fullPath); - var normalizedDownloadPath = Path.GetFullPath(downloadPath); + var normalizedKeptPath = Path.GetFullPath(keptPath); - if (!normalizedFullPath.StartsWith(normalizedDownloadPath)) + if (!normalizedFullPath.StartsWith(normalizedKeptPath)) { + _logger.LogWarning("🗑️ Invalid path (outside kept folder): {Path}", normalizedFullPath); return BadRequest(new { error = "Invalid path" }); } if (!System.IO.File.Exists(fullPath)) { + _logger.LogWarning("🗑️ File not found: {Path}", fullPath); return NotFound(new { error = "File not found" }); } System.IO.File.Delete(fullPath); - _logger.LogInformation("Deleted download: {Path}", path); + _logger.LogInformation("🗑️ Deleted file: {Path}", fullPath); - // Clean up empty directories + // Clean up empty directories (Album folder, then Artist folder if empty) var directory = Path.GetDirectoryName(fullPath); - while (directory != null && directory != downloadPath) + while (directory != null && directory != keptPath && directory.StartsWith(keptPath)) { if (Directory.Exists(directory) && !Directory.EnumerateFileSystemEntries(directory).Any()) { Directory.Delete(directory); - _logger.LogDebug("Deleted empty directory: {Dir}", directory); + _logger.LogInformation("🗑️ Deleted empty directory: {Dir}", directory); + directory = Path.GetDirectoryName(directory); } else { + _logger.LogDebug("🗑️ Directory not empty or doesn't exist, stopping cleanup: {Dir}", directory); break; } - directory = Path.GetDirectoryName(directory); } return Ok(new { success = true, message = "File deleted successfully" }); } catch (Exception ex) { - _logger.LogError(ex, "Failed to delete download: {Path}", path); + _logger.LogError(ex, "Failed to delete file: {Path}", path); return StatusCode(500, new { error = "Failed to delete file" }); } }