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