summaryrefslogtreecommitdiffstats
path: root/api/file.go
diff options
context:
space:
mode:
authorThomas Balthazar <tbalthazar@users.noreply.github.com>2016-05-18 22:34:31 +0200
committerHarrison Healey <harrisonmhealey@gmail.com>2016-05-18 16:34:31 -0400
commit55f6a0b21c46f77fb33e1af29c5960298bdb6907 (patch)
treea1af9535800ea63fac38f31be18051adb032b2fb /api/file.go
parent02576f3d597b3c419df20f2a50aa6e587f1d98bb (diff)
downloadchat-55f6a0b21c46f77fb33e1af29c5960298bdb6907.tar.gz
chat-55f6a0b21c46f77fb33e1af29c5960298bdb6907.tar.bz2
chat-55f6a0b21c46f77fb33e1af29c5960298bdb6907.zip
Move away from the "andForget" style of function (#3046)
This is the second and last part of the refactoring. First part is documented here: https://github.com/mattermost/platform/pull/3043
Diffstat (limited to 'api/file.go')
-rw-r--r--api/file.go216
1 files changed, 106 insertions, 110 deletions
diff --git a/api/file.go b/api/file.go
index 6cda48866..f4d1e0005 100644
--- a/api/file.go
+++ b/api/file.go
@@ -6,16 +6,6 @@ package api
import (
"bytes"
"fmt"
- l4g "github.com/alecthomas/log4go"
- "github.com/disintegration/imaging"
- "github.com/goamz/goamz/aws"
- "github.com/goamz/goamz/s3"
- "github.com/gorilla/mux"
- "github.com/mattermost/platform/model"
- "github.com/mattermost/platform/utils"
- "github.com/mssola/user_agent"
- "github.com/rwcarlsen/goexif/exif"
- _ "golang.org/x/image/bmp"
"image"
"image/color"
"image/draw"
@@ -30,6 +20,17 @@ import (
"strconv"
"strings"
"time"
+
+ l4g "github.com/alecthomas/log4go"
+ "github.com/disintegration/imaging"
+ "github.com/goamz/goamz/aws"
+ "github.com/goamz/goamz/s3"
+ "github.com/gorilla/mux"
+ "github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/utils"
+ "github.com/mssola/user_agent"
+ "github.com/rwcarlsen/goexif/exif"
+ _ "golang.org/x/image/bmp"
)
const (
@@ -165,110 +166,107 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
resStruct.ClientIds = append(resStruct.ClientIds, clientId)
}
- handleImagesAndForget(imageNameList, imageDataList, c.TeamId, channelId, c.Session.UserId)
+ go handleImages(imageNameList, imageDataList, c.TeamId, channelId, c.Session.UserId)
w.Write([]byte(resStruct.ToJson()))
}
-func handleImagesAndForget(filenames []string, fileData [][]byte, teamId, channelId, userId string) {
+func handleImages(filenames []string, fileData [][]byte, teamId, channelId, userId string) {
+ dest := "teams/" + teamId + "/channels/" + channelId + "/users/" + userId + "/"
+
+ for i, filename := range filenames {
+ name := filename[:strings.LastIndex(filename, ".")]
+ go func() {
+ // Decode image bytes into Image object
+ img, imgType, err := image.Decode(bytes.NewReader(fileData[i]))
+ if err != nil {
+ l4g.Error(utils.T("api.file.handle_images_forget.decode.error"), channelId, userId, filename, err)
+ return
+ }
+
+ width := img.Bounds().Dx()
+ height := img.Bounds().Dy()
+
+ // Get the image's orientation and ignore any errors since not all images will have orientation data
+ orientation, _ := getImageOrientation(fileData[i])
- go func() {
- dest := "teams/" + teamId + "/channels/" + channelId + "/users/" + userId + "/"
+ 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
+ }
+
+ 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)
+ }
- for i, filename := range filenames {
- name := filename[:strings.LastIndex(filename, ".")]
+ // Create thumbnail
go func() {
- // Decode image bytes into Image object
- img, imgType, err := image.Decode(bytes.NewReader(fileData[i]))
+ 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)
+ err = jpeg.Encode(buf, thumbnail, &jpeg.Options{Quality: 90})
if err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.decode.error"), channelId, userId, filename, err)
+ l4g.Error(utils.T("api.file.handle_images_forget.encode_jpeg.error"), channelId, userId, filename, err)
return
}
- width := img.Bounds().Dx()
- height := img.Bounds().Dy()
-
- // Get the image's orientation and ignore any errors since not all images will have orientation data
- orientation, _ := getImageOrientation(fileData[i])
+ if err := WriteFile(buf.Bytes(), dest+name+"_thumb.jpg"); err != nil {
+ l4g.Error(utils.T("api.file.handle_images_forget.upload_thumb.error"), channelId, userId, filename, err)
+ return
+ }
+ }()
- 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
+ // Create preview
+ go func() {
+ 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
}
- 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)
+ buf := new(bytes.Buffer)
+
+ err = jpeg.Encode(buf, preview, &jpeg.Options{Quality: 90})
+ if err != nil {
+ l4g.Error(utils.T("api.file.handle_images_forget.encode_preview.error"), channelId, userId, filename, err)
+ return
}
- // Create thumbnail
- go func() {
- 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)
- err = jpeg.Encode(buf, thumbnail, &jpeg.Options{Quality: 90})
- if err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.encode_jpeg.error"), channelId, userId, filename, err)
- return
- }
-
- if err := WriteFile(buf.Bytes(), dest+name+"_thumb.jpg"); err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.upload_thumb.error"), channelId, userId, filename, err)
- return
- }
- }()
-
- // Create preview
- go func() {
- 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)
-
- err = jpeg.Encode(buf, preview, &jpeg.Options{Quality: 90})
- if err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.encode_preview.error"), channelId, userId, filename, err)
- return
- }
-
- if err := WriteFile(buf.Bytes(), dest+name+"_preview.jpg"); err != nil {
- l4g.Error(utils.T("api.file.handle_images_forget.upload_preview.error"), channelId, userId, filename, err)
- return
- }
- }()
+ if err := WriteFile(buf.Bytes(), dest+name+"_preview.jpg"); err != nil {
+ l4g.Error(utils.T("api.file.handle_images_forget.upload_preview.error"), channelId, userId, filename, err)
+ return
+ }
}()
- }
- }()
+ }()
+ }
}
func getImageOrientation(imageData []byte) (int, error) {
@@ -329,7 +327,7 @@ func getFileInfo(c *Context, w http.ResponseWriter, r *http.Request) {
info = cached.(*model.FileInfo)
} else {
fileData := make(chan []byte)
- getFileAndForget(path, fileData)
+ go readFile(path, fileData)
newInfo, err := model.GetInfoForBytes(filename, <-fileData)
if err != nil {
@@ -435,7 +433,7 @@ func getFileData(teamId string, channelId string, userId string, filename string
path := "teams/" + teamId + "/channels/" + channelId + "/users/" + userId + "/" + filename
fileChan := make(chan []byte)
- getFileAndForget(path, fileChan)
+ go readFile(path, fileChan)
if bytes := <-fileChan; bytes == nil {
err := model.NewLocAppError("writeFileResponse", "api.file.get_file.not_found.app_error", nil, "path="+path)
@@ -472,16 +470,14 @@ func writeFileResponse(filename string, bytes []byte, w http.ResponseWriter, r *
return nil
}
-func getFileAndForget(path string, fileData chan []byte) {
- go func() {
- data, getErr := ReadFile(path)
- if getErr != nil {
- l4g.Error(getErr)
- fileData <- nil
- } else {
- fileData <- data
- }
- }()
+func readFile(path string, fileData chan []byte) {
+ data, getErr := ReadFile(path)
+ if getErr != nil {
+ l4g.Error(getErr)
+ fileData <- nil
+ } else {
+ fileData <- data
+ }
}
func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -588,7 +584,7 @@ func WriteFile(f []byte, path string) *model.AppError {
func MoveFile(oldPath, newPath string) *model.AppError {
if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_S3 {
fileData := make(chan []byte)
- getFileAndForget(oldPath, fileData)
+ go readFile(oldPath, fileData)
fileBytes := <-fileData
if fileBytes == nil {