summaryrefslogtreecommitdiffstats
path: root/api/file.go
diff options
context:
space:
mode:
Diffstat (limited to 'api/file.go')
-rw-r--r--api/file.go191
1 files changed, 2 insertions, 189 deletions
diff --git a/api/file.go b/api/file.go
index fdc9a8747..9fda76d8f 100644
--- a/api/file.go
+++ b/api/file.go
@@ -5,49 +5,20 @@ package api
import (
"bytes"
- "image"
- "image/color"
- "image/draw"
_ "image/gif"
- "image/jpeg"
"io"
"net/http"
"net/url"
- "path/filepath"
"strconv"
- "strings"
l4g "github.com/alecthomas/log4go"
- "github.com/disintegration/imaging"
"github.com/gorilla/mux"
"github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/utils"
- "github.com/rwcarlsen/goexif/exif"
_ "golang.org/x/image/bmp"
)
-const (
- /*
- EXIF Image Orientations
- 1 2 3 4 5 6 7 8
-
- 888888 888888 88 88 8888888888 88 88 8888888888
- 88 88 88 88 88 88 88 88 88 88 88 88
- 8888 8888 8888 8888 88 8888888888 8888888888 88
- 88 88 88 88
- 88 88 888888 888888
- */
- Upright = 1
- UprightMirrored = 2
- UpsideDown = 3
- UpsideDownMirrored = 4
- RotatedCWMirrored = 5
- RotatedCCW = 6
- RotatedCCWMirrored = 7
- RotatedCW = 8
-)
-
func InitFile() {
l4g.Debug(utils.T("api.file.init.debug"))
@@ -119,7 +90,7 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
io.Copy(buf, file)
data := buf.Bytes()
- info, err := doUploadFile(c.TeamId, channelId, c.Session.UserId, fileHeader.Filename, data)
+ info, err := app.DoUploadFile(c.TeamId, channelId, c.Session.UserId, fileHeader.Filename, data)
if err != nil {
c.Err = err
return
@@ -138,169 +109,11 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
- handleImages(previewPathList, thumbnailPathList, imageDataList)
+ app.HandleImages(previewPathList, thumbnailPathList, imageDataList)
w.Write([]byte(resStruct.ToJson()))
}
-func doUploadFile(teamId string, channelId string, userId string, rawFilename string, data []byte) (*model.FileInfo, *model.AppError) {
- filename := filepath.Base(rawFilename)
-
- info, err := model.GetInfoForBytes(filename, data)
- if err != nil {
- err.StatusCode = http.StatusBadRequest
- return nil, err
- }
-
- info.Id = model.NewId()
- info.CreatorId = userId
-
- pathPrefix := "teams/" + teamId + "/channels/" + channelId + "/users/" + userId + "/" + info.Id + "/"
- info.Path = pathPrefix + filename
-
- if info.IsImage() {
- // Check dimensions before loading the whole thing into memory later on
- if info.Width*info.Height > model.MaxImageSize {
- err := model.NewLocAppError("uploadFile", "api.file.upload_file.large_image.app_error", map[string]interface{}{"Filename": filename}, "")
- err.StatusCode = http.StatusBadRequest
- return nil, err
- }
-
- nameWithoutExtension := filename[:strings.LastIndex(filename, ".")]
- info.PreviewPath = pathPrefix + nameWithoutExtension + "_preview.jpg"
- info.ThumbnailPath = pathPrefix + nameWithoutExtension + "_thumb.jpg"
- }
-
- if err := app.WriteFile(data, info.Path); err != nil {
- return nil, err
- }
-
- if result := <-app.Srv.Store.FileInfo().Save(info); result.Err != nil {
- return nil, result.Err
- }
-
- return info, nil
-}
-
-func handleImages(previewPathList []string, thumbnailPathList []string, fileData [][]byte) {
- for i, data := range fileData {
- go func(i int, data []byte) {
- img, width, height := prepareImage(fileData[i])
- if img != nil {
- go generateThumbnailImage(*img, thumbnailPathList[i], width, height)
- go generatePreviewImage(*img, previewPathList[i], width)
- }
- }(i, data)
- }
-}
-
-func prepareImage(fileData []byte) (*image.Image, int, int) {
- // Decode image bytes into Image object
- img, imgType, err := image.Decode(bytes.NewReader(fileData))
- if err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.decode.error"), err)
- return nil, 0, 0
- }
-
- width := img.Bounds().Dx()
- height := img.Bounds().Dy()
-
- // Fill in the background of a potentially-transparent png file as white
- if imgType == "png" {
- dst := image.NewRGBA(img.Bounds())
- draw.Draw(dst, dst.Bounds(), image.NewUniform(color.White), image.Point{}, draw.Src)
- draw.Draw(dst, dst.Bounds(), img, img.Bounds().Min, draw.Over)
- img = dst
- }
-
- // Flip the image to be upright
- orientation, _ := getImageOrientation(fileData)
-
- switch orientation {
- case UprightMirrored:
- img = imaging.FlipH(img)
- case UpsideDown:
- img = imaging.Rotate180(img)
- case UpsideDownMirrored:
- img = imaging.FlipV(img)
- case RotatedCWMirrored:
- img = imaging.Transpose(img)
- case RotatedCCW:
- img = imaging.Rotate270(img)
- case RotatedCCWMirrored:
- img = imaging.Transverse(img)
- case RotatedCW:
- img = imaging.Rotate90(img)
- }
-
- return &img, width, height
-}
-
-func getImageOrientation(imageData []byte) (int, error) {
- if exifData, err := exif.Decode(bytes.NewReader(imageData)); err != nil {
- return Upright, err
- } else {
- if tag, err := exifData.Get("Orientation"); err != nil {
- return Upright, err
- } else {
- orientation, err := tag.Int(0)
- if err != nil {
- return Upright, err
- } else {
- return orientation, nil
- }
- }
- }
-}
-
-func generateThumbnailImage(img image.Image, thumbnailPath string, width int, height int) {
- thumbWidth := float64(utils.Cfg.FileSettings.ThumbnailWidth)
- thumbHeight := float64(utils.Cfg.FileSettings.ThumbnailHeight)
- imgWidth := float64(width)
- imgHeight := float64(height)
-
- var thumbnail image.Image
- if imgHeight < thumbHeight && imgWidth < thumbWidth {
- thumbnail = img
- } else if imgHeight/imgWidth < thumbHeight/thumbWidth {
- thumbnail = imaging.Resize(img, 0, utils.Cfg.FileSettings.ThumbnailHeight, imaging.Lanczos)
- } else {
- thumbnail = imaging.Resize(img, utils.Cfg.FileSettings.ThumbnailWidth, 0, imaging.Lanczos)
- }
-
- buf := new(bytes.Buffer)
- if err := jpeg.Encode(buf, thumbnail, &jpeg.Options{Quality: 90}); err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.encode_jpeg.error"), thumbnailPath, err)
- return
- }
-
- if err := app.WriteFile(buf.Bytes(), thumbnailPath); err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.upload_thumb.error"), thumbnailPath, err)
- return
- }
-}
-
-func generatePreviewImage(img image.Image, previewPath string, width int) {
- var preview image.Image
- if width > int(utils.Cfg.FileSettings.PreviewWidth) {
- preview = imaging.Resize(img, utils.Cfg.FileSettings.PreviewWidth, utils.Cfg.FileSettings.PreviewHeight, imaging.Lanczos)
- } else {
- preview = img
- }
-
- buf := new(bytes.Buffer)
-
- if err := jpeg.Encode(buf, preview, &jpeg.Options{Quality: 90}); err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.encode_preview.error"), previewPath, err)
- return
- }
-
- if err := app.WriteFile(buf.Bytes(), previewPath); err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.upload_preview.error"), previewPath, err)
- return
- }
-}
-
func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
info, err := getFileInfoForRequest(c, r, true)
if err != nil {