73 lines
2.2 KiB
Go
73 lines
2.2 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"gardomatic.kleiax.de/internal/storage"
|
|
)
|
|
|
|
func (app *application) resolveImage(gardenID int, data string, selectedID *int, userID int, source string) (*int, error) {
|
|
if strings.TrimSpace(data) == "" {
|
|
if selectedID == nil {
|
|
return nil, nil
|
|
}
|
|
if _, err := app.models.Images.Get(gardenID, *selectedID); err != nil {
|
|
return nil, err
|
|
}
|
|
return selectedID, nil
|
|
}
|
|
comma := strings.IndexByte(data, ',')
|
|
if comma < 1 || !strings.HasPrefix(data, "data:image/") || !strings.HasSuffix(data[:comma], ";base64") {
|
|
return nil, errors.New("invalid image data")
|
|
}
|
|
mediaType := strings.TrimSuffix(strings.TrimPrefix(data[:comma], "data:"), ";base64")
|
|
decoded, err := base64.StdEncoding.DecodeString(data[comma+1:])
|
|
if err != nil || len(decoded) == 0 || len(decoded) > storage.MaxImageSize {
|
|
return nil, errors.New("invalid image data")
|
|
}
|
|
image, err := app.models.Images.Insert(storage.Image{GardenID: gardenID, MediaType: mediaType, Data: decoded, Source: source, CreatedBy: userID})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &image.ID, nil
|
|
}
|
|
|
|
func (app *application) recordImageAssignment(change storage.ImageAssignment) error {
|
|
if app.models.Images == nil {
|
|
return nil
|
|
}
|
|
return app.models.Images.RecordAssignment(change)
|
|
}
|
|
|
|
func (app *application) listImagesHandler(w http.ResponseWriter, r *http.Request) {
|
|
gardenID, _ := app.readGardenIDParam(r)
|
|
images, err := app.models.Images.GetAllForGarden(gardenID, storage.ImageFilter{Source: r.URL.Query().Get("source"), Query: r.URL.Query().Get("q")})
|
|
if err != nil {
|
|
app.serverErrorResponse(w, r, err)
|
|
return
|
|
}
|
|
if err = app.writeJSON(w, http.StatusOK, envelope{"images": images}, nil); err != nil {
|
|
app.serverErrorResponse(w, r, err)
|
|
}
|
|
}
|
|
|
|
func (app *application) showImageHandler(w http.ResponseWriter, r *http.Request) {
|
|
gardenID, _ := app.readGardenIDParam(r)
|
|
id, err := app.readNamedIDParam(r, "imageID")
|
|
if err != nil {
|
|
app.notFoundResponse(w, r)
|
|
return
|
|
}
|
|
image, err := app.models.Images.Get(gardenID, id)
|
|
if err != nil {
|
|
app.respondToEntityModelError(w, r, err)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", image.MediaType)
|
|
w.Header().Set("Cache-Control", "private, max-age=86400")
|
|
_, _ = w.Write(image.Data)
|
|
}
|