alist/drivers/onedrive/onedrive.go

191 lines
4.7 KiB
Go
Raw Normal View History

2021-12-06 07:55:05 +00:00
package onedrive
2021-11-27 12:20:14 +00:00
import (
"fmt"
"github.com/Xhofe/alist/conf"
2021-12-06 07:55:05 +00:00
"github.com/Xhofe/alist/drivers/base"
2021-11-27 12:20:14 +00:00
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
"path/filepath"
"time"
)
var oneClient = resty.New()
type Host struct {
Oauth string
Api string
}
var onedriveHostMap = map[string]Host{
"global": {
Oauth: "https://login.microsoftonline.com",
Api: "https://graph.microsoft.com",
},
"cn": {
Oauth: "https://login.chinacloudapi.cn",
Api: "https://microsoftgraph.chinacloudapi.cn",
},
"us": {
Oauth: "https://login.microsoftonline.us",
Api: "https://graph.microsoft.us",
},
"de": {
Oauth: "https://login.microsoftonline.de",
Api: "https://graph.microsoft.de",
},
}
func (driver Onedrive) GetMetaUrl(account *model.Account, auth bool, path string) string {
path = filepath.Join(account.RootFolder, path)
log.Debugf(path)
host, _ := onedriveHostMap[account.Zone]
if auth {
return host.Oauth
}
switch account.OnedriveType {
case "onedrive":
{
if path == "/" || path == "\\" {
return fmt.Sprintf("%s/v1.0/me/drive/root", host.Api)
} else {
return fmt.Sprintf("%s/v1.0/me/drive/root:%s:", host.Api, path)
}
}
case "sharepoint":
{
if path == "/" || path == "\\" {
2021-11-27 12:20:14 +00:00
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root", host.Api, account.SiteId)
} else {
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root:%s:", host.Api, account.SiteId, path)
}
}
default:
return ""
}
}
type OneTokenErr struct {
Error string `json:"error"`
ErrorDescription string `json:"error_description"`
}
func (driver Onedrive) RefreshToken(account *model.Account) error {
url := driver.GetMetaUrl(account, true, "") + "/common/oauth2/v2.0/token"
2021-12-06 07:55:05 +00:00
var resp base.TokenResp
2021-11-27 12:20:14 +00:00
var e OneTokenErr
_, err := oneClient.R().SetResult(&resp).SetError(&e).SetFormData(map[string]string{
"grant_type": "refresh_token",
"client_id": account.ClientId,
"client_secret": account.ClientSecret,
"redirect_uri": account.RedirectUri,
"refresh_token": account.RefreshToken,
}).Post(url)
if err != nil {
account.Status = err.Error()
return err
}
if e.Error != "" {
account.Status = e.ErrorDescription
return fmt.Errorf("%s", e.ErrorDescription)
} else {
account.Status = "work"
}
account.RefreshToken, account.AccessToken = resp.RefreshToken, resp.AccessToken
return nil
}
type OneFile struct {
Name string `json:"name"`
Size int64 `json:"size"`
LastModifiedDateTime *time.Time `json:"lastModifiedDateTime"`
Url string `json:"@microsoft.graph.downloadUrl"`
File struct {
MimeType string `json:"mimeType"`
} `json:"file"`
2021-11-30 08:27:23 +00:00
Thumbnails []struct{
Medium struct{
Url string `json:"url"`
} `json:"medium"`
} `json:"thumbnails"`
2021-11-27 12:20:14 +00:00
}
type OneFiles struct {
Value []OneFile `json:"value"`
NextLink string `json:"@odata.nextLink"`
}
type OneRespErr struct {
Error struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
func (driver Onedrive) FormatFile(file *OneFile) *model.File {
f := &model.File{
Name: file.Name,
Size: file.Size,
UpdatedAt: file.LastModifiedDateTime,
2021-11-30 01:37:51 +00:00
Driver: driver.Config().Name,
2021-11-27 12:20:14 +00:00
Url: file.Url,
}
2021-11-30 08:27:23 +00:00
if len(file.Thumbnails) > 0 {
f.Thumbnail = file.Thumbnails[0].Medium.Url
}
2021-11-27 12:20:14 +00:00
if file.File.MimeType == "" {
f.Type = conf.FOLDER
} else {
f.Type = utils.GetFileType(filepath.Ext(file.Name))
}
return f
}
func (driver Onedrive) GetFiles(account *model.Account, path string) ([]OneFile, error) {
var res []OneFile
2021-11-30 08:27:23 +00:00
nextLink := driver.GetMetaUrl(account, false, path) + "/children?$expand=thumbnails"
2021-11-27 12:20:14 +00:00
if account.OrderBy != "" {
2021-11-30 08:27:23 +00:00
nextLink += fmt.Sprintf("&orderby=%s", account.OrderBy)
2021-11-27 12:20:14 +00:00
if account.OrderDirection != "" {
2021-12-01 03:25:04 +00:00
nextLink += fmt.Sprintf("%%20%s", account.OrderDirection)
2021-11-27 12:20:14 +00:00
}
}
for nextLink != "" {
var files OneFiles
var e OneRespErr
_, err := oneClient.R().SetResult(&files).SetError(&e).
SetHeader("Authorization", "Bearer "+account.AccessToken).
Get(nextLink)
if err != nil {
return nil, err
}
if e.Error.Code != "" {
return nil, fmt.Errorf("%s", e.Error.Message)
}
res = append(res, files.Value...)
nextLink = files.NextLink
}
return res, nil
}
func (driver Onedrive) GetFile(account *model.Account, path string) (*OneFile, error) {
var file OneFile
var e OneRespErr
_, err := oneClient.R().SetResult(&file).SetError(&e).
SetHeader("Authorization", "Bearer "+account.AccessToken).
Get(driver.GetMetaUrl(account, false, path))
if err != nil {
return nil, err
}
if e.Error.Code != "" {
return nil, fmt.Errorf("%s", e.Error.Message)
}
return &file, nil
}
func init() {
2021-12-06 07:55:05 +00:00
base.RegisterDriver(&Onedrive{})
2021-11-27 12:20:14 +00:00
oneClient.SetRetryCount(3)
}