diff --git a/handler-index.go b/handler-index.go index aec3cd562bbb9b1305245f512f7f97b530c79416..e7405e58ee1a877c5801d9e3d31bac057c3907cf 100644 --- a/handler-index.go +++ b/handler-index.go @@ -4,14 +4,9 @@ import ( "errors" "fmt" "html/template" - "image" "log" "net/http" "strconv" - - // Imported for side effects to register format handlers - _ "image/jpeg" - _ "image/png" ) var indexTemplate = template.Must(template.ParseFS(templateFS, "templates/base.tpl", "templates/index.tpl")) @@ -86,25 +81,11 @@ func (h Handler) index(w http.ResponseWriter, r *http.Request) { } defer picFile.Close() - mime := picHdr.Header.Get("Content-Type") - switch mime { - case "image/jpeg", "image/png": - default: - httpError(w, "can't load picture", errors.New("invalid mime type: "+mime), http.StatusBadRequest) - return - } - - log.Println("picture", picHdr.Size, picHdr.Header.Get("Content-Type")) - - img, imgFmt, err := image.Decode(picFile) + err = vino.AddPicture(picFile, picHdr.Header.Get("Content-Type")) if err != nil { - httpError(w, "can't read picture file", err, http.StatusInternalServerError) + httpError(w, "can't load picture", err, http.StatusBadRequest) return } - - log.Println("got a", imgFmt, "for the picture") - - vino.Picture = img } err = vino.Store(r.Context(), h.db, Add) diff --git a/vino.go b/vino.go index 1f30ca82f2b8d4a2b355397accdca05b19a8a351..f3242e7e6ddba5e195caa2ef6346df1b9f020529 100644 --- a/vino.go +++ b/vino.go @@ -3,11 +3,17 @@ package main import ( "bytes" "context" + "errors" "fmt" "image" "image/png" + "io" "log" + // Imported for side effects to register format handlers + _ "image/jpeg" + _ "image/png" + "github.com/Masterminds/squirrel" "github.com/jmoiron/sqlx" "golang.org/x/image/draw" @@ -76,6 +82,27 @@ func LoadPictureData(ctx context.Context, db *sqlx.DB, id int) ([]byte, error) { return img, nil } +// AddPicture loads picture data (PNG or JPEG) from fh and sets v's picture to it. +// If something goes wrong during loading, or the image is neither PNG nor JPEG, an error +// is returned. If contentType is not the empty string, it is validated to be either +// image/png or image/jpeg +func (v *Vino) AddPicture(fh io.Reader, contentType string) error { + switch contentType { + case "", "image/jpeg", "image/png": + default: + return fmt.Errorf("unexpected content type for image: %q", contentType) + } + + img, _, err := image.Decode(fh) + if err != nil { + return err + } + + v.Picture = img + + return nil +} + func (v Vino) String() string { return fmt.Sprintf("{Name: %q, Rating: %d}", v.Name, v.Rating) }