mirror of https://github.com/Xhofe/alist
				
				
				
			✨ support onedrive
							parent
							
								
									510292c8b0
								
							
						
					
					
						commit
						04e89754f7
					
				| 
						 | 
				
			
			@ -112,7 +112,7 @@ type AliFile struct {
 | 
			
		|||
	Url           string     `json:"url"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func AliToFile(file AliFile) *model.File {
 | 
			
		||||
func (a AliDrive) FormatFile(file *AliFile) *model.File {
 | 
			
		||||
	f := &model.File{
 | 
			
		||||
		Name:      file.Name,
 | 
			
		||||
		Size:      file.Size,
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +148,7 @@ func (a AliDrive) GetFiles(fileId string, account *model.Account) ([]AliFile, er
 | 
			
		|||
			SetResult(&resp).
 | 
			
		||||
			SetError(&e).
 | 
			
		||||
			SetHeader("authorization", "Bearer\t"+account.AccessToken).
 | 
			
		||||
			SetBody(JsonStr(Json{
 | 
			
		||||
			SetBody(Json{
 | 
			
		||||
				"drive_id":                account.DriveId,
 | 
			
		||||
				"fields":                  "*",
 | 
			
		||||
				"image_thumbnail_process": "image/resize,w_400/format,jpeg",
 | 
			
		||||
| 
						 | 
				
			
			@ -160,11 +160,20 @@ func (a AliDrive) GetFiles(fileId string, account *model.Account) ([]AliFile, er
 | 
			
		|||
				"parent_file_id":          fileId,
 | 
			
		||||
				"video_thumbnail_process": "video/snapshot,t_0,f_jpg,ar_auto,w_300",
 | 
			
		||||
				"url_expire_sec":          14400,
 | 
			
		||||
			})).Post("https://api.aliyundrive.com/v2/file/list")
 | 
			
		||||
			}).Post("https://api.aliyundrive.com/v2/file/list")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		if e.Code != "" {
 | 
			
		||||
			if e.Code == "AccessTokenInvalid" {
 | 
			
		||||
				err = a.RefreshToken(account)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return nil, err
 | 
			
		||||
				} else {
 | 
			
		||||
					_ = model.SaveAccount(*account)
 | 
			
		||||
					return a.GetFiles(fileId, account)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return nil, fmt.Errorf("%s", e.Message)
 | 
			
		||||
		}
 | 
			
		||||
		marker = resp.NextMarker
 | 
			
		||||
| 
						 | 
				
			
			@ -202,12 +211,12 @@ func (a AliDrive) Path(path string, account *model.Account) (*model.File, []*mod
 | 
			
		|||
	if err == nil {
 | 
			
		||||
		file, ok := cache.(AliFile)
 | 
			
		||||
		if ok {
 | 
			
		||||
			return AliToFile(file), nil, nil
 | 
			
		||||
			return a.FormatFile(&file), nil, nil
 | 
			
		||||
		} else {
 | 
			
		||||
			files, _ := cache.([]AliFile)
 | 
			
		||||
			res := make([]*model.File, 0)
 | 
			
		||||
			for _, file = range files {
 | 
			
		||||
				res = append(res, AliToFile(file))
 | 
			
		||||
				res = append(res, a.FormatFile(&file))
 | 
			
		||||
			}
 | 
			
		||||
			return nil, res, nil
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -227,12 +236,12 @@ func (a AliDrive) Path(path string, account *model.Account) (*model.File, []*mod
 | 
			
		|||
				if file.Name == name {
 | 
			
		||||
					found = true
 | 
			
		||||
					if file.Type == "file" {
 | 
			
		||||
						url,err := a.Link(path,account)
 | 
			
		||||
						url, err := a.Link(path, account)
 | 
			
		||||
						if err != nil {
 | 
			
		||||
							return nil, nil, err
 | 
			
		||||
						}
 | 
			
		||||
						file.Url = url
 | 
			
		||||
						return AliToFile(file), nil, nil
 | 
			
		||||
						return a.FormatFile(&file), nil, nil
 | 
			
		||||
					} else {
 | 
			
		||||
						fileId = file.FileId
 | 
			
		||||
						break
 | 
			
		||||
| 
						 | 
				
			
			@ -250,7 +259,7 @@ func (a AliDrive) Path(path string, account *model.Account) (*model.File, []*mod
 | 
			
		|||
		_ = conf.Cache.Set(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path), files, nil)
 | 
			
		||||
		res := make([]*model.File, 0)
 | 
			
		||||
		for _, file := range files {
 | 
			
		||||
			res = append(res, AliToFile(file))
 | 
			
		||||
			res = append(res, a.FormatFile(&file))
 | 
			
		||||
		}
 | 
			
		||||
		return nil, res, nil
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -275,34 +284,39 @@ func (a AliDrive) Link(path string, account *model.Account) (string, error) {
 | 
			
		|||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if e.Code != "" {
 | 
			
		||||
		if e.Code == "AccessTokenInvalid" {
 | 
			
		||||
			err = a.RefreshToken(account)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return "", err
 | 
			
		||||
			} else {
 | 
			
		||||
				_ = model.SaveAccount(*account)
 | 
			
		||||
				return a.Link(path, account)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return "", fmt.Errorf("%s", e.Message)
 | 
			
		||||
	}
 | 
			
		||||
	return resp["url"].(string), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AliTokenResp struct {
 | 
			
		||||
	AccessToken  string `json:"access_token"`
 | 
			
		||||
	RefreshToken string `json:"refresh_token"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func AliRefreshToken(refresh string) (string, string, error) {
 | 
			
		||||
func (a AliDrive) RefreshToken(account *model.Account) error {
 | 
			
		||||
	url := "https://auth.aliyundrive.com/v2/account/token"
 | 
			
		||||
	var resp AliTokenResp
 | 
			
		||||
	var resp TokenResp
 | 
			
		||||
	var e AliRespError
 | 
			
		||||
	_, err := aliClient.R().
 | 
			
		||||
		//ForceContentType("application/json").
 | 
			
		||||
		SetBody(JsonStr(Json{"refresh_token": refresh, "grant_type": "refresh_token"})).
 | 
			
		||||
		SetBody(Json{"refresh_token": account.RefreshToken, "grant_type": "refresh_token"}).
 | 
			
		||||
		SetResult(&resp).
 | 
			
		||||
		SetError(&e).
 | 
			
		||||
		Post(url)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", "", err
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	log.Debugf("%+v,%+v", resp, e)
 | 
			
		||||
	if e.Code != "" {
 | 
			
		||||
		return "", "", fmt.Errorf("failed to refresh token: %s", e.Message)
 | 
			
		||||
		return fmt.Errorf("failed to refresh token: %s", e.Message)
 | 
			
		||||
	}
 | 
			
		||||
	return resp.RefreshToken, resp.AccessToken, nil
 | 
			
		||||
	account.RefreshToken, account.AccessToken = resp.RefreshToken, resp.AccessToken
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a AliDrive) Save(account *model.Account, old *model.Account) error {
 | 
			
		||||
| 
						 | 
				
			
			@ -315,25 +329,24 @@ func (a AliDrive) Save(account *model.Account, old *model.Account) error {
 | 
			
		|||
	if account.Limit == 0 {
 | 
			
		||||
		account.Limit = 200
 | 
			
		||||
	}
 | 
			
		||||
	refresh, access, err := AliRefreshToken(account.RefreshToken)
 | 
			
		||||
	err := a.RefreshToken(account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	var resp Json
 | 
			
		||||
	_, _ = aliClient.R().SetResult(&resp).
 | 
			
		||||
		SetBody("{}").
 | 
			
		||||
		SetHeader("authorization", "Bearer\t"+access).
 | 
			
		||||
		SetHeader("authorization", "Bearer\t"+account.AccessToken).
 | 
			
		||||
		Post("https://api.aliyundrive.com/v2/user/get")
 | 
			
		||||
	log.Debugf("user info: %+v", resp)
 | 
			
		||||
	account.DriveId = resp["default_drive_id"].(string)
 | 
			
		||||
	account.RefreshToken, account.AccessToken = refresh, access
 | 
			
		||||
	cronId, err := conf.Cron.AddFunc("@every 2h", func() {
 | 
			
		||||
		name := account.Name
 | 
			
		||||
		newAccount, ok := model.GetAccount(name)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		newAccount.RefreshToken, newAccount.AccessToken, err = AliRefreshToken(newAccount.RefreshToken)
 | 
			
		||||
		err = a.RefreshToken(&newAccount)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			newAccount.Status = err.Error()
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
package drivers
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/Xhofe/alist/model"
 | 
			
		||||
	"github.com/gofiber/fiber/v2"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +11,7 @@ type Driver interface {
 | 
			
		|||
	Link(path string, account *model.Account) (string, error)
 | 
			
		||||
	Save(account *model.Account, old *model.Account) error
 | 
			
		||||
	Proxy(ctx *fiber.Ctx)
 | 
			
		||||
	Preview(path string, account *model.Account) (interface{},error)
 | 
			
		||||
	Preview(path string, account *model.Account) (interface{}, error)
 | 
			
		||||
	// TODO
 | 
			
		||||
	//MakeDir(path string, account *model.Account) error
 | 
			
		||||
	//Move(src string, des string, account *model.Account) error
 | 
			
		||||
| 
						 | 
				
			
			@ -24,10 +23,16 @@ type Item struct {
 | 
			
		|||
	Name        string `json:"name"`
 | 
			
		||||
	Label       string `json:"label"`
 | 
			
		||||
	Type        string `json:"type"`
 | 
			
		||||
	Values      string `json:"values"`
 | 
			
		||||
	Required    bool   `json:"required"`
 | 
			
		||||
	Description string `json:"description"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type TokenResp struct {
 | 
			
		||||
	AccessToken  string `json:"access_token"`
 | 
			
		||||
	RefreshToken string `json:"refresh_token"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var driversMap = map[string]Driver{}
 | 
			
		||||
 | 
			
		||||
func RegisterDriver(name string, driver Driver) {
 | 
			
		||||
| 
						 | 
				
			
			@ -48,8 +53,3 @@ func GetDrivers() map[string][]Item {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
type Json map[string]interface{}
 | 
			
		||||
 | 
			
		||||
func JsonStr(j Json) string {
 | 
			
		||||
	data, _ := json.Marshal(j)
 | 
			
		||||
	return string(data)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,307 @@
 | 
			
		|||
package drivers
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/Xhofe/alist/conf"
 | 
			
		||||
	"github.com/Xhofe/alist/model"
 | 
			
		||||
	"github.com/Xhofe/alist/utils"
 | 
			
		||||
	"github.com/go-resty/resty/v2"
 | 
			
		||||
	"github.com/gofiber/fiber/v2"
 | 
			
		||||
	"github.com/robfig/cron/v3"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Onedrive struct{}
 | 
			
		||||
 | 
			
		||||
var oneClient = resty.New()
 | 
			
		||||
 | 
			
		||||
type OnedriveHost struct {
 | 
			
		||||
	Oauth string
 | 
			
		||||
	Api   string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var onedriveHostMap = map[string]OnedriveHost{
 | 
			
		||||
	"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 init() {
 | 
			
		||||
	RegisterDriver("Onedrive", &Onedrive{})
 | 
			
		||||
	oneClient.SetRetryCount(3)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Onedrive) GetMetaUrl(account *model.Account, auth bool, path string) string {
 | 
			
		||||
	path = filepath.Join(account.RootFolder, path)
 | 
			
		||||
	host, _ := onedriveHostMap[account.Zone]
 | 
			
		||||
	if auth {
 | 
			
		||||
		return host.Oauth
 | 
			
		||||
	}
 | 
			
		||||
	switch account.OnedriveType {
 | 
			
		||||
	case "onedrive":
 | 
			
		||||
		{
 | 
			
		||||
			if 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 == "/" {
 | 
			
		||||
				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 ""
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Onedrive) Items() []Item {
 | 
			
		||||
	return []Item{
 | 
			
		||||
		{
 | 
			
		||||
			Name:        "zone",
 | 
			
		||||
			Label:       "zone",
 | 
			
		||||
			Type:        "select",
 | 
			
		||||
			Required:    true,
 | 
			
		||||
			Values:      "global,cn,us,de",
 | 
			
		||||
			Description: "",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			Name:     "onedrive_type",
 | 
			
		||||
			Label:    "onedrive type",
 | 
			
		||||
			Type:     "select",
 | 
			
		||||
			Required: true,
 | 
			
		||||
			Values:   "onedrive,sharepoint",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			Name:     "client_id",
 | 
			
		||||
			Label:    "client id",
 | 
			
		||||
			Type:     "string",
 | 
			
		||||
			Required: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			Name:     "client_secret",
 | 
			
		||||
			Label:    "client secret",
 | 
			
		||||
			Type:     "string",
 | 
			
		||||
			Required: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			Name:     "redirect_uri",
 | 
			
		||||
			Label:    "redirect uri",
 | 
			
		||||
			Type:     "string",
 | 
			
		||||
			Required: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			Name:     "refresh_token",
 | 
			
		||||
			Label:    "refresh token",
 | 
			
		||||
			Type:     "string",
 | 
			
		||||
			Required: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			Name:     "site_url",
 | 
			
		||||
			Label:    "site url",
 | 
			
		||||
			Type:     "string",
 | 
			
		||||
			Required: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			Name:     "root_folder",
 | 
			
		||||
			Label:    "root folder path",
 | 
			
		||||
			Type:     "string",
 | 
			
		||||
			Required: false,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type OneTokenErr struct {
 | 
			
		||||
	Error            string `json:"error"`
 | 
			
		||||
	ErrorDescription string `json:"error_description"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Onedrive) RefreshToken(account *model.Account) error {
 | 
			
		||||
	url := o.GetMetaUrl(account, true, "") + "/common/oauth2/v2.0/token"
 | 
			
		||||
	var resp TokenResp
 | 
			
		||||
	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 {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if e.Error != "" {
 | 
			
		||||
		return fmt.Errorf("%s", e.ErrorDescription)
 | 
			
		||||
	}
 | 
			
		||||
	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"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type OneFiles struct {
 | 
			
		||||
	Value []OneFile `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type OneRespErr struct {
 | 
			
		||||
	Error struct {
 | 
			
		||||
		Code    string `json:"code"`
 | 
			
		||||
		Message string `json:"message"`
 | 
			
		||||
	} `json:"error"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Onedrive) FormatFile(file *OneFile) *model.File {
 | 
			
		||||
	f := &model.File{
 | 
			
		||||
		Name:      file.Name,
 | 
			
		||||
		Size:      file.Size,
 | 
			
		||||
		UpdatedAt: file.LastModifiedDateTime,
 | 
			
		||||
		Driver:    "OneDrive",
 | 
			
		||||
		Url:       file.Url,
 | 
			
		||||
	}
 | 
			
		||||
	if file.File.MimeType == "" {
 | 
			
		||||
		f.Type = conf.FOLDER
 | 
			
		||||
	} else {
 | 
			
		||||
		f.Type = utils.GetFileType(filepath.Ext(file.Name))
 | 
			
		||||
	}
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Onedrive) GetFiles(account *model.Account, path string) ([]OneFile, error) {
 | 
			
		||||
	var files OneFiles
 | 
			
		||||
	var e OneRespErr
 | 
			
		||||
	_, err := oneClient.R().SetResult(&files).SetError(&e).
 | 
			
		||||
		SetHeader("Authorization", "Bearer  "+account.AccessToken).
 | 
			
		||||
		Get(o.GetMetaUrl(account, false, path) + "/children")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if e.Error.Code != "" {
 | 
			
		||||
		return nil, fmt.Errorf("%s", e.Error.Message)
 | 
			
		||||
	}
 | 
			
		||||
	return files.Value, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o 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(o.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 (o Onedrive) Path(path string, account *model.Account) (*model.File, []*model.File, error) {
 | 
			
		||||
	path = utils.ParsePath(path)
 | 
			
		||||
	cache, err := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path))
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		files, _ := cache.([]*model.File)
 | 
			
		||||
		return nil, files, nil
 | 
			
		||||
	}
 | 
			
		||||
	file, err := o.GetFile(account, path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if file.File.MimeType != "" {
 | 
			
		||||
		return o.FormatFile(file), nil, nil
 | 
			
		||||
	} else {
 | 
			
		||||
		files, err := o.GetFiles(account, path)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, nil, err
 | 
			
		||||
		}
 | 
			
		||||
		res := make([]*model.File, 0)
 | 
			
		||||
		for _, file := range files {
 | 
			
		||||
			res = append(res, o.FormatFile(&file))
 | 
			
		||||
		}
 | 
			
		||||
		_ = conf.Cache.Set(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path), res, nil)
 | 
			
		||||
		return nil, res, nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Onedrive) Link(path string, account *model.Account) (string, error) {
 | 
			
		||||
	file, err := o.GetFile(account, path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if file.File.MimeType == "" {
 | 
			
		||||
		return "", fmt.Errorf("can't down folder")
 | 
			
		||||
	}
 | 
			
		||||
	return file.Url, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Onedrive) Save(account *model.Account, old *model.Account) error {
 | 
			
		||||
	_, ok := onedriveHostMap[account.Zone]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return fmt.Errorf("no [%s] zone", account.Zone)
 | 
			
		||||
	}
 | 
			
		||||
	if old != nil {
 | 
			
		||||
		conf.Cron.Remove(cron.EntryID(old.CronId))
 | 
			
		||||
	}
 | 
			
		||||
	account.RootFolder = utils.ParsePath(account.RootFolder)
 | 
			
		||||
	err := o.RefreshToken(account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	cronId, err := conf.Cron.AddFunc("@every 1h", func() {
 | 
			
		||||
		name := account.Name
 | 
			
		||||
		newAccount, ok := model.GetAccount(name)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		err = o.RefreshToken(&newAccount)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			newAccount.Status = err.Error()
 | 
			
		||||
		}
 | 
			
		||||
		_ = model.SaveAccount(newAccount)
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	account.CronId = int(cronId)
 | 
			
		||||
	err = model.SaveAccount(*account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Onedrive) Proxy(ctx *fiber.Ctx) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o Onedrive) Preview(path string, account *model.Account) (interface{}, error) {
 | 
			
		||||
	return nil, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ Driver = (*Onedrive)(nil)
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +22,13 @@ type Account struct {
 | 
			
		|||
	Proxy          bool       `json:"proxy"`
 | 
			
		||||
	UpdatedAt      *time.Time `json:"updated_at"`
 | 
			
		||||
	Search         bool       `json:"search"`
 | 
			
		||||
	ClientId       string     `json:"client_id"`
 | 
			
		||||
	ClientSecret   string     `json:"client_secret"`
 | 
			
		||||
	Zone           string     `json:"zone"`
 | 
			
		||||
	RedirectUri    string     `json:"redirect_uri"`
 | 
			
		||||
	SiteUrl        string     `json:"site_url"`
 | 
			
		||||
	SiteId         string
 | 
			
		||||
	OnedriveType   string `json:"onedrive_type"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var accountsMap = map[string]Account{}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue