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 }