🚧 google drive api proxy

This commit is contained in:
微凉 2021-12-20 01:00:53 +08:00
parent 44cbe0522c
commit b63e65880f
4 changed files with 92 additions and 80 deletions

View File

@ -127,7 +127,6 @@ func (driver Pan123) Request(url string, method int, headers, query map[string]s
if account.APIProxyUrl != "" && proxy { if account.APIProxyUrl != "" && proxy {
url = fmt.Sprintf("%s/%s", account.APIProxyUrl, url) url = fmt.Sprintf("%s/%s", account.APIProxyUrl, url)
} }
log.Debugf("request: %s", url)
req := base.RestyClient.R() req := base.RestyClient.R()
req.SetHeader("Authorization", "Bearer "+account.AccessToken) req.SetHeader("Authorization", "Bearer "+account.AccessToken)
if headers != nil { if headers != nil {

View File

@ -113,11 +113,13 @@ func GetDrivers() map[string][]Item {
}, },
}, res[k]...) }, res[k]...)
if v.Config().ApiProxy { if v.Config().ApiProxy {
res[k] = append(res[k], Item{ res[k] = append([]Item{
Name: "api_proxy_url", {
Label: "api_proxy_url", Name: "api_proxy_url",
Type: TypeString, Label: "api_proxy_url",
}) Type: TypeString,
},
}, res[k]...)
} }
} }
return res return res

View File

