From 437bdf46d4ded73981e1e1c9e0fe8ca530668e35 Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Sat, 1 Feb 2020 10:34:23 +0800 Subject: [PATCH] Feat: thumb for shared folder --- pkg/filesystem/file.go | 7 +++++ routers/controllers/share.go | 13 +++++++++ routers/router.go | 6 ++++ service/share/visit.go | 55 ++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+) diff --git a/pkg/filesystem/file.go b/pkg/filesystem/file.go index 8ec5fd0..f17d2a7 100644 --- a/pkg/filesystem/file.go +++ b/pkg/filesystem/file.go @@ -311,6 +311,13 @@ func (fs *FileSystem) resetFileIDIfNotExist(ctx context.Context, id uint) error fs.FileTarget = []model.File{file[0]} } + // 如果上下文限制了父目录,则进行检查 + if parent, ok := ctx.Value(fsctx.LimitParentCtx).(*model.Folder); ok { + if parent.ID != fs.FileTarget[0].FolderID { + return ErrObjectNotExist + } + } + // 将当前存储策略重设为文件使用的 return fs.resetPolicyToFirstFile(ctx) } diff --git a/routers/controllers/share.go b/routers/controllers/share.go index 326067b..09612f1 100644 --- a/routers/controllers/share.go +++ b/routers/controllers/share.go @@ -160,3 +160,16 @@ func ArchiveShare(c *gin.Context) { c.JSON(200, ErrorResponse(err)) } } + +// ShareThumb 获取分享目录下文件的缩略图 +func ShareThumb(c *gin.Context) { + var service share.Service + if err := c.ShouldBindQuery(&service); err == nil { + res := service.Thumb(c) + if res.Code >= 0 { + c.JSON(200, res) + } + } else { + c.JSON(200, ErrorResponse(err)) + } +} diff --git a/routers/router.go b/routers/router.go index a6616d8..324f99c 100644 --- a/routers/router.go +++ b/routers/router.go @@ -214,6 +214,12 @@ func InitMasterRouter() *gin.Engine { middleware.CheckShareUnlocked(), controllers.PreviewShareReadme, ) + // 获取缩略图 + share.GET("thumb/:id/:file", + middleware.CheckShareUnlocked(), + middleware.ShareCanPreview(), + controllers.ShareThumb, + ) } // 需要登录保护的 diff --git a/service/share/visit.go b/service/share/visit.go index f6a9b31..db1164f 100644 --- a/service/share/visit.go +++ b/service/share/visit.go @@ -11,7 +11,9 @@ import ( "github.com/HFO4/cloudreve/pkg/util" "github.com/HFO4/cloudreve/service/explorer" "github.com/gin-gonic/gin" + "net/http" "path" + "strconv" ) // ShareGetService 获取分享服务 @@ -219,6 +221,58 @@ func (service *Service) List(c *gin.Context) serializer.Response { } } +// Thumb 获取被分享文件的缩略图 +func (service *Service) Thumb(c *gin.Context) serializer.Response { + shareCtx, _ := c.Get("share") + share := shareCtx.(*model.Share) + + if !share.IsDir { + return serializer.ParamErr("此分享无缩略图", nil) + } + + // 创建文件系统 + fs, err := filesystem.NewFileSystem(share.GetCreator()) + if err != nil { + return serializer.Err(serializer.CodePolicyNotAllowed, err.Error(), err) + } + defer fs.Recycle() + + // 重设根目录 + fs.Root = share.GetSource().(*model.Folder) + + // 找到缩略图的父目录 + exist, parent := fs.IsPathExist(service.Path) + if !exist { + return serializer.Err(serializer.CodeNotFound, "路径不存在", nil) + } + + ctx := context.WithValue(context.Background(), fsctx.LimitParentCtx, parent) + + // 获取文件ID + fileID, err := strconv.ParseUint(c.Param("file"), 10, 32) + if err != nil { + return serializer.ParamErr("无法解析文件ID", err) + } + + // 获取缩略图 + resp, err := fs.GetThumb(ctx, uint(fileID)) + if err != nil { + return serializer.Err(serializer.CodeNotSet, "无法获取缩略图", err) + } + + if resp.Redirect { + c.Header("Cache-Control", fmt.Sprintf("max-age=%d", resp.MaxAge)) + c.Redirect(http.StatusMovedPermanently, resp.URL) + return serializer.Response{Code: -1} + } + + defer resp.Content.Close() + http.ServeContent(c.Writer, c.Request, "thumb.png", fs.FileTarget[0].UpdatedAt, resp.Content) + + return serializer.Response{Code: -1} + +} + // Archive 创建批量下载归档 func (service *ArchiveService) Archive(c *gin.Context) serializer.Response { shareCtx, _ := c.Get("share") @@ -251,6 +305,7 @@ func (service *ArchiveService) Archive(c *gin.Context) serializer.Response { return serializer.Err(serializer.CodeNotFound, "路径不存在", nil) } + // 限制操作范围为父目录下 ctx := context.WithValue(context.Background(), fsctx.LimitParentCtx, parent) // 用于调下层service