-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Add new Upload service for image upload - Add configuration in `config.yaml` - Generate access URL for articles Issue #6
- Loading branch information
Showing
8 changed files
with
224 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package api | ||
|
||
import ( | ||
"github.com/gin-gonic/gin" | ||
"github.com/lc-1010/OneBlogService/global" | ||
"github.com/lc-1010/OneBlogService/internal/service" | ||
"github.com/lc-1010/OneBlogService/pkg/app" | ||
"github.com/lc-1010/OneBlogService/pkg/convert" | ||
"github.com/lc-1010/OneBlogService/pkg/errcode" | ||
"github.com/lc-1010/OneBlogService/pkg/upload" | ||
) | ||
|
||
type Upload struct{} | ||
|
||
func NewUpload() Upload { | ||
return Upload{} | ||
} | ||
|
||
func (u Upload) UploadFile(c *gin.Context) { | ||
param := service.UploadParams{ | ||
FormName: "file", | ||
FormFileType: "type", | ||
} | ||
response := app.NewResponse(c) | ||
file, fileHeader, err := c.Request.FormFile(param.FormName) | ||
if err != nil { | ||
response.ToErrorResponse(errcode.InvalidParams.WithDetails(err.Error())) | ||
return | ||
} | ||
fileType := convert.StrTo(c.PostForm(param.FormFileType)).MustInt() | ||
if fileHeader == nil || fileType <= 0 { | ||
response.ToErrorResponse(errcode.InvalidParams) | ||
return | ||
} | ||
svc := service.New(c.Request.Context()) | ||
fileInfo, err := svc.UploadFile(upload.FileType(fileType), file, fileHeader) | ||
if err != nil { | ||
global.Logger.Errorf(c, "svc.UploadFile err:%v", err) | ||
response.ToErrorResponse(errcode.ErrorUpdateTagFail.WithDetails(err.Error())) | ||
return | ||
} | ||
response.ToResponse(gin.H{ | ||
"file_access_url": fileInfo.AccessUrl, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package service | ||
|
||
import ( | ||
"errors" | ||
"mime/multipart" | ||
"os" | ||
|
||
"github.com/lc-1010/OneBlogService/global" | ||
"github.com/lc-1010/OneBlogService/pkg/upload" | ||
) | ||
|
||
type FileInfo struct { | ||
Name string | ||
AccessUrl string | ||
} | ||
|
||
type UploadParams struct { | ||
FormName string `json:"file,omitempty"` | ||
FormFileType string `json:"type,omitempty"` | ||
} | ||
|
||
func (svc *Service) UploadFile(fileType upload.FileType, file multipart.File, | ||
fileHeader *multipart.FileHeader) (*FileInfo, error) { | ||
|
||
fileName := upload.GetFileNmae(fileHeader.Filename) | ||
if !upload.CheckAllowExt(fileType, fileName) { | ||
return nil, errors.New("file suffix is not supported") | ||
} | ||
if upload.CheckOverMaxSize(fileType, file) { | ||
return nil, errors.New("exceeded maximux file limit") | ||
} | ||
|
||
uploadSavePath := upload.GetSavePath() | ||
if upload.CheckSavePath(uploadSavePath) { | ||
if err := upload.CreateSavePath(uploadSavePath, os.ModePerm); err != nil { | ||
return nil, errors.New("falied to create save directory") | ||
} | ||
} | ||
if upload.CheckPermission(uploadSavePath) { | ||
return nil, errors.New("insufficient file permissions") | ||
} | ||
dst := uploadSavePath + "/" + fileName | ||
if err := upload.SaveFile(fileHeader, dst); err != nil { | ||
return nil, err | ||
} | ||
accessUrl := global.AppSetting.UploadServerUrl + "/" + fileName | ||
|
||
return &FileInfo{Name: fileName, AccessUrl: accessUrl}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package upload | ||
|
||
import ( | ||
"io" | ||
"io/ioutil" | ||
"mime/multipart" | ||
"os" | ||
"path" | ||
"strings" | ||
|
||
"github.com/lc-1010/OneBlogService/global" | ||
"github.com/lc-1010/OneBlogService/pkg/util" | ||
) | ||
|
||
type FileType int | ||
|
||
const ( | ||
TypeImage FileType = iota + 1 | ||
TypeExcel | ||
TypeTxt | ||
) | ||
|
||
func GetFileExt(name string) string { | ||
return path.Ext(name) | ||
} | ||
|
||
func GetSavePath() string { | ||
return global.AppSetting.UploadSavePath | ||
} | ||
func CheckSavePath(dst string) bool { | ||
_, err := os.Stat(dst) | ||
return os.IsNotExist(err) | ||
} | ||
|
||
// GetFileNmae return md5string name | ||
func GetFileNmae(name string) string { | ||
ext := GetFileExt(name) | ||
fileName := strings.TrimSuffix(name, ext) | ||
fileName = util.EncodeMD5(fileName) | ||
return fileName + ext | ||
} | ||
|
||
func CheckAllowExt(t FileType, name string) bool { | ||
ext := GetFileExt(name) | ||
ext = strings.ToUpper(ext) | ||
switch t { | ||
case TypeImage: | ||
for _, allowExt := range global.AppSetting.UploadImageAllowExts { | ||
if strings.ToUpper(allowExt) == ext { | ||
return true | ||
} | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func CheckOverMaxSize(t FileType, f multipart.File) bool { | ||
content, _ := ioutil.ReadAll(f) | ||
size := len(content) | ||
switch t { | ||
case TypeImage: | ||
if size >= global.AppSetting.UploadImageMaxSize*1024*1024 { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func CreateSavePath(dst string, perm os.FileMode) error { | ||
err := os.MkdirAll(dst, perm) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func CheckPermission(dst string) bool { | ||
_, err := os.Stat(dst) | ||
return os.IsPermission(err) | ||
} | ||
|
||
func SaveFile(file *multipart.FileHeader, dst string) error { | ||
src, err := file.Open() | ||
if err != nil { | ||
return err | ||
} | ||
defer src.Close() | ||
out, err := os.Create(dst) | ||
if err != nil { | ||
return err | ||
} | ||
defer out.Close() | ||
_, err = io.Copy(out, src) | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package util | ||
|
||
import ( | ||
"crypto/md5" | ||
"encoding/hex" | ||
) | ||
|
||
func EncodeMD5(value string) string { | ||
m := md5.New() | ||
m.Write([]byte(value)) | ||
return hex.EncodeToString(m.Sum(nil)) | ||
} |