@ -17,6 +17,7 @@ func (driver GoogleDrive) Config() base.DriverConfig {
return base.DriverConfig{ return base.DriverConfig{
Name: "GoogleDrive", Name: "GoogleDrive",
OnlyProxy: true, OnlyProxy: true,
ApiProxy: true,
} }
} }
@ -92,10 +93,10 @@ func (driver GoogleDrive) File(path string, account *model.Account) (*model.File
func (driver GoogleDrive) Files(path string, account *model.Account) ([]model.File, error) { func (driver GoogleDrive) Files(path string, account *model.Account) ([]model.File, error) {
path = utils.ParsePath(path) path = utils.ParsePath(path)
var rawFiles []GoogleFile var rawFiles []File
cache, err := base.GetCache(path, account) cache, err := base.GetCache(path, account)
if err == nil { if err == nil {
rawFiles, _ = cache.([]GoogleFile) rawFiles, _ = cache.([]File)
} else { } else {
file, err := driver.File(path, account) file, err := driver.File(path, account)
if err != nil { if err != nil {
@ -125,20 +126,9 @@ func (driver GoogleDrive) Link(args base.Args, account *model.Account) (*base.Li
return nil, base.ErrNotFile return nil, base.ErrNotFile
} }
url := fmt.Sprintf("https://www.googleapis.com/drive/v3/files/%s?includeItemsFromAllDrives=true&supportsAllDrives=true", file.Id) url := fmt.Sprintf("https://www.googleapis.com/drive/v3/files/%s?includeItemsFromAllDrives=true&supportsAllDrives=true", file.Id)
var e GoogleError _, err = driver.Request(url, base.Get, nil, nil, nil, nil, nil, account)
_, _ = googleClient.R().SetError(&e). if err != nil {
SetHeader("Authorization", "Bearer "+account.AccessToken). return nil, err
Get(url)
if e.Error.Code != 0 {
if e.Error.Code == 401 {
err = driver.RefreshToken(account)
if err != nil {
_ = model.SaveAccount(account)
return nil, err
}
return driver.Link(args, account)
}
return nil, fmt.Errorf("%s: %v", e.Error.Message, e.Error.Errors)
} }
link := base.Link{ link := base.Link{
Url: url + "&alt=media", Url: url + "&alt=media",

View File

@ -7,23 +7,25 @@ import (
"github.com/Xhofe/alist/model" "github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils" "github.com/Xhofe/alist/utils"
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
"path/filepath" "path/filepath"
"strconv" "strconv"
"time" "time"
) )
var googleClient = resty.New() type TokenError struct {
type GoogleTokenError struct {
Error string `json:"error"` Error string `json:"error"`
ErrorDescription string `json:"error_description"` ErrorDescription string `json:"error_description"`
} }
func (driver GoogleDrive) RefreshToken(account *model.Account) error { func (driver GoogleDrive) RefreshToken(account *model.Account) error {
url := "https://www.googleapis.com/oauth2/v4/token" url := "https://www.googleapis.com/oauth2/v4/token"
if account.APIProxyUrl != "" {
url = fmt.Sprintf("%s/%s", account.APIProxyUrl, url)
}
var resp base.TokenResp var resp base.TokenResp
var e GoogleTokenError var e TokenError
_, err := googleClient.R().SetResult(&resp).SetError(&e). res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).
SetFormData(map[string]string{ SetFormData(map[string]string{
"client_id": account.ClientId, "client_id": account.ClientId,
"client_secret": account.ClientSecret, "client_secret": account.ClientSecret,
@ -33,6 +35,7 @@ func (driver GoogleDrive) RefreshToken(account *model.Account) error {
if err != nil { if err != nil {
return err return err
} }
log.Debug(res.String())
if e.Error != "" { if e.Error != "" {
return fmt.Errorf(e.Error) return fmt.Errorf(e.Error)
} }
@ -41,7 +44,7 @@ func (driver GoogleDrive) RefreshToken(account *model.Account) error {
return nil return nil
} }
type GoogleFile struct { type File struct {
Id string `json:"id"` Id string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
MimeType string `json:"mimeType"` MimeType string `json:"mimeType"`
@ -53,7 +56,7 @@ func (driver GoogleDrive) IsDir(mimeType string) bool {
return mimeType == "application/vnd.google-apps.folder" || mimeType == "application/vnd.google-apps.shortcut" return mimeType == "application/vnd.google-apps.folder" || mimeType == "application/vnd.google-apps.shortcut"
} }
func (driver GoogleDrive) FormatFile(file *GoogleFile) *model.File { func (driver GoogleDrive) FormatFile(file *File) *model.File {
f := &model.File{ f := &model.File{
Id: file.Id, Id: file.Id,
Name: file.Name, Name: file.Name,
@ -72,12 +75,12 @@ func (driver GoogleDrive) FormatFile(file *GoogleFile) *model.File {
return f return f
} }
type GoogleFiles struct { type Files struct {
NextPageToken string `json:"nextPageToken"` NextPageToken string `json:"nextPageToken"`
Files []GoogleFile `json:"files"` Files []File `json:"files"`
} }
type GoogleError struct { type Error struct {
Error struct { Error struct {
Errors []struct { Errors []struct {
Domain string `json:"domain"` Domain string `json:"domain"`
@ -91,68 +94,86 @@ type GoogleError struct {
} `json:"error"` } `json:"error"`
} }
func (driver GoogleDrive) GetFiles(id string, account *model.Account) ([]GoogleFile, error) { func (driver GoogleDrive) GetFiles(id string, account *model.Account) ([]File, error) {
pageToken := "first" pageToken := "first"
res := make([]GoogleFile, 0) res := make([]File, 0)
for pageToken != "" { for pageToken != "" {
if pageToken == "first" { if pageToken == "first" {
pageToken = "" pageToken = ""
} }
var resp GoogleFiles var resp Files
var e GoogleError query := map[string]string{
_, err := googleClient.R().SetResult(&resp).SetError(&e). "orderBy": "folder,name,modifiedTime desc",
SetHeader("Authorization", "Bearer "+account.AccessToken). "fields": "files(id,name,mimeType,size,modifiedTime),nextPageToken",
SetQueryParams(map[string]string{ "pageSize": "1000",
"orderBy": "folder,name,modifiedTime desc", "q": fmt.Sprintf("'%s' in parents and trashed = false", id),
"fields": "files(id,name,mimeType,size,modifiedTime),nextPageToken", "includeItemsFromAllDrives": "true",
"pageSize": "1000", "supportsAllDrives": "true",
"q": fmt.Sprintf("'%s' in parents and trashed = false", id), "pageToken": pageToken,
"includeItemsFromAllDrives": "true", }
"supportsAllDrives": "true", _, err := driver.Request("https://www.googleapis.com/drive/v3/files",
"pageToken": pageToken, base.Get, nil, query, nil, nil, &resp, account)
}).Get("https://www.googleapis.com/drive/v3/files")
if err != nil { if err != nil {
return nil, err return nil, err
} }
if e.Error.Code != 0 {
if e.Error.Code == 401 {
err = driver.RefreshToken(account)
if err != nil {
_ = model.SaveAccount(account)
return nil, err
}
return driver.GetFiles(id, account)
}
return nil, fmt.Errorf("%s: %v", e.Error.Message, e.Error.Errors)
}
pageToken = resp.NextPageToken pageToken = resp.NextPageToken
res = append(res, resp.Files...) res = append(res, resp.Files...)
} }
return res, nil return res, nil
} }
//func (driver GoogleDrive) GetFile(path string, account *model.Account) (*GoogleFile, error) { func (driver GoogleDrive) Request(url string, method int, headers, query, form map[string]string, data *base.Json, resp interface{}, account *model.Account) ([]byte, error) {
// dir, name := filepath.Split(path) rawUrl := url
// dir = utils.ParsePath(dir) if account.APIProxyUrl != "" {
// _, _, err := driver.ParentPath(dir, account) url = fmt.Sprintf("%s/%s", account.APIProxyUrl, url)
// if err != nil { }
// return nil, err req := base.RestyClient.R()
// } req.SetHeader("Authorization", "Bearer "+account.AccessToken)
// parentFiles_, _ := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, dir)) if headers != nil {
// parentFiles, _ := parentFiles_.([]GoogleFile) req.SetHeaders(headers)
// for _, file := range parentFiles { }
// if file.Name == name { if query != nil {
// if !driver.IsDir(file.MimeType) { req.SetQueryParams(query)
// return &file, err }
// } else { if form != nil {
// return nil, drivers.ErrNotFile req.SetFormData(form)
// } }
// } if data != nil {
// } req.SetBody(data)
// return nil, drivers.ErrPathNotFound }
//} if resp != nil {
req.SetResult(resp)
}
var res *resty.Response
var err error
var e Error
req.SetError(&e)
switch method {
case base.Get:
res, err = req.Get(url)
case base.Post:
res, err = req.Post(url)
default:
return nil, base.ErrNotSupport
}
if err != nil {
return nil, err
}
log.Debug(res.String())
if e.Error.Code != 0 {
if e.Error.Code == 401 {
err = driver.RefreshToken(account)
if err != nil {
_ = model.SaveAccount(account)
return nil, err
}
return driver.Request(rawUrl, method, headers, query, form, data, resp, account)
}
return nil, fmt.Errorf("%s: %v", e.Error.Message, e.Error.Errors)
}
return res.Body(), nil
}
func init() { func init() {
base.RegisterDriver(&GoogleDrive{}) base.RegisterDriver(&GoogleDrive{})
googleClient.SetRetryCount(3)
} }