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

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

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