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") }