mirror of https://gitee.com/answerdev/answer.git
fix(plugin): Add storage plugin interface
This commit is contained in:
parent
d5b5d9a51c
commit
1f05338aae
|
@ -17,9 +17,11 @@ import (
|
|||
"github.com/answerdev/answer/pkg/checker"
|
||||
"github.com/answerdev/answer/pkg/dir"
|
||||
"github.com/answerdev/answer/pkg/uid"
|
||||
"github.com/answerdev/answer/plugin"
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -70,6 +72,14 @@ func NewUploaderService(serviceConfig *service_config.ServiceConfig,
|
|||
|
||||
// UploadAvatarFile upload avatar file
|
||||
func (us *UploaderService) UploadAvatarFile(ctx *gin.Context) (url string, err error) {
|
||||
url, err = us.tryToUploadByPlugin(ctx, plugin.UserAvatar)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(url) > 0 {
|
||||
return url, nil
|
||||
}
|
||||
|
||||
// max size
|
||||
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, 5*1024*1024)
|
||||
_, file, err := ctx.Request.FormFile("file")
|
||||
|
@ -141,6 +151,14 @@ func (us *UploaderService) AvatarThumbFile(ctx *gin.Context, uploadPath, fileNam
|
|||
|
||||
func (us *UploaderService) UploadPostFile(ctx *gin.Context) (
|
||||
url string, err error) {
|
||||
url, err = us.tryToUploadByPlugin(ctx, plugin.UserAvatar)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(url) > 0 {
|
||||
return url, nil
|
||||
}
|
||||
|
||||
// max size
|
||||
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, 10*1024*1024)
|
||||
_, file, err := ctx.Request.FormFile("file")
|
||||
|
@ -159,6 +177,14 @@ func (us *UploaderService) UploadPostFile(ctx *gin.Context) (
|
|||
|
||||
func (us *UploaderService) UploadBrandingFile(ctx *gin.Context) (
|
||||
url string, err error) {
|
||||
url, err = us.tryToUploadByPlugin(ctx, plugin.UserAvatar)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(url) > 0 {
|
||||
return url, nil
|
||||
}
|
||||
|
||||
// max size
|
||||
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, 10*1024*1024)
|
||||
_, file, err := ctx.Request.FormFile("file")
|
||||
|
@ -200,3 +226,18 @@ func (us *UploaderService) uploadFile(ctx *gin.Context, file *multipart.FileHead
|
|||
url = fmt.Sprintf("%s/uploads/%s", siteGeneral.SiteUrl, fileSubPath)
|
||||
return url, nil
|
||||
}
|
||||
|
||||
func (us *UploaderService) tryToUploadByPlugin(ctx *gin.Context, source plugin.UploadSource) (
|
||||
url string, err error) {
|
||||
_ = plugin.CallStorage(func(fn plugin.Storage) error {
|
||||
resp := fn.UploadFile(ctx, source)
|
||||
if resp.OriginalError != nil {
|
||||
log.Errorf("upload file by plugin failed, err: %v", resp.OriginalError)
|
||||
err = errors.BadRequest("").WithMsg(resp.DisplayErrorMsg.Translate(ctx)).WithError(err)
|
||||
} else {
|
||||
url = resp.FullURL
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return url, err
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ func Register(p Base) {
|
|||
if _, ok := p.(Filter); ok {
|
||||
registerFilter(p.(Filter))
|
||||
}
|
||||
|
||||
if _, ok := p.(Storage); ok {
|
||||
registerStorage(p.(Storage))
|
||||
}
|
||||
}
|
||||
|
||||
type Stack[T Base] struct {
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package plugin
|
||||
|
||||
type UploadSource string
|
||||
|
||||
const (
|
||||
UserAvatar UploadSource = "user_avatar"
|
||||
UserPost UploadSource = "user_post"
|
||||
AdminBranding UploadSource = "admin_branding"
|
||||
)
|
||||
|
||||
type UploadFileResponse struct {
|
||||
// FullURL is the URL that can be used to access the file
|
||||
FullURL string
|
||||
// OriginalError is the error returned by the storage plugin. It is used for debugging.
|
||||
OriginalError error
|
||||
// DisplayErrorMsg is the error message that will be displayed to the user.
|
||||
DisplayErrorMsg Translator
|
||||
}
|
||||
|
||||
type Storage interface {
|
||||
Base
|
||||
|
||||
// UploadFile uploads a file to storage.
|
||||
// The file is in the Form of the ctx and the key is "file"
|
||||
UploadFile(ctx *GinContext, source UploadSource) UploadFileResponse
|
||||
}
|
||||
|
||||
var (
|
||||
// CallStorage is a function that calls all registered storage
|
||||
CallStorage,
|
||||
registerStorage = MakePlugin[Storage](false)
|
||||
)
|
Loading…
Reference in New Issue