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.

object.go 7.3 kB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. package cdsapi
  2. import (
  3. "fmt"
  4. "io"
  5. "mime"
  6. "net/url"
  7. "strings"
  8. "time"
  9. "gitlink.org.cn/cloudream/common/consts/errorcode"
  10. "gitlink.org.cn/cloudream/common/pkgs/iterator"
  11. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  12. "gitlink.org.cn/cloudream/common/utils/http2"
  13. "gitlink.org.cn/cloudream/common/utils/serder"
  14. )
  15. type ObjectService struct {
  16. *Client
  17. }
  18. func (c *Client) Object() *ObjectService {
  19. return &ObjectService{
  20. Client: c,
  21. }
  22. }
  23. const ObjectUploadPath = "/object/upload"
  24. type ObjectUpload struct {
  25. ObjectUploadInfo
  26. Files UploadObjectIterator `json:"-"`
  27. }
  28. type ObjectUploadInfo struct {
  29. UserID cdssdk.UserID `json:"userID" binding:"required"`
  30. PackageID cdssdk.PackageID `json:"packageID" binding:"required"`
  31. Affinity cdssdk.StorageID `json:"affinity"`
  32. LoadTo []cdssdk.StorageID `json:"loadTo"`
  33. }
  34. type UploadingObject struct {
  35. Path string
  36. File io.ReadCloser
  37. }
  38. type UploadObjectIterator = iterator.Iterator[*UploadingObject]
  39. type ObjectUploadResp struct {
  40. Uploadeds []cdssdk.Object `json:"uploadeds"`
  41. }
  42. func (c *ObjectService) Upload(req ObjectUpload) (*ObjectUploadResp, error) {
  43. url, err := url.JoinPath(c.baseURL, ObjectUploadPath)
  44. if err != nil {
  45. return nil, err
  46. }
  47. infoJSON, err := serder.ObjectToJSON(req)
  48. if err != nil {
  49. return nil, fmt.Errorf("upload info to json: %w", err)
  50. }
  51. resp, err := http2.PostMultiPart(url, http2.MultiPartRequestParam{
  52. Form: map[string]string{"info": string(infoJSON)},
  53. Files: iterator.Map(req.Files, func(src *UploadingObject) (*http2.IterMultiPartFile, error) {
  54. return &http2.IterMultiPartFile{
  55. FieldName: "files",
  56. FileName: src.Path,
  57. File: src.File,
  58. }, nil
  59. }),
  60. })
  61. if err != nil {
  62. return nil, err
  63. }
  64. contType := resp.Header.Get("Content-Type")
  65. if strings.Contains(contType, http2.ContentTypeJSON) {
  66. var err error
  67. var codeResp response[ObjectUploadResp]
  68. if codeResp, err = serder.JSONToObjectStreamEx[response[ObjectUploadResp]](resp.Body); err != nil {
  69. return nil, fmt.Errorf("parsing response: %w", err)
  70. }
  71. if codeResp.Code == errorcode.OK {
  72. return &codeResp.Data, nil
  73. }
  74. return nil, codeResp.ToError()
  75. }
  76. return nil, fmt.Errorf("unknow response content type: %s", contType)
  77. }
  78. const ObjectDownloadPath = "/object/download"
  79. type ObjectDownload struct {
  80. UserID cdssdk.UserID `form:"userID" json:"userID" binding:"required"`
  81. ObjectID cdssdk.ObjectID `form:"objectID" json:"objectID" binding:"required"`
  82. Offset int64 `form:"offset" json:"offset,omitempty"`
  83. Length *int64 `form:"length" json:"length,omitempty"`
  84. PartSize int64 `form:"partSize" json:"partSize,omitempty"`
  85. }
  86. type DownloadingObject struct {
  87. Path string
  88. File io.ReadCloser
  89. }
  90. func (c *ObjectService) Download(req ObjectDownload) (*DownloadingObject, error) {
  91. url, err := url.JoinPath(c.baseURL, ObjectDownloadPath)
  92. if err != nil {
  93. return nil, err
  94. }
  95. resp, err := http2.GetJSON(url, http2.RequestParam{
  96. Query: req,
  97. })
  98. if err != nil {
  99. return nil, err
  100. }
  101. contType := resp.Header.Get("Content-Type")
  102. if strings.Contains(contType, http2.ContentTypeJSON) {
  103. var codeResp response[any]
  104. if err := serder.JSONToObjectStream(resp.Body, &codeResp); err != nil {
  105. return nil, fmt.Errorf("parsing response: %w", err)
  106. }
  107. return nil, codeResp.ToError()
  108. }
  109. _, params, err := mime.ParseMediaType(resp.Header.Get("Content-Disposition"))
  110. if err != nil {
  111. return nil, fmt.Errorf("parsing content disposition: %w", err)
  112. }
  113. return &DownloadingObject{
  114. Path: params["filename"],
  115. File: resp.Body,
  116. }, nil
  117. }
  118. const ObjectUpdateInfoPath = "/object/updateInfo"
  119. type UpdatingObject struct {
  120. ObjectID cdssdk.ObjectID `json:"objectID" binding:"required"`
  121. UpdateTime time.Time `json:"updateTime" binding:"required"`
  122. }
  123. func (u *UpdatingObject) ApplyTo(obj *cdssdk.Object) {
  124. obj.UpdateTime = u.UpdateTime
  125. }
  126. type ObjectUpdateInfo struct {
  127. UserID cdssdk.UserID `json:"userID" binding:"required"`
  128. Updatings []UpdatingObject `json:"updatings" binding:"required"`
  129. }
  130. type ObjectUpdateInfoResp struct {
  131. Successes []cdssdk.ObjectID `json:"successes"`
  132. }
  133. func (c *ObjectService) UpdateInfo(req ObjectUpdateInfo) (*ObjectUpdateInfoResp, error) {
  134. url, err := url.JoinPath(c.baseURL, ObjectUpdateInfoPath)
  135. if err != nil {
  136. return nil, err
  137. }
  138. resp, err := http2.PostJSON(url, http2.RequestParam{
  139. Body: req,
  140. })
  141. if err != nil {
  142. return nil, err
  143. }
  144. jsonResp, err := ParseJSONResponse[response[ObjectUpdateInfoResp]](resp)
  145. if err != nil {
  146. return nil, err
  147. }
  148. if jsonResp.Code == errorcode.OK {
  149. return &jsonResp.Data, nil
  150. }
  151. return nil, jsonResp.ToError()
  152. }
  153. const ObjectMovePath = "/object/move"
  154. type MovingObject struct {
  155. ObjectID cdssdk.ObjectID `json:"objectID" binding:"required"`
  156. PackageID cdssdk.PackageID `json:"packageID" binding:"required"`
  157. Path string `json:"path" binding:"required"`
  158. }
  159. func (m *MovingObject) ApplyTo(obj *cdssdk.Object) {
  160. obj.PackageID = m.PackageID
  161. obj.Path = m.Path
  162. }
  163. type ObjectMove struct {
  164. UserID cdssdk.UserID `json:"userID" binding:"required"`
  165. Movings []MovingObject `json:"movings" binding:"required"`
  166. }
  167. type ObjectMoveResp struct {
  168. Successes []cdssdk.ObjectID `json:"successes"`
  169. }
  170. func (c *ObjectService) Move(req ObjectMove) (*ObjectMoveResp, error) {
  171. url, err := url.JoinPath(c.baseURL, ObjectMovePath)
  172. if err != nil {
  173. return nil, err
  174. }
  175. resp, err := http2.PostJSON(url, http2.RequestParam{
  176. Body: req,
  177. })
  178. if err != nil {
  179. return nil, err
  180. }
  181. jsonResp, err := ParseJSONResponse[response[ObjectMoveResp]](resp)
  182. if err != nil {
  183. return nil, err
  184. }
  185. if jsonResp.Code == errorcode.OK {
  186. return &jsonResp.Data, nil
  187. }
  188. return nil, jsonResp.ToError()
  189. }
  190. const ObjectDeletePath = "/object/delete"
  191. type ObjectDelete struct {
  192. UserID cdssdk.UserID `json:"userID" binding:"required"`
  193. ObjectIDs []cdssdk.ObjectID `json:"objectIDs" binding:"required"`
  194. }
  195. type ObjectDeleteResp struct{}
  196. func (c *ObjectService) Delete(req ObjectDelete) error {
  197. url, err := url.JoinPath(c.baseURL, ObjectDeletePath)
  198. if err != nil {
  199. return err
  200. }
  201. resp, err := http2.PostJSON(url, http2.RequestParam{
  202. Body: req,
  203. })
  204. if err != nil {
  205. return err
  206. }
  207. jsonResp, err := ParseJSONResponse[response[ObjectDeleteResp]](resp)
  208. if err != nil {
  209. return err
  210. }
  211. if jsonResp.Code == errorcode.OK {
  212. return nil
  213. }
  214. return jsonResp.ToError()
  215. }
  216. const ObjectGetPackageObjectsPath = "/object/getPackageObjects"
  217. type ObjectGetPackageObjects struct {
  218. UserID cdssdk.UserID `form:"userID" json:"userID" binding:"required"`
  219. PackageID cdssdk.PackageID `form:"packageID" json:"packageID" binding:"required"`
  220. }
  221. type ObjectGetPackageObjectsResp struct {
  222. Objects []cdssdk.Object `json:"objects"`
  223. }
  224. func (c *ObjectService) GetPackageObjects(req ObjectGetPackageObjects) (*ObjectGetPackageObjectsResp, error) {
  225. url, err := url.JoinPath(c.baseURL, ObjectGetPackageObjectsPath)
  226. if err != nil {
  227. return nil, err
  228. }
  229. resp, err := http2.GetForm(url, http2.RequestParam{
  230. Query: req,
  231. })
  232. if err != nil {
  233. return nil, err
  234. }
  235. jsonResp, err := ParseJSONResponse[response[ObjectGetPackageObjectsResp]](resp)
  236. if err != nil {
  237. return nil, err
  238. }
  239. if jsonResp.Code == errorcode.OK {
  240. return &jsonResp.Data, nil
  241. }
  242. return nil, jsonResp.ToError()
  243. }