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
This commit is contained in:
2026-02-07 00:32:22 -05:00
parent 3a9d00dcdb
commit c9b44dea43

View File

@@ -3402,7 +3402,7 @@ public class LinkPlaylistRequest
/// <summary>
/// DELETE /api/admin/downloads
/// Deletes a specific downloaded file
/// Deletes a specific kept file and cleans up empty folders
/// </summary>
[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" });
}
}