diff --git a/drivers/google/driver.go b/drivers/google/driver.go index 92f7c864..1c5d6e5d 100644 --- a/drivers/google/driver.go +++ b/drivers/google/driver.go @@ -8,6 +8,7 @@ import ( "github.com/Xhofe/alist/utils" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" + "io/ioutil" "path/filepath" ) @@ -168,23 +169,105 @@ func (driver GoogleDrive) Preview(path string, account *model.Account) (interfac } func (driver GoogleDrive) MakeDir(path string, account *model.Account) error { - return base.ErrNotImplement + parentFile, err := driver.File(utils.Dir(path), account) + if err != nil { + return err + } + data := base.Json{ + "name": utils.Base(path), + "parents": []string{parentFile.Id}, + "mimeType": "application/vnd.google-apps.folder", + } + _, err = driver.Request("https://www.googleapis.com/drive/v3/files", base.Post, nil, nil, nil, &data, nil, account) + if err == nil { + _ = base.DeleteCache(utils.Dir(path), account) + } + return err } func (driver GoogleDrive) Move(src string, dst string, account *model.Account) error { - return base.ErrNotImplement + srcFile, err := driver.File(src, account) + url := "https://www.googleapis.com/drive/v3/files/" + srcFile.Id + if err != nil { + return err + } + if utils.Dir(src) == utils.Dir(dst) { + // rename + data := base.Json{ + "name": utils.Base(dst), + } + _, err = driver.Request(url, base.Patch, nil, nil, nil, &data, nil, account) + } else { + dstParentFile, err := driver.File(utils.Dir(dst), account) + if err != nil { + return err + } + query := map[string]string{ + "addParents": dstParentFile.Id, + "removeParents": "root", + } + _, err = driver.Request(url, base.Patch, nil, query, nil, nil, nil, account) + } + if err == nil { + _ = base.DeleteCache(utils.Dir(src), account) + if utils.Dir(src) != utils.Dir(dst) { + _ = base.DeleteCache(utils.Dir(dst), account) + } + } + return err } func (driver GoogleDrive) Copy(src string, dst string, account *model.Account) error { - return base.ErrNotImplement + return base.ErrNotSupport } func (driver GoogleDrive) Delete(path string, account *model.Account) error { - return base.ErrNotImplement + file, err := driver.File(path, account) + url := "https://www.googleapis.com/drive/v3/files/" + file.Id + if err != nil { + return err + } + _, err = driver.Request(url, base.Delete, nil, nil, nil, nil, nil, account) + if err == nil { + _ = base.DeleteCache(utils.Dir(path), account) + } + return err } func (driver GoogleDrive) Upload(file *model.FileStream, account *model.Account) error { - return base.ErrNotImplement + parentFile, err := driver.File(file.ParentPath, account) + if err != nil { + return err + } + data := base.Json{ + "name": file.Name, + "parents": []string{parentFile.Id}, + } + var e Error + res, err := base.NoRedirectClient.R().SetHeader("Authorization", "Bearer "+account.AccessToken). + SetError(&e).SetBody(data). + Post("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&supportsAllDrives=true") + if err != nil { + return err + } + if e.Error.Code != 0 { + if e.Error.Code == 401 { + err = driver.RefreshToken(account) + if err != nil { + _ = model.SaveAccount(account) + return err + } + return driver.Upload(file, account) + } + return fmt.Errorf("%s: %v", e.Error.Message, e.Error.Errors) + } + putUrl := res.Header().Get("location") + byteData, _ := ioutil.ReadAll(file) + _, err = driver.Request(putUrl, base.Put, nil, nil, nil, byteData, nil, account) + if err == nil { + _ = base.DeleteCache(file.ParentPath, account) + } + return err } var _ base.Driver = (*GoogleDrive)(nil) diff --git a/drivers/google/googledrive.go b/drivers/google/googledrive.go index 446b0df5..8fcadc43 100644 --- a/drivers/google/googledrive.go +++ b/drivers/google/googledrive.go @@ -103,13 +103,13 @@ func (driver GoogleDrive) GetFiles(id string, account *model.Account) ([]File, e } var resp Files query := map[string]string{ - "orderBy": "folder,name,modifiedTime desc", - "fields": "files(id,name,mimeType,size,modifiedTime),nextPageToken", - "pageSize": "1000", - "q": fmt.Sprintf("'%s' in parents and trashed = false", id), - "includeItemsFromAllDrives": "true", - "supportsAllDrives": "true", - "pageToken": pageToken, + "orderBy": "folder,name,modifiedTime desc", + "fields": "files(id,name,mimeType,size,modifiedTime),nextPageToken", + "pageSize": "1000", + "q": fmt.Sprintf("'%s' in parents and trashed = false", id), + //"includeItemsFromAllDrives": "true", + //"supportsAllDrives": "true", + "pageToken": pageToken, } _, err := driver.Request("https://www.googleapis.com/drive/v3/files", base.Get, nil, query, nil, nil, &resp, account) @@ -122,13 +122,15 @@ func (driver GoogleDrive) GetFiles(id string, account *model.Account) ([]File, e return res, nil } -func (driver GoogleDrive) Request(url string, method int, headers, query, form map[string]string, data *base.Json, resp interface{}, account *model.Account) ([]byte, error) { +func (driver GoogleDrive) Request(url string, method int, headers, query, form map[string]string, data interface{}, resp interface{}, account *model.Account) ([]byte, error) { rawUrl := url if account.APIProxyUrl != "" { url = fmt.Sprintf("%s/%s", account.APIProxyUrl, url) } req := base.RestyClient.R() req.SetHeader("Authorization", "Bearer "+account.AccessToken) + req.SetQueryParam("includeItemsFromAllDrives", "true") + req.SetQueryParam("supportsAllDrives", "true") if headers != nil { req.SetHeaders(headers) } @@ -153,6 +155,12 @@ func (driver GoogleDrive) Request(url string, method int, headers, query, form m res, err = req.Get(url) case base.Post: res, err = req.Post(url) + case base.Delete: + res, err = req.Delete(url) + case base.Patch: + res, err = req.Patch(url) + case base.Put: + res, err = req.Put(url) default: return nil, base.ErrNotSupport } diff --git a/server/webdav/file.go b/server/webdav/file.go index c0a9cfe8..fdb64d03 100644 --- a/server/webdav/file.go +++ b/server/webdav/file.go @@ -165,6 +165,7 @@ func (fs *FileSystem) CreateDirectory(ctx context.Context, rawPath string) error if err != nil { return err } + log.Debugf("mkdir: %s", path_) return driver.MakeDir(path_, account) }