172 lines
4.7 KiB
Go
172 lines
4.7 KiB
Go
package controllers
|
|
|
|
import (
|
|
"58team_blog/internal/application/commands"
|
|
"58team_blog/internal/application/errors"
|
|
"58team_blog/internal/application/services"
|
|
"58team_blog/internal/interfaces/api/mapper"
|
|
"58team_blog/internal/interfaces/api/responses"
|
|
"58team_blog/internal/utils"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type ImagesController struct {
|
|
images_path string
|
|
service *services.ImagesService
|
|
}
|
|
|
|
func CreateImagesController(images_path string, service *services.ImagesService) ImagesController {
|
|
return ImagesController{
|
|
images_path: images_path,
|
|
service: service,
|
|
}
|
|
}
|
|
|
|
// @Summary Upload new image
|
|
// @Description Upload new image and returns uploaded image json object
|
|
// @Tags images
|
|
// @Produce json
|
|
// @Param file formData file true "image file"
|
|
// @Success 200 {object} responses.ImageResponse
|
|
// @Failure 500 {object} responses.ErrorResponse
|
|
// @Router /images/ [post]
|
|
// @Security BasicAuth
|
|
func (r *ImagesController) PostImage(c *gin.Context) {
|
|
file, err := c.FormFile("file")
|
|
if err != nil {
|
|
resp := utils.HandleError(errors.NewNotFoundError("File not found"))
|
|
c.JSON(resp.ErrorCode, resp)
|
|
return
|
|
}
|
|
|
|
uploadedFile, err := file.Open()
|
|
if err != nil {
|
|
resp := utils.HandleError(errors.NewReadFileError(err.Error()))
|
|
c.JSON(resp.ErrorCode, resp)
|
|
return
|
|
}
|
|
|
|
// Read first 512 bytes for detect MIME-type
|
|
buffer := make([]byte, 512)
|
|
_, err = uploadedFile.Read(buffer)
|
|
if err != nil {
|
|
resp := utils.HandleError(errors.NewReadFileError(err.Error()))
|
|
c.JSON(resp.ErrorCode, resp)
|
|
return
|
|
}
|
|
|
|
uploadedFile.Close()
|
|
|
|
mimeType := http.DetectContentType(buffer)
|
|
|
|
if !utils.IsImageMime(mimeType) {
|
|
resp := utils.HandleError(errors.NewValidationError("Unexpected file type. Expected: jpeg, png, gif, webp, bmp."))
|
|
c.JSON(resp.ErrorCode, resp)
|
|
return
|
|
}
|
|
|
|
cmd := commands.CreateImageCommand{
|
|
Path: uuid.NewString(),
|
|
}
|
|
|
|
image, err := r.service.Create(cmd)
|
|
if err != nil {
|
|
resp := utils.HandleError(errors.NewValidationError(err.Error()))
|
|
c.JSON(resp.ErrorCode, resp)
|
|
return
|
|
}
|
|
|
|
c.SaveUploadedFile(file, r.images_path+"/"+image.Path)
|
|
|
|
resp := mapper.ResponseFromImageResult(image)
|
|
|
|
c.JSON(http.StatusOK, resp)
|
|
}
|
|
|
|
// @Summary Get an image by path
|
|
// @Description get image by path
|
|
// @Tags images
|
|
// @Param path path string true "Path to image"
|
|
// @Produce octet-stream
|
|
// @Produce json
|
|
// @Success 200 {file} blob
|
|
// @Failure 400 {object} responses.ErrorResponse
|
|
// @Failure 404 {object} responses.ErrorResponse
|
|
// @Failure 500 {object} responses.ErrorResponse
|
|
// @Router /images/{path} [get]
|
|
func (r *ImagesController) GetImage(c *gin.Context) {
|
|
filename := c.Param("path")
|
|
|
|
filePath := filepath.Join(r.images_path, filename)
|
|
|
|
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
|
log.Println(err)
|
|
resp := responses.CreateErrorResponse(http.StatusNotFound, "Image not found")
|
|
c.JSON(resp.ErrorCode, resp)
|
|
return
|
|
}
|
|
|
|
file, err := os.Open(filePath)
|
|
if err != nil {
|
|
log.Println(err)
|
|
resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Cannot load image file from server")
|
|
c.JSON(resp.ErrorCode, resp)
|
|
return
|
|
}
|
|
|
|
mimeData := make([]byte, 512)
|
|
if _, err := file.Read(mimeData); err != nil {
|
|
log.Println(err)
|
|
resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Cannot load image from server")
|
|
c.JSON(resp.ErrorCode, resp)
|
|
return
|
|
}
|
|
|
|
mimeType, err := utils.GetImageMimeType(mimeData)
|
|
if err != nil {
|
|
log.Println(err)
|
|
resp := responses.CreateErrorResponse(http.StatusInternalServerError, err.Error())
|
|
c.JSON(resp.ErrorCode, resp)
|
|
return
|
|
}
|
|
|
|
c.Header("Content-Type", mimeType)
|
|
c.File(filePath)
|
|
}
|
|
|
|
// @Summary Delete image by path
|
|
// @Description Delete image from server by given path
|
|
// @Tags images
|
|
// @Param filename path string true "Path to image"
|
|
// @Produce image/png
|
|
// @Produce image/jpeg
|
|
// @Success 200 {object} responses.GetAllImagesList
|
|
// @Failure 400 {object} responses.ErrorResponse
|
|
// @Failure 404 {object} responses.ErrorResponse
|
|
// @Failure 500 {object} responses.ErrorResponse
|
|
// @Router /images [get]
|
|
func (r *ImagesController) GetAllImage(c *gin.Context) {
|
|
panic("Not implemented")
|
|
}
|
|
|
|
// @Summary Delete image by path
|
|
// @Description Delete image from server by given path
|
|
// @Tags images
|
|
// @Param filename path string true "Path to image"
|
|
// @Produce image/png
|
|
// @Produce image/jpeg
|
|
// @Success 200
|
|
// @Failure 400 {object} responses.ErrorResponse
|
|
// @Failure 404 {object} responses.ErrorResponse
|
|
// @Failure 500 {object} responses.ErrorResponse
|
|
// @Router /images/{path} [delete]
|
|
// @Security BasicAuth
|
|
func (r *ImagesController) DeleteImage(c *gin.Context) {
|
|
panic("Not implemented")
|
|
}
|