mirror of https://gitlab.com/ngerakines/tavern.git
141 lines
3.5 KiB
Go
141 lines
3.5 KiB
Go
package web
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"fmt"
|
|
"image"
|
|
"image/jpeg"
|
|
"image/png"
|
|
"net/http"
|
|
|
|
"github.com/buckket/go-blurhash"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/nfnt/resize"
|
|
|
|
"github.com/ngerakines/tavern/errors"
|
|
"github.com/ngerakines/tavern/storage"
|
|
)
|
|
|
|
func (h handler) viewAsset(c *gin.Context) {
|
|
checksum := c.Param("checksum")
|
|
img, err := h.storage.GetImageByChecksum(c.Request.Context(), checksum)
|
|
if err != nil {
|
|
if errors.Is(err, errors.NewNotFoundError(nil)) {
|
|
h.notFoundJSON(c, nil)
|
|
return
|
|
}
|
|
h.internalServerErrorJSON(c, err)
|
|
return
|
|
}
|
|
|
|
readerCloser, err := h.assetStorage.Read(c.Request.Context(), img.Location)
|
|
if err != nil {
|
|
h.internalServerErrorJSON(c, err)
|
|
return
|
|
}
|
|
|
|
var contentType = "application/octet-stream"
|
|
// TODO: Handle other content types.
|
|
switch img.ContentType {
|
|
case storage.ContentTypeJPG:
|
|
contentType = "image/jpeg"
|
|
case storage.ContentTypePNG:
|
|
contentType = "image/png"
|
|
}
|
|
|
|
extraHeaders := map[string]string{
|
|
"Cache-Control": "max-age=7200",
|
|
}
|
|
c.DataFromReader(http.StatusOK, int64(img.Size), contentType, readerCloser, extraHeaders)
|
|
}
|
|
|
|
func (h handler) viewThumbnail(c *gin.Context) {
|
|
checksum := c.Param("checksum")
|
|
img, err := h.storage.GetImageByChecksum(c.Request.Context(), checksum)
|
|
if err != nil {
|
|
if errors.Is(err, errors.NewNotFoundError(nil)) {
|
|
h.notFoundJSON(c, nil)
|
|
return
|
|
}
|
|
h.internalServerErrorJSON(c, err)
|
|
return
|
|
}
|
|
|
|
readerCloser, err := h.assetStorage.Read(c.Request.Context(), img.Location)
|
|
if err != nil {
|
|
h.internalServerErrorJSON(c, err)
|
|
return
|
|
}
|
|
|
|
// TODO: Log this error
|
|
defer readerCloser.Close()
|
|
|
|
readImage, _, err := image.Decode(readerCloser)
|
|
if err != nil {
|
|
h.internalServerErrorJSON(c, err)
|
|
return
|
|
}
|
|
m := resize.Thumbnail(40, 40, readImage, resize.NearestNeighbor)
|
|
|
|
// TODO: Handle other content types.
|
|
switch img.ContentType {
|
|
case storage.ContentTypeJPG:
|
|
c.Writer.Header().Add("Cache-Control", "max-age=7200")
|
|
c.Writer.Header().Add("Content-Type", "image/jpeg")
|
|
// TODO: handle this error.
|
|
jpeg.Encode(c.Writer, m, nil)
|
|
case storage.ContentTypePNG:
|
|
c.Writer.Header().Add("Cache-Control", "max-age=7200")
|
|
c.Writer.Header().Add("Content-Type", "image/png")
|
|
// TODO: handle this error.
|
|
png.Encode(c.Writer, m)
|
|
default:
|
|
h.internalServerErrorJSON(c, fmt.Errorf("unable to process image thumbnail"))
|
|
}
|
|
}
|
|
|
|
func (h handler) viewBlur(c *gin.Context) {
|
|
encBlurHash := c.Param("blurHash")
|
|
blurHash, err := hex.DecodeString(encBlurHash)
|
|
if err != nil {
|
|
h.badRequestJSON(c, err)
|
|
return
|
|
}
|
|
|
|
height := intParam(c, "height", 60)
|
|
width := intParam(c, "width", 60)
|
|
|
|
blurImg, err := blurhash.Decode(string(blurHash), width, height, 1)
|
|
if err != nil {
|
|
h.internalServerErrorJSON(c, err)
|
|
return
|
|
}
|
|
c.Writer.Header().Add("Cache-Control", "max-age=7200")
|
|
c.Writer.Header().Add("Content-Type", "image/png")
|
|
// Todo: handle this error
|
|
png.Encode(c.Writer, blurImg)
|
|
}
|
|
|
|
func (h handler) viewThumbnailBlur(c *gin.Context) {
|
|
checksum := c.Param("checksum")
|
|
img, err := h.storage.GetImageByChecksum(c.Request.Context(), checksum)
|
|
if err != nil {
|
|
if errors.Is(err, errors.NewNotFoundError(nil)) {
|
|
h.notFoundJSON(c, err)
|
|
return
|
|
}
|
|
h.internalServerErrorJSON(c, err)
|
|
return
|
|
}
|
|
|
|
blurImg, err := blurhash.Decode(img.Blur, 40, 40, 1)
|
|
if err != nil {
|
|
h.internalServerErrorJSON(c, err)
|
|
return
|
|
}
|
|
c.Writer.Header().Add("Cache-Control", "max-age=7200")
|
|
c.Writer.Header().Add("Content-Type", "image/png")
|
|
// Todo: handle this error
|
|
png.Encode(c.Writer, blurImg)
|
|
}
|