Skip to content
Snippets Groups Projects
handler-index.go 2.17 KiB
package main

import (
	"errors"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"strconv"
)

var indexTemplate = template.Must(template.ParseFS(templateFS, "templates/base.tpl", "templates/index.tpl"))

func (h Handler) index(w http.ResponseWriter, r *http.Request) {
	log.Println("handling", r.Method, r.URL, "from", r.RemoteAddr)

	if r.Method == "GET" {
		wines, err := ListWines(r.Context(), h.db)
		if err != nil {
			httpError(w, "can't list wines", err, http.StatusInternalServerError)
			return
		}

		w.Header().Add("content-type", "text/html")

		data := struct {
			Wines []Vino
		}{wines}

		err = indexTemplate.ExecuteTemplate(w, "index.tpl", data)
		if err != nil {
			log.Println("can't execute index template:", err)
		}

		return
	}

	if r.Method != "POST" {
		httpError(w, "invalid method", errors.New(r.Method), http.StatusMethodNotAllowed)
		return
	}

	name := r.FormValue("name")
	if len(name) > 80 {
		httpError(w, "bad name", errors.New("name too long, max length is 80"), http.StatusBadRequest)
		return
	}

	ratingVal := r.FormValue("rating")

	var (
		rating int
		err    error
	)

	if ratingVal != "" {
		rating, err = strconv.Atoi(ratingVal)
		if err != nil {
			httpError(w, "can't convert rating", err, http.StatusBadRequest)
			return
		}
	}

	err = r.ParseMultipartForm(16 * 1024 * 1024)
	if err != nil {
		httpError(w, "can't parse multipart form data", err, http.StatusInternalServerError)
		return
	}

	vino := Vino{
		Name:   name,
		Rating: rating,
	}

	// See if there's an image file uploaded
	if len(r.MultipartForm.File["picture"]) != 0 {
		picFile, picHdr, err := r.FormFile("picture")
		if err != nil {
			httpError(w, "can't open picture file", err, http.StatusInternalServerError)
			return
		}
		defer picFile.Close()

		err = vino.AddPicture(picFile, picHdr.Header.Get("Content-Type"))
		if err != nil {
			httpError(w, "can't load picture", err, http.StatusBadRequest)
			return
		}
	}

	err = vino.Store(r.Context(), h.db, Add)
	if err != nil {
		httpError(w, fmt.Sprintf("can't store wine %q", vino), err, http.StatusInternalServerError)
		return
	}

	http.Redirect(w, r, "/details?id="+strconv.Itoa(vino.ID), http.StatusSeeOther) // TODO: Is this the correct status?
}