Refactor
This commit is contained in:
parent
bceaa3b6df
commit
937216bda6
|
@ -1 +1,2 @@
|
||||||
resource_manager
|
resource_manager
|
||||||
|
.idea/
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"git.bbr-dev.info/brajkovic/resource_manager/domain/resize"
|
||||||
|
"git.bbr-dev.info/brajkovic/resource_manager/domain/resource"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UploadRequest struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Properties struct {
|
||||||
|
Overwrite bool `json:"overwrite"`
|
||||||
|
MimeType string `json:"mimeType"`
|
||||||
|
} `json:"properties"`
|
||||||
|
Resize *struct {
|
||||||
|
Width int `json:"width"`
|
||||||
|
Height int `json:"height"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
} `json:"resize"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NoMethod() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{
|
||||||
|
"status": 404,
|
||||||
|
"created": time.Now(),
|
||||||
|
"message": "no handler for method '" + c.Request.Method + "'",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NoRoute() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{
|
||||||
|
"status": 404,
|
||||||
|
"created": time.Now(),
|
||||||
|
"message": "no handler for " + c.Request.Method + " '" + c.Request.URL.RequestURI() + "'",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleUpload(resourceManager resource.Manager) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
var request UploadRequest
|
||||||
|
if err := c.BindJSON(&request); err != nil {
|
||||||
|
c.AbortWithStatusJSON(400, gin.H{"error": "bad request"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
content, err := base64.StdEncoding.DecodeString(request.Content)
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithStatusJSON(400, gin.H{"error": "bad request"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if resize.IsResizable(readMimeType(request.Path, request.Properties.MimeType)) && request.Resize != nil {
|
||||||
|
content, err = resize.ResizeImage(content, resize.Resize{
|
||||||
|
Height: request.Resize.Height,
|
||||||
|
Width: request.Resize.Width,
|
||||||
|
Type: mapResizeType(request.Resize.Type),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithStatusJSON(400, gin.H{"error": "bad request"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resourceManager.Upload(resource.UploadRequest{
|
||||||
|
Buffer: bytes.NewBuffer(content),
|
||||||
|
Path: request.Path,
|
||||||
|
MimeType: request.Properties.MimeType,
|
||||||
|
Overwrite: request.Properties.Overwrite,
|
||||||
|
})
|
||||||
|
// we return this as success
|
||||||
|
c.Status(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleCopy(resourceManager resource.Manager) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
from := c.Query("from")
|
||||||
|
to := c.Query("to")
|
||||||
|
overwrite := c.Query("overwrite") == "true"
|
||||||
|
if err := resourceManager.Copy(from, to, overwrite); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
c.AbortWithStatus(500)
|
||||||
|
} else {
|
||||||
|
c.Status(201)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandlePresign(resourceManager resource.Manager) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
path := c.Query("path")
|
||||||
|
url, err := resourceManager.Presign(c, path)
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithStatus(404)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if c.Query("redirect") == "true" {
|
||||||
|
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||||
|
} else {
|
||||||
|
c.JSON(200, gin.H{"url": url})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleDownload(resourceManager resource.Manager) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
path := c.Query("path")
|
||||||
|
data, err := resourceManager.Download(c, path)
|
||||||
|
if err == nil {
|
||||||
|
c.Header("content-disposition", "inline; filename=\""+filename(path)+"\"")
|
||||||
|
c.Data(200, readMimeType(path, ""), data)
|
||||||
|
} else {
|
||||||
|
c.AbortWithStatus(http.StatusNotFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleDelete(resourceManager resource.Manager) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
path := c.Query("path")
|
||||||
|
if err := resourceManager.Delete(path); err != nil {
|
||||||
|
c.AbortWithError(400, err)
|
||||||
|
} else {
|
||||||
|
c.Status(204)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var mimeTypes = map[string]string{
|
||||||
|
"jpg": "image/jpg",
|
||||||
|
"jpeg": "image/jpeg",
|
||||||
|
"png": "image/png",
|
||||||
|
"gif": "image/gif",
|
||||||
|
"json": "application/json",
|
||||||
|
"pdf": "application/pdf",
|
||||||
|
"html": "text/html",
|
||||||
|
"xml": "application/xml",
|
||||||
|
}
|
||||||
|
|
||||||
|
func readMimeType(path string, mimeType string) string {
|
||||||
|
if mimeType != "" {
|
||||||
|
return mimeType
|
||||||
|
}
|
||||||
|
parts := strings.Split(path, ".")
|
||||||
|
fileType := strings.ToLower(parts[len(parts)-1])
|
||||||
|
if value, exists := mimeTypes[fileType]; exists {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
return "application/octet-stream"
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapResizeType(resizeType string) resize.ResizeType {
|
||||||
|
switch resizeType {
|
||||||
|
case "cover":
|
||||||
|
return resize.Cover
|
||||||
|
case "contain":
|
||||||
|
return resize.Contain
|
||||||
|
case "exact_height":
|
||||||
|
return resize.ExactHeight
|
||||||
|
case "exact_width":
|
||||||
|
return resize.ExactWidth
|
||||||
|
default:
|
||||||
|
return resize.Exact
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func filename(path string) string {
|
||||||
|
substrings := strings.Split(path, "/")
|
||||||
|
return substrings[len(substrings)-1]
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.bbr-dev.info/brajkovic/resource_manager/domain/cache"
|
||||||
|
"git.bbr-dev.info/brajkovic/resource_manager/domain/resource"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetupServer() *gin.Engine {
|
||||||
|
server := createServer()
|
||||||
|
RegisterRoutes(server)
|
||||||
|
return server
|
||||||
|
}
|
||||||
|
|
||||||
|
func createServer() *gin.Engine {
|
||||||
|
server := gin.New()
|
||||||
|
server.NoRoute(NoRoute())
|
||||||
|
server.NoMethod(NoMethod())
|
||||||
|
server.Use(gin.Recovery())
|
||||||
|
return server
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterRoutes(server *gin.Engine) {
|
||||||
|
cacheManager := cache.NewManager()
|
||||||
|
expiration := loadExpiration()
|
||||||
|
|
||||||
|
log.Println("Presign | expiration set to " + expiration.String())
|
||||||
|
|
||||||
|
resourceManager := resource.NewManager(cacheManager, expiration)
|
||||||
|
|
||||||
|
server.POST("/api/v1/upload", HandleUpload(resourceManager))
|
||||||
|
server.GET("/api/v1/download", HandleDownload(resourceManager))
|
||||||
|
server.GET("/api/v1/presign", HandlePresign(resourceManager))
|
||||||
|
server.PUT("/api/v1/copy", HandleCopy(resourceManager))
|
||||||
|
server.DELETE("/api/v1/delete", HandleDelete(resourceManager))
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadExpiration() time.Duration {
|
||||||
|
if value := os.Getenv("PRESIGN_DURATION"); value != "" {
|
||||||
|
duration, err := time.ParseDuration(value)
|
||||||
|
if err != nil {
|
||||||
|
return duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// default duration
|
||||||
|
return 1 * time.Hour
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package resize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"github.com/anthonynsimon/bild/transform"
|
||||||
|
"image"
|
||||||
|
"image/jpeg"
|
||||||
|
"image/png"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
var mimeTypes = map[string]string{
|
||||||
|
"image/jpg": "image/jpg",
|
||||||
|
"image/jpeg": "image/jpeg",
|
||||||
|
"image/png": "image/png",
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsResizable(mimeType string) bool {
|
||||||
|
_, present := mimeTypes[mimeType]
|
||||||
|
return present
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResizeType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Cover - resize preserving image aspect
|
||||||
|
// - resizes to the smallest image where both width and height are larger or equal to given size
|
||||||
|
Cover ResizeType = iota
|
||||||
|
// Contain - resize preserving image aspect
|
||||||
|
// - resizes to the largest image where both width and height are smaller or equal to given size
|
||||||
|
Contain ResizeType = iota
|
||||||
|
// ExactHeight - resize preserving image aspect
|
||||||
|
// - resizes to the image with given height
|
||||||
|
ExactHeight ResizeType = iota
|
||||||
|
// ExactWidth - resize preserving image aspect
|
||||||
|
// - resizes to the image with given width
|
||||||
|
ExactWidth ResizeType = iota
|
||||||
|
// Exact - resize without preserving image aspect
|
||||||
|
// - resizes to exact size defined in request
|
||||||
|
Exact ResizeType = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
type Resize struct {
|
||||||
|
Height int
|
||||||
|
Width int
|
||||||
|
Type ResizeType
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResizeImage(imageBytes []byte, resize Resize) ([]byte, error) {
|
||||||
|
img, format, err := image.Decode(bytes.NewReader(imageBytes))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
writer := io.Writer(&buffer)
|
||||||
|
|
||||||
|
resizeWidth, resizeHeight := calculateResizedDimensions(img.Bounds(), resize)
|
||||||
|
|
||||||
|
img = transform.Resize(img, resizeWidth, resizeHeight, transform.Gaussian)
|
||||||
|
switch format {
|
||||||
|
case "png":
|
||||||
|
err = png.Encode(writer, img)
|
||||||
|
case "jpeg":
|
||||||
|
err = jpeg.Encode(writer, img, nil)
|
||||||
|
default:
|
||||||
|
err = jpeg.Encode(writer, img, nil)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buffer.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func calculateResizedDimensions(bounds image.Rectangle, resize Resize) (width int, height int) {
|
||||||
|
width = bounds.Dx()
|
||||||
|
height = bounds.Dy()
|
||||||
|
|
||||||
|
switch resize.Type {
|
||||||
|
case Cover:
|
||||||
|
rWidth := resize.Height * width / height
|
||||||
|
if rWidth >= resize.Width {
|
||||||
|
return rWidth, resize.Height
|
||||||
|
}
|
||||||
|
rHeight := resize.Width * height / width
|
||||||
|
if rHeight >= resize.Height {
|
||||||
|
return resize.Width, rHeight
|
||||||
|
}
|
||||||
|
case Contain:
|
||||||
|
rWidth := resize.Height * width / height
|
||||||
|
if rWidth <= resize.Width {
|
||||||
|
return rWidth, resize.Height
|
||||||
|
}
|
||||||
|
rHeight := resize.Width * height / width
|
||||||
|
if rHeight <= resize.Height {
|
||||||
|
return resize.Width, rHeight
|
||||||
|
}
|
||||||
|
case ExactHeight:
|
||||||
|
rWidth := resize.Height * width / height
|
||||||
|
return rWidth, resize.Height
|
||||||
|
case ExactWidth:
|
||||||
|
rHeight := resize.Width * height / width
|
||||||
|
return resize.Width, rHeight
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"git.bbr-dev.info/brajkovic/resource_manager/cache"
|
"git.bbr-dev.info/brajkovic/resource_manager/domain/cache"
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/s3"
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
@ -39,11 +39,20 @@ type fileManager struct {
|
||||||
func (f *fileManager) Upload(request UploadRequest) {
|
func (f *fileManager) Upload(request UploadRequest) {
|
||||||
fullPath := filepath.Join(f.path, request.Path)
|
fullPath := filepath.Join(f.path, request.Path)
|
||||||
createFolder(fullPath)
|
createFolder(fullPath)
|
||||||
|
if checkFileExists(fullPath) && !request.Overwrite {
|
||||||
|
log.Println("Manager | cannot upload file as file on same path already exists")
|
||||||
|
return
|
||||||
|
}
|
||||||
log.Println("Manager | uploading to (" + request.Path + ")")
|
log.Println("Manager | uploading to (" + request.Path + ")")
|
||||||
if err := ioutil.WriteFile(fullPath, request.Buffer.Bytes(), 0o644); err != nil {
|
if err := os.WriteFile(fullPath, request.Buffer.Bytes(), 0o644); err != nil {
|
||||||
log.Println("Manager | failed uploading (" + request.Path + ") cause: " + err.Error())
|
log.Println("Manager | failed uploading (" + request.Path + ") cause: " + err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkFileExists(path string) bool {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
func (f *fileManager) Download(ctx context.Context, path string) (file []byte, err error) {
|
func (f *fileManager) Download(ctx context.Context, path string) (file []byte, err error) {
|
||||||
fullPath := filepath.Join(f.path, path)
|
fullPath := filepath.Join(f.path, path)
|
||||||
file, err = ioutil.ReadFile(fullPath)
|
file, err = ioutil.ReadFile(fullPath)
|
|
@ -3,7 +3,7 @@ package resource
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"git.bbr-dev.info/brajkovic/resource_manager/cache"
|
"git.bbr-dev.info/brajkovic/resource_manager/domain/cache"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
109
handlers.go
109
handlers.go
|
@ -1,109 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/base64"
|
|
||||||
"git.bbr-dev.info/brajkovic/resource_manager/resource"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LegacySave struct {
|
|
||||||
Content string `json:"content"`
|
|
||||||
Path string `json:"path"`
|
|
||||||
Properties struct {
|
|
||||||
Height int `json:"height"`
|
|
||||||
Overwrite bool `json:"overwrite"`
|
|
||||||
MimeType string `json:"mimeType"`
|
|
||||||
} `json:"properties"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func HandleLegacySave(resourceManager resource.Manager) gin.HandlerFunc {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
var legacySave LegacySave
|
|
||||||
if err := c.ShouldBindJSON(&legacySave); err == nil {
|
|
||||||
// removing image/(png/jpeg/...); start
|
|
||||||
if strings.HasPrefix(legacySave.Content, "data:") {
|
|
||||||
legacySave.Content = strings.Split(legacySave.Content, ";")[1]
|
|
||||||
}
|
|
||||||
if imageBytes, err := base64.StdEncoding.DecodeString(legacySave.Content); err == nil {
|
|
||||||
if legacySave.Properties.Height > 0 {
|
|
||||||
imageBytes, err = resizeImage(imageBytes, legacySave.Properties.Height)
|
|
||||||
}
|
|
||||||
mimeType := readMimeType(legacySave.Path, legacySave.Properties.MimeType)
|
|
||||||
if err == nil {
|
|
||||||
// request is sent to uplader service after which it is being uploaded
|
|
||||||
resourceManager.Upload(resource.UploadRequest{
|
|
||||||
Buffer: bytes.NewBuffer(imageBytes),
|
|
||||||
Path: legacySave.Path,
|
|
||||||
MimeType: mimeType,
|
|
||||||
})
|
|
||||||
// we return this as success
|
|
||||||
c.Status(http.StatusNoContent)
|
|
||||||
} else {
|
|
||||||
c.AbortWithStatusJSON(400, gin.H{"error": "bad request"})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
c.AbortWithStatusJSON(400, gin.H{"error": "bad request"})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
c.AbortWithStatusJSON(400, gin.H{"error": "bad request"})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func HandleCopy(resourceManager resource.Manager) gin.HandlerFunc {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
from := c.Query("from")
|
|
||||||
to := c.Query("to")
|
|
||||||
overwrite := c.Query("overwrite") == "true"
|
|
||||||
if err := resourceManager.Copy(from, to, overwrite); err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
c.AbortWithStatus(500)
|
|
||||||
} else {
|
|
||||||
c.Status(201)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func HandlePresign(resourceManager resource.Manager) gin.HandlerFunc {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
path := c.Query("path")
|
|
||||||
url, err := resourceManager.Presign(c, path)
|
|
||||||
if err != nil {
|
|
||||||
c.AbortWithStatus(404)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if c.Query("redirect") == "true" {
|
|
||||||
c.Redirect(http.StatusTemporaryRedirect, url)
|
|
||||||
} else {
|
|
||||||
c.JSON(200, url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func HandleGet(resourceManager resource.Manager) gin.HandlerFunc {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
path := c.Query("path")
|
|
||||||
data, err := resourceManager.Download(c, path)
|
|
||||||
if err == nil {
|
|
||||||
c.Data(200, readMimeType(path, ""), data)
|
|
||||||
} else {
|
|
||||||
c.AbortWithStatus(http.StatusNotFound)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func HandleDelete(resourceManager resource.Manager) gin.HandlerFunc {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
path := c.Query("path")
|
|
||||||
if err := resourceManager.Delete(path); err != nil {
|
|
||||||
c.AbortWithError(400, err)
|
|
||||||
} else {
|
|
||||||
c.Status(204)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
57
image.go
57
image.go
|
@ -1,57 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"github.com/anthonynsimon/bild/transform"
|
|
||||||
"image"
|
|
||||||
"image/jpeg"
|
|
||||||
"image/png"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var mimeTypes = map[string]string{
|
|
||||||
"jpg": "image/jpg",
|
|
||||||
"jpeg": "image/jpeg",
|
|
||||||
"png": "image/png",
|
|
||||||
"json": "application/json",
|
|
||||||
"html": "text/html",
|
|
||||||
"xml": "application/xml",
|
|
||||||
}
|
|
||||||
|
|
||||||
func readMimeType(path string, mimeType string) string {
|
|
||||||
if mimeType != "" {
|
|
||||||
return mimeType
|
|
||||||
}
|
|
||||||
parts := strings.Split(path, ".")
|
|
||||||
fileType := parts[len(parts)-1]
|
|
||||||
if value, exists := mimeTypes[fileType]; exists {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
return "application/octet-stream"
|
|
||||||
}
|
|
||||||
|
|
||||||
func resizeImage(imageBytes []byte, resizeHeight int) ([]byte, error) {
|
|
||||||
img, format, err := image.Decode(bytes.NewReader(imageBytes))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
writer := io.Writer(&buffer)
|
|
||||||
resizeWidth := img.Bounds().Dx() * resizeHeight / img.Bounds().Dy()
|
|
||||||
img = transform.Resize(img, resizeWidth, resizeHeight, transform.Gaussian)
|
|
||||||
switch format {
|
|
||||||
case "png":
|
|
||||||
err = png.Encode(writer, img)
|
|
||||||
break
|
|
||||||
case "jpeg":
|
|
||||||
err = jpeg.Encode(writer, img, nil)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
err = jpeg.Encode(writer, img, nil)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return buffer.Bytes(), nil
|
|
||||||
}
|
|
45
main.go
45
main.go
|
@ -1,15 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.bbr-dev.info/brajkovic/resource_manager/cache"
|
"git.bbr-dev.info/brajkovic/resource_manager/api"
|
||||||
"git.bbr-dev.info/brajkovic/resource_manager/resource"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -18,42 +13,6 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cacheManager := cache.NewManager()
|
server := api.SetupServer()
|
||||||
expiration := loadExpiration()
|
|
||||||
log.Println("Presign | expiration set to " + expiration.String())
|
|
||||||
|
|
||||||
resourceManager := resource.NewManager(cacheManager, expiration)
|
|
||||||
|
|
||||||
server := gin.Default()
|
|
||||||
if strings.Contains(os.Getenv("PROFILE"), "legacy") {
|
|
||||||
setupLegacyEndpoints(server, resourceManager)
|
|
||||||
}
|
|
||||||
setupV1Endpoints(server, resourceManager)
|
|
||||||
log.Fatalln(http.ListenAndServe(":5201", server))
|
log.Fatalln(http.ListenAndServe(":5201", server))
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadExpiration() time.Duration {
|
|
||||||
if value := os.Getenv("PRESIGN_DURATION"); value != "" {
|
|
||||||
duration, err := time.ParseDuration(value)
|
|
||||||
if err != nil {
|
|
||||||
return duration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// default duration
|
|
||||||
return 1 * time.Hour
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupLegacyEndpoints(server *gin.Engine, resourceManager resource.Manager) {
|
|
||||||
server.POST("/save", HandleLegacySave(resourceManager))
|
|
||||||
server.GET("/get", HandleGet(resourceManager))
|
|
||||||
server.GET("/presign", HandlePresign(resourceManager))
|
|
||||||
server.PUT("/copy", HandleCopy(resourceManager))
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupV1Endpoints(server *gin.Engine, resourceManager resource.Manager) {
|
|
||||||
server.POST("/api/v1/save", HandleLegacySave(resourceManager))
|
|
||||||
server.GET("/api/v1/get", HandleGet(resourceManager))
|
|
||||||
server.GET("/api/v1/presign", HandlePresign(resourceManager))
|
|
||||||
server.PUT("/api/v1/copy", HandleCopy(resourceManager))
|
|
||||||
server.DELETE("/api/v1/delete", HandleDelete(resourceManager))
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue