This repository has been archived on 2023-11-13. You can view files and clone it, but cannot push or open issues or pull requests.
imagini/internal/api/media.go

99 lines
2.2 KiB
Go
Raw Permalink Normal View History

2021-02-11 20:47:42 +00:00
package api
import (
2021-02-21 17:31:03 +00:00
"bytes"
"errors"
2021-02-11 20:47:42 +00:00
"net/http"
"os"
"path"
2021-02-21 17:31:03 +00:00
"strconv"
"time"
2021-02-11 20:47:42 +00:00
"github.com/h2non/bimg"
2021-02-21 17:31:03 +00:00
log "github.com/sirupsen/logrus"
2021-02-11 20:47:42 +00:00
"reichard.io/imagini/graph/model"
)
/**
* Responsible for serving up static images / videos
**/
func (api *API) mediaHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
if path.Dir(r.URL.Path) != "/media" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
// Acquire Width & Height Parameters
2021-02-21 17:31:03 +00:00
width, _ := strconv.Atoi(r.URL.Query().Get("width"))
2021-02-11 20:47:42 +00:00
// Pull out userID
authContext := r.Context().Value("auth").(*model.AuthContext)
rawUserID, _ := (*authContext.AccessToken).Get("sub")
userID := rawUserID.(string)
// Derive Path
fileName := path.Base(r.URL.Path)
folderPath := path.Join("/" + api.Config.DataPath + "/media/" + userID)
mediaPath := path.Join(folderPath + "/" + fileName)
// Check if File Exists
_, err := os.Stat(mediaPath)
if os.IsNotExist(err) {
2021-02-21 17:31:03 +00:00
log.Warn("[media] Image does not exist on disk")
w.WriteHeader(http.StatusInternalServerError)
return
}
mediaFile, err := resizeAndConvertImageBIMG(mediaPath, width)
//mediaFile, err := resizeAndConvertImage(mediaPath, width)
2021-02-21 17:31:03 +00:00
if err != nil {
log.Warn("[media] Image conversion failed:", err)
w.WriteHeader(http.StatusInternalServerError)
2021-02-11 20:47:42 +00:00
return
}
2021-02-21 17:31:03 +00:00
// TODO: Cache mediaFile
http.ServeContent(w, r, fileName, time.Time{}, bytes.NewReader(mediaFile))
}
func resizeAndConvertImageBIMG(path string, desiredWidth int) ([]byte, error) {
buffer, err := bimg.Read(path)
2021-02-21 17:31:03 +00:00
if err != nil {
return nil, errors.New("[media] Unable to read image")
}
inputImage := bimg.NewImage(buffer)
2021-02-21 17:31:03 +00:00
// Return RAW
if inputImage.Type() == "jpeg" && desiredWidth == 0 {
return buffer, nil
2021-02-21 17:31:03 +00:00
}
imageSize, err := inputImage.Size()
options := bimg.Options{
Quality: 100,
// NoAutoRotate: true,
Background: bimg.Color{R: 255, G: 255, B: 255},
}
// Set dimensions
if desiredWidth != 0 && imageSize.Width > desiredWidth {
options.Width = desiredWidth
options.Quality = 50
2021-02-21 17:31:03 +00:00
}
// Convert to JPEG
if inputImage.Type() != "jpeg" {
options.Type = bimg.JPEG
}
// Process image
return inputImage.Process(options)
2021-02-11 20:47:42 +00:00
}