github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/routers/controllers/file.go (about)

     1  package controllers
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"github.com/cloudreve/Cloudreve/v3/pkg/filesystem"
     7  	"net/http"
     8  
     9  	model "github.com/cloudreve/Cloudreve/v3/models"
    10  	"github.com/cloudreve/Cloudreve/v3/pkg/request"
    11  	"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
    12  	"github.com/cloudreve/Cloudreve/v3/service/explorer"
    13  	"github.com/gin-gonic/gin"
    14  )
    15  
    16  func DownloadArchive(c *gin.Context) {
    17  	// 创建上下文
    18  	ctx, cancel := context.WithCancel(context.Background())
    19  	defer cancel()
    20  
    21  	var service explorer.ArchiveService
    22  	if err := c.ShouldBindUri(&service); err == nil {
    23  		service.DownloadArchived(ctx, c)
    24  	} else {
    25  		c.JSON(200, ErrorResponse(err))
    26  	}
    27  }
    28  
    29  func Archive(c *gin.Context) {
    30  	// 创建上下文
    31  	ctx, cancel := context.WithCancel(context.Background())
    32  	defer cancel()
    33  
    34  	var service explorer.ItemIDService
    35  	if err := c.ShouldBindJSON(&service); err == nil {
    36  		res := service.Archive(ctx, c)
    37  		c.JSON(200, res)
    38  	} else {
    39  		c.JSON(200, ErrorResponse(err))
    40  	}
    41  }
    42  
    43  // Compress 创建文件压缩任务
    44  func Compress(c *gin.Context) {
    45  	var service explorer.ItemCompressService
    46  	if err := c.ShouldBindJSON(&service); err == nil {
    47  		res := service.CreateCompressTask(c)
    48  		c.JSON(200, res)
    49  	} else {
    50  		c.JSON(200, ErrorResponse(err))
    51  	}
    52  }
    53  
    54  // Decompress 创建文件解压缩任务
    55  func Decompress(c *gin.Context) {
    56  	var service explorer.ItemDecompressService
    57  	if err := c.ShouldBindJSON(&service); err == nil {
    58  		res := service.CreateDecompressTask(c)
    59  		c.JSON(200, res)
    60  	} else {
    61  		c.JSON(200, ErrorResponse(err))
    62  	}
    63  }
    64  
    65  // AnonymousGetContent 匿名获取文件资源
    66  func AnonymousGetContent(c *gin.Context) {
    67  	// 创建上下文
    68  	ctx, cancel := context.WithCancel(context.Background())
    69  	defer cancel()
    70  
    71  	var service explorer.FileAnonymousGetService
    72  	if err := c.ShouldBindUri(&service); err == nil {
    73  		res := service.Download(ctx, c)
    74  		if res.Code != 0 {
    75  			c.JSON(200, res)
    76  		}
    77  	} else {
    78  		c.JSON(200, ErrorResponse(err))
    79  	}
    80  }
    81  
    82  // AnonymousPermLink Deprecated 文件签名后的永久链接
    83  func AnonymousPermLinkDeprecated(c *gin.Context) {
    84  	// 创建上下文
    85  	ctx, cancel := context.WithCancel(context.Background())
    86  	defer cancel()
    87  
    88  	var service explorer.FileAnonymousGetService
    89  	if err := c.ShouldBindUri(&service); err == nil {
    90  		res := service.Source(ctx, c)
    91  		// 是否需要重定向
    92  		if res.Code == -302 {
    93  			c.Redirect(302, res.Data.(string))
    94  			return
    95  		}
    96  		// 是否有错误发生
    97  		if res.Code != 0 {
    98  			c.JSON(200, res)
    99  		}
   100  	} else {
   101  		c.JSON(200, ErrorResponse(err))
   102  	}
   103  }
   104  
   105  // AnonymousPermLink 文件中转后的永久直链接
   106  func AnonymousPermLink(c *gin.Context) {
   107  	// 创建上下文
   108  	ctx, cancel := context.WithCancel(context.Background())
   109  	defer cancel()
   110  
   111  	sourceLinkRaw, ok := c.Get("source_link")
   112  	if !ok {
   113  		c.JSON(200, serializer.Err(serializer.CodeFileNotFound, "", nil))
   114  		return
   115  	}
   116  
   117  	sourceLink := sourceLinkRaw.(*model.SourceLink)
   118  
   119  	service := &explorer.FileAnonymousGetService{
   120  		ID:   sourceLink.FileID,
   121  		Name: sourceLink.File.Name,
   122  	}
   123  
   124  	res := service.Source(ctx, c)
   125  	// 是否需要重定向
   126  	if res.Code == -302 {
   127  		c.Redirect(302, res.Data.(string))
   128  		return
   129  	}
   130  
   131  	// 是否有错误发生
   132  	if res.Code != 0 {
   133  		c.JSON(200, res)
   134  	}
   135  
   136  }
   137  
   138  func GetSource(c *gin.Context) {
   139  	// 创建上下文
   140  	ctx, cancel := context.WithCancel(context.Background())
   141  	defer cancel()
   142  
   143  	var service explorer.ItemIDService
   144  	if err := c.ShouldBindJSON(&service); err == nil {
   145  		res := service.Sources(ctx, c)
   146  		c.JSON(200, res)
   147  	} else {
   148  		c.JSON(200, ErrorResponse(err))
   149  	}
   150  }
   151  
   152  // Thumb 获取文件缩略图
   153  func Thumb(c *gin.Context) {
   154  	// 创建上下文
   155  	ctx, cancel := context.WithCancel(context.Background())
   156  	defer cancel()
   157  
   158  	fs, err := filesystem.NewFileSystemFromContext(c)
   159  	if err != nil {
   160  		c.JSON(200, serializer.Err(serializer.CodePolicyNotAllowed, err.Error(), err))
   161  		return
   162  	}
   163  	defer fs.Recycle()
   164  
   165  	// 获取文件ID
   166  	fileID, ok := c.Get("object_id")
   167  	if !ok {
   168  		c.JSON(200, serializer.Err(serializer.CodeFileNotFound, "", err))
   169  		return
   170  	}
   171  
   172  	// 获取缩略图
   173  	resp, err := fs.GetThumb(ctx, fileID.(uint))
   174  	if err != nil {
   175  		c.JSON(200, serializer.Err(serializer.CodeNotSet, "Failed to get thumbnail", err))
   176  		return
   177  	}
   178  
   179  	if resp.Redirect {
   180  		c.Header("Cache-Control", fmt.Sprintf("max-age=%d", resp.MaxAge))
   181  		c.Redirect(http.StatusMovedPermanently, resp.URL)
   182  		return
   183  	}
   184  
   185  	defer resp.Content.Close()
   186  	http.ServeContent(c.Writer, c.Request, "thumb."+model.GetSettingByNameWithDefault("thumb_encode_method", "jpg"), fs.FileTarget[0].UpdatedAt, resp.Content)
   187  
   188  }
   189  
   190  // Preview 预览文件
   191  func Preview(c *gin.Context) {
   192  	// 创建上下文
   193  	ctx, cancel := context.WithCancel(context.Background())
   194  	defer cancel()
   195  
   196  	var service explorer.FileIDService
   197  	if err := c.ShouldBindUri(&service); err == nil {
   198  		res := service.PreviewContent(ctx, c, false)
   199  		// 是否需要重定向
   200  		if res.Code == -301 {
   201  			c.Redirect(302, res.Data.(string))
   202  			return
   203  		}
   204  		// 是否有错误发生
   205  		if res.Code != 0 {
   206  			c.JSON(200, res)
   207  		}
   208  	} else {
   209  		c.JSON(200, ErrorResponse(err))
   210  	}
   211  }
   212  
   213  // PreviewText 预览文本文件
   214  func PreviewText(c *gin.Context) {
   215  	// 创建上下文
   216  	ctx, cancel := context.WithCancel(context.Background())
   217  	defer cancel()
   218  
   219  	var service explorer.FileIDService
   220  	if err := c.ShouldBindUri(&service); err == nil {
   221  		res := service.PreviewContent(ctx, c, true)
   222  		// 是否有错误发生
   223  		if res.Code != 0 {
   224  			c.JSON(200, res)
   225  		}
   226  	} else {
   227  		c.JSON(200, ErrorResponse(err))
   228  	}
   229  }
   230  
   231  // GetDocPreview 获取DOC文件预览地址
   232  func GetDocPreview(c *gin.Context) {
   233  	// 创建上下文
   234  	ctx, cancel := context.WithCancel(context.Background())
   235  	defer cancel()
   236  
   237  	var service explorer.FileIDService
   238  	if err := c.ShouldBindUri(&service); err == nil {
   239  		res := service.CreateDocPreviewSession(ctx, c, true)
   240  		c.JSON(200, res)
   241  	} else {
   242  		c.JSON(200, ErrorResponse(err))
   243  	}
   244  }
   245  
   246  // CreateDownloadSession 创建文件下载会话
   247  func CreateDownloadSession(c *gin.Context) {
   248  	// 创建上下文
   249  	ctx, cancel := context.WithCancel(context.Background())
   250  	defer cancel()
   251  
   252  	var service explorer.FileIDService
   253  	if err := c.ShouldBindUri(&service); err == nil {
   254  		res := service.CreateDownloadSession(ctx, c)
   255  		c.JSON(200, res)
   256  	} else {
   257  		c.JSON(200, ErrorResponse(err))
   258  	}
   259  }
   260  
   261  // Download 文件下载
   262  func Download(c *gin.Context) {
   263  	// 创建上下文
   264  	ctx, cancel := context.WithCancel(context.Background())
   265  	defer cancel()
   266  
   267  	var service explorer.DownloadService
   268  	if err := c.ShouldBindUri(&service); err == nil {
   269  		res := service.Download(ctx, c)
   270  		if res.Code != 0 {
   271  			c.JSON(200, res)
   272  		}
   273  	} else {
   274  		c.JSON(200, ErrorResponse(err))
   275  	}
   276  }
   277  
   278  // PutContent 更新文件内容
   279  func PutContent(c *gin.Context) {
   280  	// 创建上下文
   281  	ctx, cancel := context.WithCancel(context.Background())
   282  	defer cancel()
   283  
   284  	var service explorer.FileIDService
   285  	if err := c.ShouldBindUri(&service); err == nil {
   286  		res := service.PutContent(ctx, c)
   287  		c.JSON(200, res)
   288  	} else {
   289  		c.JSON(200, ErrorResponse(err))
   290  	}
   291  }
   292  
   293  // FileUpload 本地策略文件上传
   294  func FileUpload(c *gin.Context) {
   295  	// 创建上下文
   296  	ctx, cancel := context.WithCancel(context.Background())
   297  	defer cancel()
   298  
   299  	var service explorer.UploadService
   300  	if err := c.ShouldBindUri(&service); err == nil {
   301  		res := service.LocalUpload(ctx, c)
   302  		c.JSON(200, res)
   303  		request.BlackHole(c.Request.Body)
   304  	} else {
   305  		c.JSON(200, ErrorResponse(err))
   306  	}
   307  
   308  	//fileData := fsctx.FileStream{
   309  	//	MIMEType:    c.Request.Header.Get("Content-Type"),
   310  	//	File:        c.Request.Body,
   311  	//	Size:        fileSize,
   312  	//	Name:        fileName,
   313  	//	VirtualPath: filePath,
   314  	//	Mode:        fsctx.Create,
   315  	//}
   316  	//
   317  	//// 创建文件系统
   318  	//fs, err := filesystem.NewFileSystemFromContext(c)
   319  	//if err != nil {
   320  	//	c.JSON(200, serializer.Err(serializer.CodePolicyNotAllowed, err.Error(), err))
   321  	//	return
   322  	//}
   323  	//
   324  	//// 非可用策略时拒绝上传
   325  	//if !fs.Policy.IsTransitUpload(fileSize) {
   326  	//	request.BlackHole(c.Request.Body)
   327  	//	c.JSON(200, serializer.Err(serializer.CodePolicyNotAllowed, "当前存储策略无法使用", nil))
   328  	//	return
   329  	//}
   330  	//
   331  	//// 给文件系统分配钩子
   332  	//fs.Use("BeforeUpload", filesystem.HookValidateFile)
   333  	//fs.Use("BeforeUpload", filesystem.HookValidateCapacity)
   334  	//fs.Use("AfterUploadCanceled", filesystem.HookDeleteTempFile)
   335  	//fs.Use("AfterUploadCanceled", filesystem.HookGiveBackCapacity)
   336  	//fs.Use("AfterUpload", filesystem.GenericAfterUpload)
   337  	//fs.Use("AfterValidateFailed", filesystem.HookDeleteTempFile)
   338  	//fs.Use("AfterValidateFailed", filesystem.HookGiveBackCapacity)
   339  	//fs.Use("AfterUploadFailed", filesystem.HookGiveBackCapacity)
   340  	//
   341  	//// 执行上传
   342  	//ctx = context.WithValue(ctx, fsctx.ValidateCapacityOnceCtx, &sync.Once{})
   343  	//uploadCtx := context.WithValue(ctx, fsctx.GinCtx, c)
   344  	//err = fs.Upload(uploadCtx, &fileData)
   345  	//if err != nil {
   346  	//	c.JSON(200, serializer.Err(serializer.CodeUploadFailed, err.Error(), err))
   347  	//	return
   348  	//}
   349  	//
   350  	//c.JSON(200, serializer.Response{
   351  	//	Code: 0,
   352  	//})
   353  }
   354  
   355  // DeleteUploadSession 删除上传会话
   356  func DeleteUploadSession(c *gin.Context) {
   357  	// 创建上下文
   358  	ctx, cancel := context.WithCancel(context.Background())
   359  	defer cancel()
   360  
   361  	var service explorer.UploadSessionService
   362  	if err := c.ShouldBindUri(&service); err == nil {
   363  		res := service.Delete(ctx, c)
   364  		c.JSON(200, res)
   365  	} else {
   366  		c.JSON(200, ErrorResponse(err))
   367  	}
   368  }
   369  
   370  // DeleteAllUploadSession 删除全部上传会话
   371  func DeleteAllUploadSession(c *gin.Context) {
   372  	// 创建上下文
   373  	ctx, cancel := context.WithCancel(context.Background())
   374  	defer cancel()
   375  
   376  	res := explorer.DeleteAllUploadSession(ctx, c)
   377  	c.JSON(200, res)
   378  }
   379  
   380  // GetUploadSession 创建上传会话
   381  func GetUploadSession(c *gin.Context) {
   382  	// 创建上下文
   383  	ctx, cancel := context.WithCancel(context.Background())
   384  	defer cancel()
   385  
   386  	var service explorer.CreateUploadSessionService
   387  	if err := c.ShouldBindJSON(&service); err == nil {
   388  		res := service.Create(ctx, c)
   389  		c.JSON(200, res)
   390  	} else {
   391  		c.JSON(200, ErrorResponse(err))
   392  	}
   393  }
   394  
   395  // SearchFile 搜索文件
   396  func SearchFile(c *gin.Context) {
   397  	var service explorer.ItemSearchService
   398  	if err := c.ShouldBindUri(&service); err != nil {
   399  		c.JSON(200, ErrorResponse(err))
   400  		return
   401  	}
   402  
   403  	if err := c.ShouldBindQuery(&service); err != nil {
   404  		c.JSON(200, ErrorResponse(err))
   405  		return
   406  	}
   407  
   408  	res := service.Search(c)
   409  	c.JSON(200, res)
   410  }
   411  
   412  // CreateFile 创建空白文件
   413  func CreateFile(c *gin.Context) {
   414  	var service explorer.SingleFileService
   415  	if err := c.ShouldBindJSON(&service); err == nil {
   416  		res := service.Create(c)
   417  		c.JSON(200, res)
   418  	} else {
   419  		c.JSON(200, ErrorResponse(err))
   420  	}
   421  }