{ post.Body }
-diff --git a/.gitignore b/.gitignore index 83a6adb..db7cd78 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ internal/database/comfychan.db **/*_templ.go tmp +web/static/img/posts diff --git a/internal/database/handlers.go b/internal/database/handlers.go index 662e078..82b97eb 100644 --- a/internal/database/handlers.go +++ b/internal/database/handlers.go @@ -118,8 +118,8 @@ func PutThread(db *sql.DB, boardSlug string, subject string, body string, mediaP return nil } -func PutPost(db *sql.DB, threadId int, body string) error { - _, err := db.Exec(`INSERT INTO posts (thread_id, body) VALUES (?, ?)`, threadId, body) +func PutPost(db *sql.DB, threadId int, body string, mediaPath string) error { + _, err := db.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 73e4978..a378dcf 100644 --- a/web/main.go +++ b/web/main.go @@ -2,9 +2,11 @@ package main import ( "database/sql" + "errors" "fmt" "io" "log" + "mime/multipart" "net/http" "os" "path/filepath" @@ -17,6 +19,8 @@ import ( _ "github.com/mattn/go-sqlite3" ) +const FILE_MEM_LIMIT int64 = 10 << 20 + var dev = true func disableCacheInDevMode(next http.Handler) http.Handler { @@ -29,6 +33,24 @@ func disableCacheInDevMode(next http.Handler) http.Handler { }) } +func savePostFile(file *multipart.File, header *multipart.FileHeader) error { + dstPath := filepath.Join("web/static/img/posts", header.Filename) + + dst, err := os.Create(dstPath) + if err != nil { + log.Printf("os.Create: %v", err) + return err + } + defer dst.Close() + + if _, err := io.Copy(dst, *file); err != nil { + log.Printf("io.Copy: %v", err) + return err + } + + return nil +} + func main() { // ----------------- // SETUP @@ -119,37 +141,27 @@ func main() { r.Post("/{slug}/threads", func(w http.ResponseWriter, r *http.Request) { slug := chi.URLParam(r, "slug") + subject := r.FormValue("subject") + body := r.FormValue("body") + // 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) + if err := r.ParseMultipartForm(FILE_MEM_LIMIT); err != nil { + http.Error(w, "Failed to parse form", http.StatusBadRequest) + log.Printf("ParseMultipartForm: %v", err) return } file, header, err := r.FormFile("file") if err != nil { - http.Error(w, "Failed to retrieve file from form", http.StatusBadRequest) + http.Error(w, "Failed to retrive file from form", http.StatusBadRequest) log.Printf("FormFile: %v", err) return } defer file.Close() - subject := r.FormValue("subject") - body := r.FormValue("body") - - 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 { + if err := savePostFile(&file, header); err != nil { http.Error(w, "Failed to save file", http.StatusInternalServerError) - log.Printf("io.Copy: %v", err) + log.Printf("savePostFile: %v", err) return } @@ -172,8 +184,33 @@ func main() { } body := r.FormValue("body") + mediaPath := "" - if err := database.PutPost(db, threadId, body); err != nil { + // 10 MB memory limit + if err := r.ParseMultipartForm(FILE_MEM_LIMIT); err != nil { + http.Error(w, "Failed to parse form", http.StatusBadRequest) + log.Printf("ParseMultipartForm: %v", err) + return + } + + file, header, err := r.FormFile("file") + if err != nil { + if !errors.Is(err, http.ErrMissingFile) { + http.Error(w, "Failed to retrive file from form", http.StatusBadRequest) + log.Printf("FormFile: %v", err) + return + } + } else { + defer file.Close() + if err := savePostFile(&file, header); err != nil { + http.Error(w, "Failed to save file", http.StatusInternalServerError) + log.Printf("savePostFile: %v", err) + return + } + mediaPath = header.Filename + } + + if err := database.PutPost(db, threadId, body, mediaPath); err != nil { http.Error(w, "Failed to create post", http.StatusInternalServerError) log.Printf("PutPost: %v", err) return diff --git a/web/views/board.templ b/web/views/board.templ index eb41154..d2dcf23 100644 --- a/web/views/board.templ +++ b/web/views/board.templ @@ -1,56 +1,60 @@ package views import ( -"fmt" -database "github.com/dominicf2001/comfychan/internal/database" -"github.com/dominicf2001/comfychan/web/views/shared" + "fmt" + "github.com/dominicf2001/comfychan/internal/database" + "github.com/dominicf2001/comfychan/web/views/shared" ) templ NewThreadForm(board database.Board) { -
+ then trigger refreshThreads on body" + > +| Subject | ++ |
|---|---|
| Comment | ++ |
| File | ++ |
{ board.Tag }
-{ board.Tag }
+{ post.Body }
-{ post.Body }
+| comment | ++ |
|---|---|
| File | ++ |
{ posts[0].Body }
-{ posts[0].Body }
+