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 11 kB

1 year ago
11 months ago
1 year ago
11 months ago
11 months ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  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 ObjectListPath = "/object/list"
  24. type ObjectList struct {
  25. UserID cdssdk.UserID `form:"userID" binding:"required"`
  26. PackageID cdssdk.PackageID `form:"packageID" binding:"required"`
  27. Path string `form:"path" binding:"required"`
  28. IsPrefix bool `form:"isPrefix"`
  29. }
  30. type ObjectListResp struct {
  31. Objects []cdssdk.Object `json:"objects"`
  32. }
  33. func (c *ObjectService) List(req ObjectList) (*ObjectListResp, error) {
  34. url, err := url.JoinPath(c.baseURL, ObjectListPath)
  35. if err != nil {
  36. return nil, err
  37. }
  38. resp, err := http2.GetForm(url, http2.RequestParam{
  39. Query: req,
  40. })
  41. if err != nil {
  42. return nil, err
  43. }
  44. jsonResp, err := ParseJSONResponse[response[ObjectListResp]](resp)
  45. if err != nil {
  46. return nil, err
  47. }
  48. if jsonResp.Code == errorcode.OK {
  49. return &jsonResp.Data, nil
  50. }
  51. return nil, jsonResp.ToError()
  52. }
  53. const ObjectUploadPath = "/object/upload"
  54. type ObjectUpload struct {
  55. ObjectUploadInfo
  56. Files UploadObjectIterator `json:"-"`
  57. }
  58. type ObjectUploadInfo struct {
  59. UserID cdssdk.UserID `json:"userID" binding:"required"`
  60. PackageID cdssdk.PackageID `json:"packageID" binding:"required"`
  61. Affinity cdssdk.StorageID `json:"affinity"`
  62. LoadTo []cdssdk.StorageID `json:"loadTo"`
  63. }
  64. type UploadingObject struct {
  65. Path string
  66. File io.ReadCloser
  67. }
  68. type UploadObjectIterator = iterator.Iterator[*UploadingObject]
  69. type ObjectUploadResp struct {
  70. Uploadeds []cdssdk.Object `json:"uploadeds"`
  71. }
  72. func (c *ObjectService) Upload(req ObjectUpload) (*ObjectUploadResp, error) {
  73. url, err := url.JoinPath(c.baseURL, ObjectUploadPath)
  74. if err != nil {
  75. return nil, err
  76. }
  77. infoJSON, err := serder.ObjectToJSON(req)
  78. if err != nil {
  79. return nil, fmt.Errorf("upload info to json: %w", err)
  80. }
  81. resp, err := http2.PostMultiPart(url, http2.MultiPartRequestParam{
  82. Form: map[string]string{"info": string(infoJSON)},
  83. Files: iterator.Map(req.Files, func(src *UploadingObject) (*http2.IterMultiPartFile, error) {
  84. return &http2.IterMultiPartFile{
  85. FieldName: "files",
  86. FileName: src.Path,
  87. File: src.File,
  88. }, nil
  89. }),
  90. })
  91. if err != nil {
  92. return nil, err
  93. }
  94. contType := resp.Header.Get("Content-Type")
  95. if strings.Contains(contType, http2.ContentTypeJSON) {
  96. var err error
  97. var codeResp response[ObjectUploadResp]
  98. if codeResp, err = serder.JSONToObjectStreamEx[response[ObjectUploadResp]](resp.Body); err != nil {
  99. return nil, fmt.Errorf("parsing response: %w", err)
  100. }
  101. if codeResp.Code == errorcode.OK {
  102. return &codeResp.Data, nil
  103. }
  104. return nil, codeResp.ToError()
  105. }
  106. return nil, fmt.Errorf("unknow response content type: %s", contType)
  107. }
  108. const ObjectDownloadPath = "/object/download"
  109. type ObjectDownload struct {
  110. UserID cdssdk.UserID `form:"userID" json:"userID" binding:"required"`
  111. ObjectID cdssdk.ObjectID `form:"objectID" json:"objectID" binding:"required"`
  112. Offset int64 `form:"offset" json:"offset,omitempty"`
  113. Length *int64 `form:"length" json:"length,omitempty"`
  114. }
  115. type DownloadingObject struct {
  116. Path string
  117. File io.ReadCloser
  118. }
  119. func (c *ObjectService) Download(req ObjectDownload) (*DownloadingObject, error) {
  120. url, err := url.JoinPath(c.baseURL, ObjectDownloadPath)
  121. if err != nil {
  122. return nil, err
  123. }
  124. resp, err := http2.GetJSON(url, http2.RequestParam{
  125. Query: req,
  126. })
  127. if err != nil {
  128. return nil, err
  129. }
  130. contType := resp.Header.Get("Content-Type")
  131. if strings.Contains(contType, http2.ContentTypeJSON) {
  132. var codeResp response[any]
  133. if err := serder.JSONToObjectStream(resp.Body, &codeResp); err != nil {
  134. return nil, fmt.Errorf("parsing response: %w", err)
  135. }
  136. return nil, codeResp.ToError()
  137. }
  138. _, params, err := mime.ParseMediaType(resp.Header.Get("Content-Disposition"))
  139. if err != nil {
  140. return nil, fmt.Errorf("parsing content disposition: %w", err)
  141. }
  142. return &DownloadingObject{
  143. Path: params["filename"],
  144. File: resp.Body,
  145. }, nil
  146. }
  147. const ObjectDownloadByPathPath = "/object/downloadByPath"
  148. type ObjectDownloadByPath struct {
  149. UserID cdssdk.UserID `form:"userID" json:"userID" binding:"required"`
  150. PackageID cdssdk.PackageID `form:"packageID" json:"packageID" binding:"required"`
  151. Path string `form:"path" json:"path" binding:"required"`
  152. Offset int64 `form:"offset" json:"offset,omitempty"`
  153. Length *int64 `form:"length" json:"length,omitempty"`
  154. }
  155. func (c *ObjectService) DownloadByPath(req ObjectDownloadByPath) (*DownloadingObject, error) {
  156. url, err := url.JoinPath(c.baseURL, ObjectDownloadByPathPath)
  157. if err != nil {
  158. return nil, err
  159. }
  160. resp, err := http2.GetJSON(url, http2.RequestParam{
  161. Query: req,
  162. })
  163. if err != nil {
  164. return nil, err
  165. }
  166. contType := resp.Header.Get("Content-Type")
  167. if strings.Contains(contType, http2.ContentTypeJSON) {
  168. var codeResp response[any]
  169. if err := serder.JSONToObjectStream(resp.Body, &codeResp); err != nil {
  170. return nil, fmt.Errorf("parsing response: %w", err)
  171. }
  172. return nil, codeResp.ToError()
  173. }
  174. _, params, err := mime.ParseMediaType(resp.Header.Get("Content-Disposition"))
  175. if err != nil {
  176. return nil, fmt.Errorf("parsing content disposition: %w", err)
  177. }
  178. return &DownloadingObject{
  179. Path: params["filename"],
  180. File: resp.Body,
  181. }, nil
  182. }
  183. const ObjectUpdateInfoPath = "/object/updateInfo"
  184. type UpdatingObject struct {
  185. ObjectID cdssdk.ObjectID `json:"objectID" binding:"required"`
  186. UpdateTime time.Time `json:"updateTime" binding:"required"`
  187. }
  188. func (u *UpdatingObject) ApplyTo(obj *cdssdk.Object) {
  189. obj.UpdateTime = u.UpdateTime
  190. }
  191. type ObjectUpdateInfo struct {
  192. UserID cdssdk.UserID `json:"userID" binding:"required"`
  193. Updatings []UpdatingObject `json:"updatings" binding:"required"`
  194. }
  195. type ObjectUpdateInfoResp struct {
  196. Successes []cdssdk.ObjectID `json:"successes"`
  197. }
  198. func (c *ObjectService) UpdateInfo(req ObjectUpdateInfo) (*ObjectUpdateInfoResp, error) {
  199. url, err := url.JoinPath(c.baseURL, ObjectUpdateInfoPath)
  200. if err != nil {
  201. return nil, err
  202. }
  203. resp, err := http2.PostJSON(url, http2.RequestParam{
  204. Body: req,
  205. })
  206. if err != nil {
  207. return nil, err
  208. }
  209. jsonResp, err := ParseJSONResponse[response[ObjectUpdateInfoResp]](resp)
  210. if err != nil {
  211. return nil, err
  212. }
  213. if jsonResp.Code == errorcode.OK {
  214. return &jsonResp.Data, nil
  215. }
  216. return nil, jsonResp.ToError()
  217. }
  218. const ObjectUpdateInfoByPathPath = "/object/updateInfoByPath"
  219. type ObjectUpdateInfoByPath struct {
  220. UserID cdssdk.UserID `json:"userID" binding:"required"`
  221. PackageID cdssdk.PackageID `json:"packageID" binding:"required"`
  222. Path string `json:"path" binding:"required"`
  223. UpdateTime time.Time `json:"updateTime" binding:"required"`
  224. }
  225. type ObjectUpdateInfoByPathResp struct{}
  226. func (c *ObjectService) UpdateInfoByPath(req ObjectUpdateInfoByPath) (*ObjectUpdateInfoByPathResp, error) {
  227. url, err := url.JoinPath(c.baseURL, ObjectUpdateInfoByPathPath)
  228. if err != nil {
  229. return nil, err
  230. }
  231. resp, err := http2.PostJSON(url, http2.RequestParam{
  232. Body: req,
  233. })
  234. if err != nil {
  235. return nil, err
  236. }
  237. jsonResp, err := ParseJSONResponse[response[ObjectUpdateInfoByPathResp]](resp)
  238. if err != nil {
  239. return nil, err
  240. }
  241. if jsonResp.Code == errorcode.OK {
  242. return &jsonResp.Data, nil
  243. }
  244. return nil, jsonResp.ToError()
  245. }
  246. const ObjectMovePath = "/object/move"
  247. type MovingObject struct {
  248. ObjectID cdssdk.ObjectID `json:"objectID" binding:"required"`
  249. PackageID cdssdk.PackageID `json:"packageID" binding:"required"`
  250. Path string `json:"path" binding:"required"`
  251. }
  252. func (m *MovingObject) ApplyTo(obj *cdssdk.Object) {
  253. obj.PackageID = m.PackageID
  254. obj.Path = m.Path
  255. }
  256. type ObjectMove struct {
  257. UserID cdssdk.UserID `json:"userID" binding:"required"`
  258. Movings []MovingObject `json:"movings" binding:"required"`
  259. }
  260. type ObjectMoveResp struct {
  261. Successes []cdssdk.ObjectID `json:"successes"`
  262. }
  263. func (c *ObjectService) Move(req ObjectMove) (*ObjectMoveResp, error) {
  264. url, err := url.JoinPath(c.baseURL, ObjectMovePath)
  265. if err != nil {
  266. return nil, err
  267. }
  268. resp, err := http2.PostJSON(url, http2.RequestParam{
  269. Body: req,
  270. })
  271. if err != nil {
  272. return nil, err
  273. }
  274. jsonResp, err := ParseJSONResponse[response[ObjectMoveResp]](resp)
  275. if err != nil {
  276. return nil, err
  277. }
  278. if jsonResp.Code == errorcode.OK {
  279. return &jsonResp.Data, nil
  280. }
  281. return nil, jsonResp.ToError()
  282. }
  283. const ObjectDeletePath = "/object/delete"
  284. type ObjectDelete struct {
  285. UserID cdssdk.UserID `json:"userID" binding:"required"`
  286. ObjectIDs []cdssdk.ObjectID `json:"objectIDs" binding:"required"`
  287. }
  288. type ObjectDeleteResp struct{}
  289. func (c *ObjectService) Delete(req ObjectDelete) error {
  290. url, err := url.JoinPath(c.baseURL, ObjectDeletePath)
  291. if err != nil {
  292. return err
  293. }
  294. resp, err := http2.PostJSON(url, http2.RequestParam{
  295. Body: req,
  296. })
  297. if err != nil {
  298. return err
  299. }
  300. jsonResp, err := ParseJSONResponse[response[ObjectDeleteResp]](resp)
  301. if err != nil {
  302. return err
  303. }
  304. if jsonResp.Code == errorcode.OK {
  305. return nil
  306. }
  307. return jsonResp.ToError()
  308. }
  309. const ObjectDeleteByPathPath = "/object/deleteByPath"
  310. type ObjectDeleteByPath struct {
  311. UserID cdssdk.UserID `json:"userID" binding:"required"`
  312. PackageID cdssdk.PackageID `json:"packageID" binding:"required"`
  313. Path string `json:"path" binding:"required"`
  314. }
  315. type ObjectDeleteByPathResp struct{}
  316. func (c *ObjectService) DeleteByPath(req ObjectDeleteByPath) error {
  317. url, err := url.JoinPath(c.baseURL, ObjectDeleteByPathPath)
  318. if err != nil {
  319. return err
  320. }
  321. resp, err := http2.PostJSON(url, http2.RequestParam{
  322. Body: req,
  323. })
  324. if err != nil {
  325. return err
  326. }
  327. jsonResp, err := ParseJSONResponse[response[ObjectDeleteByPathResp]](resp)
  328. if err != nil {
  329. return err
  330. }
  331. if jsonResp.Code == errorcode.OK {
  332. return nil
  333. }
  334. return jsonResp.ToError()
  335. }
  336. const ObjectGetPackageObjectsPath = "/object/getPackageObjects"
  337. type ObjectGetPackageObjects struct {
  338. UserID cdssdk.UserID `form:"userID" json:"userID" binding:"required"`
  339. PackageID cdssdk.PackageID `form:"packageID" json:"packageID" binding:"required"`
  340. }
  341. type ObjectGetPackageObjectsResp struct {
  342. Objects []cdssdk.Object `json:"objects"`
  343. }
  344. func (c *ObjectService) GetPackageObjects(req ObjectGetPackageObjects) (*ObjectGetPackageObjectsResp, error) {
  345. url, err := url.JoinPath(c.baseURL, ObjectGetPackageObjectsPath)
  346. if err != nil {
  347. return nil, err
  348. }
  349. resp, err := http2.GetForm(url, http2.RequestParam{
  350. Query: req,
  351. })
  352. if err != nil {
  353. return nil, err
  354. }
  355. jsonResp, err := ParseJSONResponse[response[ObjectGetPackageObjectsResp]](resp)
  356. if err != nil {
  357. return nil, err
  358. }
  359. if jsonResp.Code == errorcode.OK {
  360. return &jsonResp.Data, nil
  361. }
  362. return nil, jsonResp.ToError()
  363. }