commit dd3f7e7ff47fa8ad30cc19115bafc3b738d2bedf
parent 631d58af67757b000f701a2c5478d0c393f66de2
Author: breadcat <breadcat@users.noreply.github.com>
Date: Sun, 21 Sep 2025 09:40:50 +0100
With renaming, allow deletion too
Diffstat:
2 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/main.go b/main.go
@@ -287,10 +287,16 @@ func uploadHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, fmt.Sprintf("/file/%d", id), http.StatusSeeOther)
}
-// Router for file operations, tag deletion, and rename
+// Router for file operations, tag deletion, rename, and delete
func fileRouter(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.URL.Path, "/")
+ // Handle delete: /file/{id}/delete
+ if len(parts) >= 4 && parts[3] == "delete" {
+ fileDeleteHandler(w, r, parts)
+ return
+ }
+
// Handle rename: /file/{id}/rename
if len(parts) >= 4 && parts[3] == "rename" {
fileRenameHandler(w, r, parts)
@@ -307,6 +313,63 @@ func fileRouter(w http.ResponseWriter, r *http.Request) {
fileHandler(w, r)
}
+// Handle file deletion
+func fileDeleteHandler(w http.ResponseWriter, r *http.Request, parts []string) {
+ if r.Method != http.MethodPost {
+ http.Redirect(w, r, "/file/"+parts[2], http.StatusSeeOther)
+ return
+ }
+
+ fileID := parts[2]
+
+ // Get current file info
+ var currentFile File
+ err := db.QueryRow("SELECT id, filename, path FROM files WHERE id=?", fileID).Scan(¤tFile.ID, ¤tFile.Filename, ¤tFile.Path)
+ if err != nil {
+ http.Error(w, "File not found", http.StatusNotFound)
+ return
+ }
+
+ // Start a transaction to ensure data consistency
+ tx, err := db.Begin()
+ if err != nil {
+ http.Error(w, "Failed to start transaction", http.StatusInternalServerError)
+ return
+ }
+ defer tx.Rollback() // Will be ignored if tx.Commit() is called
+
+ // Delete file_tags relationships
+ _, err = tx.Exec("DELETE FROM file_tags WHERE file_id=?", fileID)
+ if err != nil {
+ http.Error(w, "Failed to delete file tags", http.StatusInternalServerError)
+ return
+ }
+
+ // Delete file record
+ _, err = tx.Exec("DELETE FROM files WHERE id=?", fileID)
+ if err != nil {
+ http.Error(w, "Failed to delete file record", http.StatusInternalServerError)
+ return
+ }
+
+ // Commit the database transaction
+ err = tx.Commit()
+ if err != nil {
+ http.Error(w, "Failed to commit transaction", http.StatusInternalServerError)
+ return
+ }
+
+ // Delete the physical file (after successful database deletion)
+ err = os.Remove(currentFile.Path)
+ if err != nil {
+ // Log the error but don't fail the request - database is already clean
+ log.Printf("Warning: Failed to delete physical file %s: %v", currentFile.Path, err)
+ }
+
+ // Redirect to home page with success
+ http.Redirect(w, r, "/?deleted="+currentFile.Filename, http.StatusSeeOther)
+}
+
// Handle file renaming
func fileRenameHandler(w http.ResponseWriter, r *http.Request, parts []string) {
if r.Method != http.MethodPost {
diff --git a/templates/file.html b/templates/file.html
@@ -12,13 +12,17 @@ File {{.Data.File.Filename}}
<a href="/uploads/{{.Data.File.Filename}}">Download file</a><br>
{{end}}
-<h3>Rename File</h3>
-<form method="post" action="/file/{{.Data.File.ID}}/rename">
+<h3>File Actions</h3>
+<form method="post" action="/file/{{.Data.File.ID}}/rename" style="display:inline-block; margin-right: 20px;">
New filename: <input type="text" name="newfilename" value="{{.Data.File.Filename}}" required style="width:300px"><br>
<small>Include file extension (e.g., "new-name.jpg")</small><br><br>
<button type="submit" onclick="return confirm('Are you sure you want to rename this file?')">Rename File</button>
</form>
+<form method="post" action="/file/{{.Data.File.ID}}/delete" style="display:inline-block;">
+ <button type="submit" onclick="return confirm('Are you sure you want to delete this file? This cannot be undone!')" style="background-color: #dc3545; color: white;">Delete File</button>
+</form>
+
<h3>Tags</h3>
<ul>
{{range $k, $v := .Data.File.Tags}}