From 7fbbcefc57ae80be95835666806466d254b6679f Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Wed, 15 Jan 2020 14:15:25 +0800 Subject: [PATCH] Feat: get thumb & download file in qiniu policy --- pkg/filesystem/fsctx/context.go | 2 ++ pkg/filesystem/image.go | 3 ++ pkg/filesystem/manage.go | 4 +++ pkg/filesystem/qiniu/handller.go | 46 +++++++++++++++++++++++++-- pkg/filesystem/remote/handler.go | 2 +- pkg/filesystem/remote/handler_test.go | 2 +- pkg/filesystem/validator.go | 5 +++ pkg/filesystem/validator_test.go | 2 ++ 8 files changed, 62 insertions(+), 4 deletions(-) diff --git a/pkg/filesystem/fsctx/context.go b/pkg/filesystem/fsctx/context.go index 66a10bb..2005c7b 100644 --- a/pkg/filesystem/fsctx/context.go +++ b/pkg/filesystem/fsctx/context.go @@ -19,4 +19,6 @@ const ( UploadPolicyCtx // UserCtx 用户 UserCtx + // ThumbSizeCtx 缩略图尺寸 + ThumbSizeCtx ) diff --git a/pkg/filesystem/image.go b/pkg/filesystem/image.go index 1a4fbec..7d23ea5 100644 --- a/pkg/filesystem/image.go +++ b/pkg/filesystem/image.go @@ -5,6 +5,7 @@ import ( "fmt" model "github.com/HFO4/cloudreve/models" "github.com/HFO4/cloudreve/pkg/conf" + "github.com/HFO4/cloudreve/pkg/filesystem/fsctx" "github.com/HFO4/cloudreve/pkg/filesystem/response" "github.com/HFO4/cloudreve/pkg/thumb" "github.com/HFO4/cloudreve/pkg/util" @@ -28,6 +29,8 @@ func (fs *FileSystem) GetThumb(ctx context.Context, id uint) (*response.ContentR }, ErrObjectNotExist } + w, h := fs.GenerateThumbnailSize(0, 0) + ctx = context.WithValue(ctx, fsctx.ThumbSizeCtx, [2]uint{w, h}) res, err := fs.Handler.Thumb(ctx, fs.FileTarget[0].SourceName) // TODO 出错时重新生成缩略图 diff --git a/pkg/filesystem/manage.go b/pkg/filesystem/manage.go index b53c283..9fef4c3 100644 --- a/pkg/filesystem/manage.go +++ b/pkg/filesystem/manage.go @@ -7,6 +7,7 @@ import ( "github.com/HFO4/cloudreve/pkg/serializer" "github.com/HFO4/cloudreve/pkg/util" "path" + "strings" ) /* ================= @@ -322,6 +323,9 @@ func (fs *FileSystem) CreateDirectory(ctx context.Context, fullPath string) erro base := path.Dir(fullPath) dir := path.Base(fullPath) + // 去掉结尾空格 + dir = strings.TrimRight(dir, " ") + // 检查目录名是否合法 if !fs.ValidateLegalName(ctx, dir) { return ErrIllegalObjectName diff --git a/pkg/filesystem/qiniu/handller.go b/pkg/filesystem/qiniu/handller.go index cd717e0..52365e8 100644 --- a/pkg/filesystem/qiniu/handller.go +++ b/pkg/filesystem/qiniu/handller.go @@ -3,6 +3,7 @@ package qiniu import ( "context" "errors" + "fmt" model "github.com/HFO4/cloudreve/models" "github.com/HFO4/cloudreve/pkg/filesystem/fsctx" "github.com/HFO4/cloudreve/pkg/filesystem/response" @@ -11,6 +12,7 @@ import ( "github.com/qiniu/api.v7/v7/storage" "io" "net/url" + "time" ) // Handler 本地策略适配器 @@ -61,7 +63,23 @@ func (handler Handler) Delete(ctx context.Context, files []string) ([]string, er // Thumb 获取文件缩略图 func (handler Handler) Thumb(ctx context.Context, path string) (*response.ContentResponse, error) { - return nil, errors.New("未实现") + var ( + thumbSize = [2]uint{400, 300} + ok = false + ) + if thumbSize, ok = ctx.Value(fsctx.ThumbSizeCtx).([2]uint); !ok { + return nil, errors.New("无法获取缩略图尺寸设置") + } + + path = fmt.Sprintf("%s?imageView2/1/w/%d/h/%d", path, thumbSize[0], thumbSize[1]) + return &response.ContentResponse{ + Redirect: true, + URL: handler.signSourceURL( + ctx, + path, + int64(model.GetIntSetting("preview_timeout", 60)), + ), + }, nil } // Source 获取外链URL @@ -73,7 +91,31 @@ func (handler Handler) Source( isDownload bool, speed int, ) (string, error) { - return "", errors.New("未实现") + // 尝试从上下文获取文件名 + fileName := "" + if file, ok := ctx.Value(fsctx.FileModelCtx).(model.File); ok { + fileName = file.Name + } + + // 加入下载相关设置 + if isDownload { + path = path + "?attname=" + url.PathEscape(fileName) + } + + // 取得原始文件地址 + return handler.signSourceURL(ctx, path, ttl), nil +} + +func (handler Handler) signSourceURL(ctx context.Context, path string, ttl int64) string { + var sourceURL string + if handler.Policy.IsPrivate { + mac := qbox.NewMac(handler.Policy.AccessKey, handler.Policy.SecretKey) + deadline := time.Now().Add(time.Second * time.Duration(ttl)).Unix() + sourceURL = storage.MakePrivateURL(mac, handler.Policy.BaseURL, path, deadline) + } else { + sourceURL = storage.MakePublicURL(handler.Policy.BaseURL, path) + } + return sourceURL } // Token 获取上传策略和认证Token diff --git a/pkg/filesystem/remote/handler.go b/pkg/filesystem/remote/handler.go index 9741d69..ec7403e 100644 --- a/pkg/filesystem/remote/handler.go +++ b/pkg/filesystem/remote/handler.go @@ -174,7 +174,7 @@ func (handler Handler) Delete(ctx context.Context, files []string) ([]string, er func (handler Handler) Thumb(ctx context.Context, path string) (*response.ContentResponse, error) { sourcePath := base64.RawURLEncoding.EncodeToString([]byte(path)) thumbURL := handler.getAPIUrl("thumb") + "/" + sourcePath - ttl := model.GetIntSetting("slave_api_timeout", 60) + ttl := model.GetIntSetting("preview_timeout", 60) signedThumbURL, err := auth.SignURI(handler.AuthInstance, thumbURL, int64(ttl)) if err != nil { return nil, err diff --git a/pkg/filesystem/remote/handler_test.go b/pkg/filesystem/remote/handler_test.go index ede1e55..75402c6 100644 --- a/pkg/filesystem/remote/handler_test.go +++ b/pkg/filesystem/remote/handler_test.go @@ -347,7 +347,7 @@ func TestHandler_Thumb(t *testing.T) { AuthInstance: auth.HMACAuth{}, } ctx := context.Background() - asserts.NoError(cache.Set("setting_slave_api_timeout", "60", 0)) + asserts.NoError(cache.Set("preview_timeout", "60", 0)) resp, err := handler.Thumb(ctx, "/1.txt") asserts.NoError(err) asserts.True(resp.Redirect) diff --git a/pkg/filesystem/validator.go b/pkg/filesystem/validator.go index 30e7453..66c2c36 100644 --- a/pkg/filesystem/validator.go +++ b/pkg/filesystem/validator.go @@ -34,6 +34,11 @@ func (fs *FileSystem) ValidateLegalName(ctx context.Context, name string) bool { return false } + // 结尾不能是空格 + if strings.HasSuffix(name, " ") { + return false + } + return true } diff --git a/pkg/filesystem/validator_test.go b/pkg/filesystem/validator_test.go index 2dffc7a..e19ce42 100644 --- a/pkg/filesystem/validator_test.go +++ b/pkg/filesystem/validator_test.go @@ -38,6 +38,8 @@ func TestFileSystem_ValidateLegalName(t *testing.T) { asserts.False(fs.ValidateLegalName(ctx, "/11.txt")) asserts.False(fs.ValidateLegalName(ctx, "\\11.txt")) asserts.False(fs.ValidateLegalName(ctx, "")) + asserts.False(fs.ValidateLegalName(ctx, "1.tx t ")) + asserts.True(fs.ValidateLegalName(ctx, "1.tx t")) } func TestFileSystem_ValidateCapacity(t *testing.T) {