From 2de6c5394ec3a1cd974aae46c41f61fb0e9f9bd8 Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Fri, 20 Jan 2017 14:47:14 +0000 Subject: Move Slack Import to App Layer. (#5135) --- api/file.go | 191 +----------------------------------------------------------- 1 file changed, 2 insertions(+), 189 deletions(-) (limited to 'api/file.go') 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 { -- cgit v1.2.3-1-g7c22