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