util.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package google_drive
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "net/http"
  7. "strconv"
  8. "github.com/IceWhaleTech/CasaOS-Common/utils/logger"
  9. "github.com/IceWhaleTech/CasaOS/drivers/base"
  10. "github.com/IceWhaleTech/CasaOS/model"
  11. "github.com/IceWhaleTech/CasaOS/pkg/utils"
  12. "github.com/go-resty/resty/v2"
  13. log "github.com/sirupsen/logrus"
  14. "go.uber.org/zap"
  15. )
  16. // do others that not defined in Driver interface
  17. func (d *GoogleDrive) getRefreshToken() error {
  18. url := "https://www.googleapis.com/oauth2/v4/token"
  19. var resp base.TokenResp
  20. var e TokenError
  21. res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).
  22. SetFormData(map[string]string{
  23. "client_id": d.ClientID,
  24. "client_secret": d.ClientSecret,
  25. "code": d.Code,
  26. "grant_type": "authorization_code",
  27. "redirect_uri": "http://test-get.casaos.io",
  28. }).Post(url)
  29. if err != nil {
  30. return err
  31. }
  32. logger.Info("get refresh token", zap.String("res", res.String()))
  33. if e.Error != "" {
  34. return fmt.Errorf(e.Error)
  35. }
  36. d.RefreshToken = resp.RefreshToken
  37. return nil
  38. }
  39. func (d *GoogleDrive) refreshToken() error {
  40. url := "https://www.googleapis.com/oauth2/v4/token"
  41. var resp base.TokenResp
  42. var e TokenError
  43. res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).
  44. SetFormData(map[string]string{
  45. "client_id": d.ClientID,
  46. "client_secret": d.ClientSecret,
  47. "refresh_token": d.RefreshToken,
  48. "grant_type": "refresh_token",
  49. }).Post(url)
  50. if err != nil {
  51. return err
  52. }
  53. log.Debug(res.String())
  54. if e.Error != "" {
  55. return fmt.Errorf(e.Error)
  56. }
  57. d.AccessToken = resp.AccessToken
  58. return nil
  59. }
  60. func (d *GoogleDrive) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
  61. req := base.RestyClient.R()
  62. req.SetHeader("Authorization", "Bearer "+d.AccessToken)
  63. req.SetQueryParam("includeItemsFromAllDrives", "true")
  64. req.SetQueryParam("supportsAllDrives", "true")
  65. if callback != nil {
  66. callback(req)
  67. }
  68. if resp != nil {
  69. req.SetResult(resp)
  70. }
  71. var e Error
  72. req.SetError(&e)
  73. res, err := req.Execute(method, url)
  74. if err != nil {
  75. return nil, err
  76. }
  77. if e.Error.Code != 0 {
  78. if e.Error.Code == 401 {
  79. err = d.refreshToken()
  80. if err != nil {
  81. return nil, err
  82. }
  83. return d.request(url, method, callback, resp)
  84. }
  85. return nil, fmt.Errorf("%s: %v", e.Error.Message, e.Error.Errors)
  86. }
  87. return res.Body(), nil
  88. }
  89. func (d *GoogleDrive) getFiles(id string) ([]File, error) {
  90. pageToken := "first"
  91. res := make([]File, 0)
  92. for pageToken != "" {
  93. if pageToken == "first" {
  94. pageToken = ""
  95. }
  96. var resp Files
  97. orderBy := "folder,name,modifiedTime desc"
  98. if d.OrderBy != "" {
  99. orderBy = d.OrderBy + " " + d.OrderDirection
  100. }
  101. query := map[string]string{
  102. "orderBy": orderBy,
  103. "fields": "files(id,name,mimeType,size,modifiedTime,thumbnailLink,shortcutDetails),nextPageToken",
  104. "pageSize": "1000",
  105. "q": fmt.Sprintf("'%s' in parents and trashed = false", id),
  106. //"includeItemsFromAllDrives": "true",
  107. //"supportsAllDrives": "true",
  108. "pageToken": pageToken,
  109. }
  110. _, err := d.request("https://www.googleapis.com/drive/v3/files", http.MethodGet, func(req *resty.Request) {
  111. req.SetQueryParams(query)
  112. }, &resp)
  113. if err != nil {
  114. return nil, err
  115. }
  116. pageToken = resp.NextPageToken
  117. res = append(res, resp.Files...)
  118. }
  119. return res, nil
  120. }
  121. func (d *GoogleDrive) chunkUpload(ctx context.Context, stream model.FileStreamer, url string) error {
  122. var defaultChunkSize = d.ChunkSize * 1024 * 1024
  123. var finish int64 = 0
  124. for finish < stream.GetSize() {
  125. if utils.IsCanceled(ctx) {
  126. return ctx.Err()
  127. }
  128. chunkSize := stream.GetSize() - finish
  129. if chunkSize > defaultChunkSize {
  130. chunkSize = defaultChunkSize
  131. }
  132. _, err := d.request(url, http.MethodPut, func(req *resty.Request) {
  133. req.SetHeaders(map[string]string{
  134. "Content-Length": strconv.FormatInt(chunkSize, 10),
  135. "Content-Range": fmt.Sprintf("bytes %d-%d/%d", finish, finish+chunkSize-1, stream.GetSize()),
  136. }).SetBody(io.LimitReader(stream.GetReadCloser(), chunkSize)).SetContext(ctx)
  137. }, nil)
  138. if err != nil {
  139. return err
  140. }
  141. finish += chunkSize
  142. }
  143. return nil
  144. }