You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

package.go 7.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package http
  2. import (
  3. "fmt"
  4. "mime/multipart"
  5. "net/http"
  6. "net/url"
  7. "github.com/gin-gonic/gin"
  8. "gitlink.org.cn/cloudream/common/consts/errorcode"
  9. "gitlink.org.cn/cloudream/common/pkgs/logger"
  10. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  11. "gitlink.org.cn/cloudream/common/sdks/storage/cdsapi"
  12. )
  13. // PackageService 包服务,负责处理包相关的HTTP请求。
  14. type PackageService struct {
  15. *Server
  16. }
  17. // Package 返回PackageService的实例。
  18. func (s *Server) Package() *PackageService {
  19. return &PackageService{
  20. Server: s,
  21. }
  22. }
  23. func (s *PackageService) Get(ctx *gin.Context) {
  24. log := logger.WithField("HTTP", "Package.Get")
  25. var req cdsapi.PackageGetReq
  26. if err := ctx.ShouldBindQuery(&req); err != nil {
  27. log.Warnf("binding body: %s", err.Error())
  28. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  29. return
  30. }
  31. pkg, err := s.svc.PackageSvc().Get(req.UserID, req.PackageID)
  32. if err != nil {
  33. log.Warnf("getting package: %s", err.Error())
  34. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get package failed"))
  35. return
  36. }
  37. ctx.JSON(http.StatusOK, OK(cdsapi.PackageGetResp{Package: *pkg}))
  38. }
  39. func (s *PackageService) GetByName(ctx *gin.Context) {
  40. log := logger.WithField("HTTP", "Package.GetByName")
  41. var req cdsapi.PackageGetByName
  42. if err := ctx.ShouldBindQuery(&req); err != nil {
  43. log.Warnf("binding query: %s", err.Error())
  44. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  45. return
  46. }
  47. pkg, err := s.svc.PackageSvc().GetByName(req.UserID, req.BucketName, req.PackageName)
  48. if err != nil {
  49. log.Warnf("getting package by name: %s", err.Error())
  50. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get package by name failed"))
  51. return
  52. }
  53. ctx.JSON(http.StatusOK, OK(cdsapi.PackageGetByNameResp{Package: *pkg}))
  54. }
  55. // Create 处理创建新包的HTTP请求。
  56. func (s *PackageService) Create(ctx *gin.Context) {
  57. log := logger.WithField("HTTP", "Package.Create")
  58. var req cdsapi.PackageCreate
  59. if err := ctx.ShouldBindJSON(&req); err != nil {
  60. log.Warnf("binding body: %s", err.Error())
  61. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  62. return
  63. }
  64. pkg, err := s.svc.PackageSvc().Create(req.UserID, req.BucketID, req.Name)
  65. if err != nil {
  66. log.Warnf("creating package: %s", err.Error())
  67. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "create package failed"))
  68. return
  69. }
  70. ctx.JSON(http.StatusOK, OK(cdsapi.PackageCreateResp{
  71. Package: pkg,
  72. }))
  73. }
  74. type PackageCreateLoad struct {
  75. Info cdsapi.PackageCreateLoad `form:"info" binding:"required"`
  76. Files []*multipart.FileHeader `form:"files"`
  77. }
  78. func (s *PackageService) CreateLoad(ctx *gin.Context) {
  79. log := logger.WithField("HTTP", "Package.CreateLoad")
  80. var req PackageCreateLoad
  81. if err := ctx.ShouldBindJSON(&req); err != nil {
  82. log.Warnf("binding body: %s", err.Error())
  83. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  84. return
  85. }
  86. up, err := s.svc.Uploader.BeginCreateLoad(req.Info.UserID, req.Info.BucketID, req.Info.Name, req.Info.LoadTo)
  87. if err != nil {
  88. log.Warnf("begin package create load: %s", err.Error())
  89. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, fmt.Sprintf("begin package create load: %v", err)))
  90. return
  91. }
  92. defer up.Abort()
  93. var pathes []string
  94. for _, file := range req.Files {
  95. f, err := file.Open()
  96. if err != nil {
  97. log.Warnf("open file: %s", err.Error())
  98. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, fmt.Sprintf("open file %v: %v", file.Filename, err)))
  99. return
  100. }
  101. path, err := url.PathUnescape(file.Filename)
  102. if err != nil {
  103. log.Warnf("unescape filename: %s", err.Error())
  104. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, fmt.Sprintf("unescape filename %v: %v", file.Filename, err)))
  105. return
  106. }
  107. err = up.Upload(path, file.Size, f)
  108. if err != nil {
  109. log.Warnf("uploading file: %s", err.Error())
  110. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, fmt.Sprintf("uploading file %v: %v", file.Filename, err)))
  111. return
  112. }
  113. pathes = append(pathes, path)
  114. }
  115. ret, err := up.Commit()
  116. if err != nil {
  117. log.Warnf("commit create load: %s", err.Error())
  118. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, fmt.Sprintf("commit create load: %v", err)))
  119. return
  120. }
  121. objs := make([]cdssdk.Object, len(pathes))
  122. for i := range pathes {
  123. objs[i] = ret.Objects[pathes[i]]
  124. }
  125. ctx.JSON(http.StatusOK, OK(cdsapi.PackageCreateLoadResp{Package: ret.Package, Objects: objs, LoadedDirs: ret.LoadedDirs}))
  126. }
  127. func (s *PackageService) Delete(ctx *gin.Context) {
  128. log := logger.WithField("HTTP", "Package.Delete")
  129. var req cdsapi.PackageDelete
  130. if err := ctx.ShouldBindJSON(&req); err != nil {
  131. log.Warnf("binding body: %s", err.Error())
  132. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  133. return
  134. }
  135. err := s.svc.PackageSvc().DeletePackage(req.UserID, req.PackageID)
  136. if err != nil {
  137. log.Warnf("deleting package: %s", err.Error())
  138. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "delete package failed"))
  139. return
  140. }
  141. ctx.JSON(http.StatusOK, OK(nil))
  142. }
  143. func (s *PackageService) ListBucketPackages(ctx *gin.Context) {
  144. log := logger.WithField("HTTP", "Package.ListBucketPackages")
  145. var req cdsapi.PackageListBucketPackages
  146. if err := ctx.ShouldBindQuery(&req); err != nil {
  147. log.Warnf("binding query: %s", err.Error())
  148. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  149. return
  150. }
  151. pkgs, err := s.svc.PackageSvc().GetBucketPackages(req.UserID, req.BucketID)
  152. if err != nil {
  153. log.Warnf("getting bucket packages: %s", err.Error())
  154. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get bucket packages failed"))
  155. return
  156. }
  157. ctx.JSON(http.StatusOK, OK(cdsapi.PackageListBucketPackagesResp{
  158. Packages: pkgs,
  159. }))
  160. }
  161. // GetCachedStorages 处理获取包的缓存节点的HTTP请求。
  162. func (s *PackageService) GetCachedStorages(ctx *gin.Context) {
  163. log := logger.WithField("HTTP", "Package.GetCachedStorages")
  164. var req cdsapi.PackageGetCachedStoragesReq
  165. if err := ctx.ShouldBindQuery(&req); err != nil {
  166. log.Warnf("binding query: %s", err.Error())
  167. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  168. return
  169. }
  170. resp, err := s.svc.PackageSvc().GetCachedStorages(req.UserID, req.PackageID)
  171. if err != nil {
  172. log.Warnf("get package cached storages failed: %s", err.Error())
  173. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get package cached storages failed"))
  174. return
  175. }
  176. ctx.JSON(http.StatusOK, OK(cdsapi.PackageGetCachedStoragesResp{PackageCachingInfo: resp}))
  177. }
  178. // GetLoadedStorages 处理获取包的加载节点的HTTP请求。
  179. func (s *PackageService) GetLoadedStorages(ctx *gin.Context) {
  180. log := logger.WithField("HTTP", "Package.GetLoadedStorages")
  181. var req cdsapi.PackageGetLoadedStoragesReq
  182. if err := ctx.ShouldBindQuery(&req); err != nil {
  183. log.Warnf("binding query: %s", err.Error())
  184. ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
  185. return
  186. }
  187. stgIDs, err := s.svc.PackageSvc().GetLoadedStorages(req.UserID, req.PackageID)
  188. if err != nil {
  189. log.Warnf("get package loaded storages failed: %s", err.Error())
  190. ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get package loaded storages failed"))
  191. return
  192. }
  193. ctx.JSON(http.StatusOK, OK(cdsapi.PackageGetLoadedStoragesResp{
  194. StorageIDs: stgIDs,
  195. }))
  196. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。