From 00c8057b5b212d49b2be73d631ee6cc9039a8f53 Mon Sep 17 00:00:00 2001 From: Dominic Ferrando Date: Fri, 18 Apr 2025 15:03:54 -0400 Subject: [PATCH] Basic file upload for thread creation --- internal/database/handlers.go | 4 ++-- web/main.go | 45 ++++++++++++++++++++++++++--------- web/views/board.templ | 7 +++++- web/views/threads.templ | 4 +++- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/internal/database/handlers.go b/internal/database/handlers.go index 3b4befc..662e078 100644 --- a/internal/database/handlers.go +++ b/internal/database/handlers.go @@ -89,7 +89,7 @@ func GetPosts(db *sql.DB, threadId int) ([]Post, error) { return result, rows.Err() } -func PutThread(db *sql.DB, boardSlug string, subject string, body string) error { +func PutThread(db *sql.DB, boardSlug string, subject string, body string, mediaPath string) error { tx, err := db.Begin() if err != nil { return err @@ -106,7 +106,7 @@ func PutThread(db *sql.DB, boardSlug string, subject string, body string) error return err } - _, err = tx.Exec(`INSERT INTO posts (thread_id, body, media_path) VALUES (?, ?, ?)`, threadId, body, "default.png") + _, err = tx.Exec(`INSERT INTO posts (thread_id, body, media_path) VALUES (?, ?, ?)`, threadId, body, mediaPath) if err != nil { return err } diff --git a/web/main.go b/web/main.go index 903c890..73e4978 100644 --- a/web/main.go +++ b/web/main.go @@ -3,14 +3,18 @@ package main import ( "database/sql" "fmt" + "io" + "log" + "net/http" + "os" + "path/filepath" + "strconv" + "github.com/dominicf2001/comfychan/internal/database" "github.com/dominicf2001/comfychan/web/views" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" _ "github.com/mattn/go-sqlite3" - "log" - "net/http" - "strconv" ) var dev = true @@ -115,16 +119,41 @@ func main() { r.Post("/{slug}/threads", func(w http.ResponseWriter, r *http.Request) { slug := chi.URLParam(r, "slug") - if err := r.ParseForm(); err != nil { + // 10 MB memory limit + if err := r.ParseMultipartForm(10 << 20); err != nil { http.Error(w, "Bad form data", http.StatusBadRequest) log.Printf("ParseForm: %v", err) return } + file, header, err := r.FormFile("file") + if err != nil { + http.Error(w, "Failed to retrieve file from form", http.StatusBadRequest) + log.Printf("FormFile: %v", err) + return + } + defer file.Close() + subject := r.FormValue("subject") body := r.FormValue("body") - if err := database.PutThread(db, slug, subject, body); err != nil { + dstPath := filepath.Join("web/static/img/posts", header.Filename) + + dst, err := os.Create(dstPath) + if err != nil { + http.Error(w, "Failed to create file", http.StatusInternalServerError) + log.Printf("os.Create: %v", err) + return + } + defer dst.Close() + + if _, err := io.Copy(dst, file); err != nil { + http.Error(w, "Failed to save file", http.StatusInternalServerError) + log.Printf("io.Copy: %v", err) + return + } + + if err := database.PutThread(db, slug, subject, body, header.Filename); err != nil { http.Error(w, "Failed to create thread", http.StatusInternalServerError) log.Printf("PutThread: %v", err) return @@ -142,12 +171,6 @@ func main() { return } - if err := r.ParseForm(); err != nil { - http.Error(w, "Bad form data", http.StatusBadRequest) - log.Printf("ParseForm: %v", err) - return - } - body := r.FormValue("body") if err := database.PutPost(db, threadId, body); err != nil { diff --git a/web/views/board.templ b/web/views/board.templ index 0e22eb4..eb41154 100644 --- a/web/views/board.templ +++ b/web/views/board.templ @@ -7,7 +7,8 @@ database "github.com/dominicf2001/comfychan/internal/database" ) templ NewThreadForm(board database.Board) { -