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/checker"
|
||||||
"github.com/answerdev/answer/pkg/dir"
|
"github.com/answerdev/answer/pkg/dir"
|
||||||
"github.com/answerdev/answer/pkg/uid"
|
"github.com/answerdev/answer/pkg/uid"
|
||||||
|
"github.com/answerdev/answer/plugin"
|
||||||
"github.com/disintegration/imaging"
|
"github.com/disintegration/imaging"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/segmentfault/pacman/errors"
|
"github.com/segmentfault/pacman/errors"
|
||||||
|
"github.com/segmentfault/pacman/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -70,6 +72,14 @@ func NewUploaderService(serviceConfig *service_config.ServiceConfig,
|
||||||
|
|
||||||
// UploadAvatarFile upload avatar file
|
// UploadAvatarFile upload avatar file
|
||||||
func (us *UploaderService) UploadAvatarFile(ctx *gin.Context) (url string, err error) {
|
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
|
// max size
|
||||||
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, 5*1024*1024)
|
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, 5*1024*1024)
|
||||||
_, file, err := ctx.Request.FormFile("file")
|
_, 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) (
|
func (us *UploaderService) UploadPostFile(ctx *gin.Context) (
|
||||||
url string, err error) {
|
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
|
// max size
|
||||||
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, 10*1024*1024)
|
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, 10*1024*1024)
|
||||||
_, file, err := ctx.Request.FormFile("file")
|
_, file, err := ctx.Request.FormFile("file")
|
||||||
|
@ -159,6 +177,14 @@ func (us *UploaderService) UploadPostFile(ctx *gin.Context) (
|
||||||
|
|
||||||
func (us *UploaderService) UploadBrandingFile(ctx *gin.Context) (
|
func (us *UploaderService) UploadBrandingFile(ctx *gin.Context) (
|
||||||
url string, err error) {
|
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
|
// max size
|
||||||
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, 10*1024*1024)
|
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, 10*1024*1024)
|
||||||
_, file, err := ctx.Request.FormFile("file")
|
_, 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)
|
url = fmt.Sprintf("%s/uploads/%s", siteGeneral.SiteUrl, fileSubPath)
|
||||||
return url, nil
|
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 {
|
if _, ok := p.(Filter); ok {
|
||||||
registerFilter(p.(Filter))
|
registerFilter(p.(Filter))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, ok := p.(Storage); ok {
|
||||||
|
registerStorage(p.(Storage))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Stack[T Base] struct {
|
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