🔨 refactor driver: ali

pull/548/head
微凉 2021-11-27 19:40:36 +08:00
parent 98691b2aa8
commit f577d82242
14 changed files with 999 additions and 918 deletions

View File

@ -17,7 +17,7 @@ func InitAccounts() {
model.RegisterAccount(account)
driver, ok := drivers.GetDriver(account.Type)
if !ok {
log.Errorf("no [%s] driver", driver)
log.Errorf("no [%s] driver", account.Type)
} else {
err := driver.Save(&accounts[i], nil)
if err != nil {

7
bootstrap/drivers.go Normal file
View File

@ -0,0 +1,7 @@
package bootstrap
import (
_ "github.com/Xhofe/alist/drivers/123pan"
_ "github.com/Xhofe/alist/drivers/189cloud"
_ "github.com/Xhofe/alist/drivers/alidrive"
)

View File

@ -1,321 +0,0 @@
package drivers
import (
"fmt"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/gin-gonic/gin"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
"path/filepath"
"strconv"
"time"
)
type Pan123 struct {
}
var pan123Client = resty.New()
var pan123 = "123Pan"
func (p Pan123) Items() []Item {
return []Item{
{
Name: "proxy",
Label: "proxy",
Type: "bool",
Required: true,
Description: "allow proxy",
},
{
Name: "username",
Label: "username",
Type: "string",
Required: true,
Description: "account username/phone number",
},
{
Name: "password",
Label: "password",
Type: "string",
Required: true,
Description: "account password",
},
{
Name: "root_folder",
Label: "root folder file_id",
Type: "string",
Required: false,
},
{
Name: "order_by",
Label: "order_by",
Type: "select",
Values: "name,fileId,updateAt,createAt",
Required: true,
},
{
Name: "order_direction",
Label: "order_direction",
Type: "select",
Values: "asc,desc",
Required: true,
},
}
}
type Pan123TokenResp struct {
Code int `json:"code"`
Data struct {
Token string `json:"token"`
} `json:"data"`
Message string `json:"message"`
}
func (p Pan123) Login(account *model.Account) error {
var resp Pan123TokenResp
_, err := pan123Client.R().
SetResult(&resp).
SetBody(Json{
"passport": account.Username,
"password": account.Password,
}).Post("https://www.123pan.com/api/user/sign_in")
if err != nil {
return err
}
if resp.Code != 200 {
err = fmt.Errorf(resp.Message)
account.Status = resp.Message
} else {
account.Status = "work"
account.AccessToken = resp.Data.Token
}
_ = model.SaveAccount(account)
return err
}
func (p Pan123) Save(account *model.Account, old *model.Account) error {
if account.RootFolder == "" {
account.RootFolder = "0"
}
err := p.Login(account)
return err
}
type Pan123File struct {
FileName string `json:"FileName"`
Size int64 `json:"Size"`
UpdateAt *time.Time `json:"UpdateAt"`
FileId int64 `json:"FileId"`
Type int `json:"Type"`
Etag string `json:"Etag"`
S3KeyFlag string `json:"S3KeyFlag"`
}
func (p Pan123) FormatFile(file *Pan123File) *model.File {
f := &model.File{
Id: strconv.FormatInt(file.FileId, 10),
Name: file.FileName,
Size: file.Size,
Driver: "123Pan",
UpdatedAt: file.UpdateAt,
}
if file.Type == 1 {
f.Type = conf.FOLDER
} else {
f.Type = utils.GetFileType(filepath.Ext(file.FileName))
}
return f
}
type Pan123Files struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
InfoList []Pan123File `json:"InfoList"`
Next string `json:"Next"`
} `json:"data"`
}
func (p Pan123) GetFiles(parentId string, account *model.Account) ([]Pan123File, error) {
next := "0"
res := make([]Pan123File, 0)
for next != "-1" {
var resp Pan123Files
_, err := pan123Client.R().SetResult(&resp).
SetHeader("authorization", "Bearer "+account.AccessToken).
SetQueryParams(map[string]string{
"driveId": "0",
"limit": "100",
"next": next,
"orderBy": account.OrderBy,
"orderDirection": account.OrderDirection,
"parentFileId": parentId,
"trashed": "false",
}).Get("https://www.123pan.com/api/file/list")
if err != nil {
return nil, err
}
log.Debugf("%+v", resp)
if resp.Code != 0 {
if resp.Code == 401 {
err := p.Login(account)
if err != nil {
return nil, err
}
return p.GetFiles(parentId, account)
}
return nil, fmt.Errorf(resp.Message)
}
next = resp.Data.Next
res = append(res, resp.Data.InfoList...)
}
return res, nil
}
func (p Pan123) File(path string, account *model.Account) (*model.File, error) {
path = utils.ParsePath(path)
if path == "/" {
return &model.File{
Id: account.RootFolder,
Name: account.Name,
Size: 0,
Type: conf.FOLDER,
Driver: pan123,
UpdatedAt: account.UpdatedAt,
}, nil
}
dir, name := filepath.Split(path)
files, err := p.Files(dir, account)
if err != nil {
return nil, err
}
for _, file := range files {
if file.Name == name {
return &file, nil
}
}
return nil, PathNotFound
}
func (p Pan123) Files(path string, account *model.Account) ([]model.File, error) {
path = utils.ParsePath(path)
var rawFiles []Pan123File
cache, err := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path))
if err == nil {
rawFiles, _ = cache.([]Pan123File)
} else {
file, err := p.File(path, account)
if err != nil {
return nil, err
}
rawFiles, err = p.GetFiles(file.Id, account)
if err != nil {
return nil, err
}
if len(rawFiles) > 0 {
_ = conf.Cache.Set(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path), rawFiles, nil)
}
}
files := make([]model.File, 0)
for _, file := range rawFiles {
files = append(files, *p.FormatFile(&file))
}
return files, nil
}
func (p Pan123) Path(path string, account *model.Account) (*model.File, []model.File, error) {
path = utils.ParsePath(path)
log.Debugf("pan123 path: %s", path)
file, err := p.File(path, account)
if err != nil {
return nil, nil, err
}
if file.Type != conf.FOLDER {
file.Url, _ = p.Link(path, account)
return file, nil, nil
}
files, err := p.Files(path, account)
if err != nil {
return nil, nil, err
}
return nil, files, nil
}
func (p Pan123) GetFile(path string, account *model.Account) (*Pan123File, error) {
dir, name := filepath.Split(path)
dir = utils.ParsePath(dir)
_, err := p.Files(dir, account)
if err != nil {
return nil, err
}
parentFiles_, _ := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, dir))
parentFiles, _ := parentFiles_.([]Pan123File)
for _, file := range parentFiles {
if file.FileName == name {
if file.Type != 1 {
return &file, err
} else {
return nil, NotFile
}
}
}
return nil, PathNotFound
}
type Pan123DownResp struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
DownloadUrl string `json:"DownloadUrl"`
} `json:"data"`
}
func (p Pan123) Link(path string, account *model.Account) (string, error) {
file, err := p.GetFile(utils.ParsePath(path), account)
if err != nil {
return "", err
}
var resp Pan123DownResp
_, err = pan123Client.R().SetResult(&resp).SetHeader("authorization", "Bearer "+account.AccessToken).
SetBody(Json{
"driveId": 0,
"etag": file.Etag,
"fileId": file.FileId,
"fileName": file.FileName,
"s3keyFlag": file.S3KeyFlag,
"size": file.Size,
"type": file.Type,
}).Post("https://www.123pan.com/api/file/download_info")
if err != nil {
return "", err
}
if resp.Code != 0 {
if resp.Code == 401 {
err := p.Login(account)
if err != nil {
return "", err
}
return p.Link(path, account)
}
return "", fmt.Errorf(resp.Message)
}
return resp.Data.DownloadUrl, nil
}
func (p Pan123) Proxy(c *gin.Context, account *model.Account) {
c.Request.Header.Del("origin")
}
func (p Pan123) Preview(path string, account *model.Account) (interface{}, error) {
return nil, nil
}
var _ Driver = (*Pan123)(nil)
func init() {
RegisterDriver("123Pan", &Pan123{})
pan123Client.SetRetryCount(3)
}

150
drivers/123pan/123pan.go Normal file
View File

@ -0,0 +1,150 @@
package _23pan
import (
"fmt"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/drivers"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
"path/filepath"
"strconv"
"time"
)
var pan123Client = resty.New()
type Pan123TokenResp struct {
Code int `json:"code"`
Data struct {
Token string `json:"token"`
} `json:"data"`
Message string `json:"message"`
}
type Pan123File struct {
FileName string `json:"FileName"`
Size int64 `json:"Size"`
UpdateAt *time.Time `json:"UpdateAt"`
FileId int64 `json:"FileId"`
Type int `json:"Type"`
Etag string `json:"Etag"`
S3KeyFlag string `json:"S3KeyFlag"`
}
type Pan123Files struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
InfoList []Pan123File `json:"InfoList"`
Next string `json:"Next"`
} `json:"data"`
}
type Pan123DownResp struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
DownloadUrl string `json:"DownloadUrl"`
} `json:"data"`
}
func (driver Pan123) Login(account *model.Account) error {
var resp Pan123TokenResp
_, err := pan123Client.R().
SetResult(&resp).
SetBody(drivers.Json{
"passport": account.Username,
"password": account.Password,
}).Post("https://www.123pan.com/api/user/sign_in")
if err != nil {
return err
}
if resp.Code != 200 {
err = fmt.Errorf(resp.Message)
account.Status = resp.Message
} else {
account.Status = "work"
account.AccessToken = resp.Data.Token
}
_ = model.SaveAccount(account)
return err
}
func (driver Pan123) FormatFile(file *Pan123File) *model.File {
f := &model.File{
Id: strconv.FormatInt(file.FileId, 10),
Name: file.FileName,
Size: file.Size,
Driver: driverName,
UpdatedAt: file.UpdateAt,
}
if file.Type == 1 {
f.Type = conf.FOLDER
} else {
f.Type = utils.GetFileType(filepath.Ext(file.FileName))
}
return f
}
func (driver Pan123) GetFiles(parentId string, account *model.Account) ([]Pan123File, error) {
next := "0"
res := make([]Pan123File, 0)
for next != "-1" {
var resp Pan123Files
_, err := pan123Client.R().SetResult(&resp).
SetHeader("authorization", "Bearer "+account.AccessToken).
SetQueryParams(map[string]string{
"driveId": "0",
"limit": "100",
"next": next,
"orderBy": account.OrderBy,
"orderDirection": account.OrderDirection,
"parentFileId": parentId,
"trashed": "false",
}).Get("https://www.123pan.com/api/file/list")
if err != nil {
return nil, err
}
log.Debugf("%+v", resp)
if resp.Code != 0 {
if resp.Code == 401 {
err := driver.Login(account)
if err != nil {
return nil, err
}
return driver.GetFiles(parentId, account)
}
return nil, fmt.Errorf(resp.Message)
}
next = resp.Data.Next
res = append(res, resp.Data.InfoList...)
}
return res, nil
}
func (driver Pan123) GetFile(path string, account *model.Account) (*Pan123File, error) {
dir, name := filepath.Split(path)
_, err := driver.Files(dir, account)
if err != nil {
return nil, err
}
parentFiles_, _ := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, dir))
parentFiles, _ := parentFiles_.([]Pan123File)
for _, file := range parentFiles {
if file.FileName == name {
if file.Type != 1 {
return &file, err
} else {
return nil, drivers.NotFile
}
}
}
return nil, drivers.PathNotFound
}
func init() {
drivers.RegisterDriver(driverName, &Pan123{})
pan123Client.SetRetryCount(3)
}

181
drivers/123pan/driver.go Normal file
View File

@ -0,0 +1,181 @@
package _23pan
import (
"fmt"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/drivers"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"path/filepath"
)
type Pan123 struct {}
var driverName = "123Pan"
func (driver Pan123) Items() []drivers.Item {
return []drivers.Item{
{
Name: "proxy",
Label: "proxy",
Type: "bool",
Required: true,
Description: "allow proxy",
},
{
Name: "username",
Label: "username",
Type: "string",
Required: true,
Description: "account username/phone number",
},
{
Name: "password",
Label: "password",
Type: "string",
Required: true,
Description: "account password",
},
{
Name: "root_folder",
Label: "root folder file_id",
Type: "string",
Required: false,
},
{
Name: "order_by",
Label: "order_by",
Type: "select",
Values: "name,fileId,updateAt,createAt",
Required: true,
},
{
Name: "order_direction",
Label: "order_direction",
Type: "select",
Values: "asc,desc",
Required: true,
},
}
}
func (driver Pan123) Save(account *model.Account, old *model.Account) error {
if account.RootFolder == "" {
account.RootFolder = "0"
}
err := driver.Login(account)
return err
}
func (driver Pan123) File(path string, account *model.Account) (*model.File, error) {
path = utils.ParsePath(path)
if path == "/" {
return &model.File{
Id: account.RootFolder,
Name: account.Name,
Size: 0,
Type: conf.FOLDER,
Driver: driverName,
UpdatedAt: account.UpdatedAt,
}, nil
}
dir, name := filepath.Split(path)
files, err := driver.Files(dir, account)
if err != nil {
return nil, err
}
for _, file := range files {
if file.Name == name {
return &file, nil
}
}
return nil, drivers.PathNotFound
}
func (driver Pan123) Files(path string, account *model.Account) ([]model.File, error) {
path = utils.ParsePath(path)
var rawFiles []Pan123File
cache, err := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path))
if err == nil {
rawFiles, _ = cache.([]Pan123File)
} else {
file, err := driver.File(path, account)
if err != nil {
return nil, err
}
rawFiles, err = driver.GetFiles(file.Id, account)
if err != nil {
return nil, err
}
if len(rawFiles) > 0 {
_ = conf.Cache.Set(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path), rawFiles, nil)
}
}
files := make([]model.File, 0)
for _, file := range rawFiles {
files = append(files, *driver.FormatFile(&file))
}
return files, nil
}
func (driver Pan123) Link(path string, account *model.Account) (string, error) {
file, err := driver.GetFile(utils.ParsePath(path), account)
if err != nil {
return "", err
}
var resp Pan123DownResp
_, err = pan123Client.R().SetResult(&resp).SetHeader("authorization", "Bearer "+account.AccessToken).
SetBody(drivers.Json{
"driveId": 0,
"etag": file.Etag,
"fileId": file.FileId,
"fileName": file.FileName,
"s3keyFlag": file.S3KeyFlag,
"size": file.Size,
"type": file.Type,
}).Post("https://www.123pan.com/api/file/download_info")
if err != nil {
return "", err
}
if resp.Code != 0 {
if resp.Code == 401 {
err := driver.Login(account)
if err != nil {
return "", err
}
return driver.Link(path, account)
}
return "", fmt.Errorf(resp.Message)
}
return resp.Data.DownloadUrl, nil
}
func (driver Pan123) Path(path string, account *model.Account) (*model.File, []model.File, error) {
path = utils.ParsePath(path)
log.Debugf("pan123 path: %s", path)
file, err := driver.File(path, account)
if err != nil {
return nil, nil, err
}
if file.Type != conf.FOLDER {
file.Url, _ = driver.Link(path, account)
return file, nil, nil
}
files, err := driver.Files(path, account)
if err != nil {
return nil, nil, err
}
return nil, files, nil
}
func (driver Pan123) Proxy(c *gin.Context, account *model.Account) {
c.Request.Header.Del("origin")
}
func (driver Pan123) Preview(path string, account *model.Account) (interface{}, error) {
return nil, nil
}
var _ drivers.Driver = (*Pan123)(nil)

View File

@ -1,4 +1,4 @@
package drivers
package _89cloud
import (
"crypto/rand"
@ -9,9 +9,9 @@ import (
"encoding/pem"
"fmt"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/drivers"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/gin-gonic/gin"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
mathRand "math/rand"
@ -22,75 +22,10 @@ import (
"time"
)
type Cloud189 struct {
}
var client189Map map[string]*resty.Client
func (c Cloud189) Items() []Item {
return []Item{
{
Name: "proxy",
Label: "proxy",
Type: "bool",
Required: true,
Description: "allow proxy",
},
{
Name: "username",
Label: "username",
Type: "string",
Required: true,
Description: "account username/phone number",
},
{
Name: "password",
Label: "password",
Type: "string",
Required: true,
Description: "account password",
},
{
Name: "root_folder",
Label: "root folder file_id",
Type: "string",
Required: true,
},
{
Name: "order_by",
Label: "order_by",
Type: "select",
Values: "name,size,lastOpTime,createdDate",
Required: true,
},
{
Name: "order_direction",
Label: "desc",
Type: "select",
Values: "true,false",
Required: true,
},
}
}
func (c Cloud189) Save(account *model.Account, old *model.Account) error {
if old != nil && old.Name != account.Name {
delete(client189Map, old.Name)
}
if err := c.Login(account); err != nil {
account.Status = err.Error()
_ = model.SaveAccount(account)
return err
}
account.Status = "work"
err := model.SaveAccount(account)
if err != nil {
return err
}
return nil
}
func (c Cloud189) FormatFile(file *Cloud189File) *model.File {
func (driver Cloud189) FormatFile(file *Cloud189File) *model.File {
f := &model.File{
Id: strconv.FormatInt(file.Id, 10),
Name: file.Name,
@ -114,75 +49,6 @@ func (c Cloud189) FormatFile(file *Cloud189File) *model.File {
return f
}
func (c Cloud189) File(path string, account *model.Account) (*model.File, error) {
path = utils.ParsePath(path)
if path == "/" {
return &model.File{
Id: account.RootFolder,
Name: account.Name,
Size: 0,
Type: conf.FOLDER,
Driver: pan123,
UpdatedAt: account.UpdatedAt,
}, nil
}
dir, name := filepath.Split(path)
files, err := c.Files(dir, account)
if err != nil {
return nil, err
}
for _, file := range files {
if file.Name == name {
return &file, nil
}
}
return nil, PathNotFound
}
func (c Cloud189) Files(path string, account *model.Account) ([]model.File, error) {
path = utils.ParsePath(path)
var rawFiles []Cloud189File
cache, err := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path))
if err == nil {
rawFiles, _ = cache.([]Cloud189File)
} else {
file, err := c.File(path, account)
if err != nil {
return nil, err
}
rawFiles, err = c.GetFiles(file.Id, account)
if err != nil {
return nil, err
}
if len(rawFiles) > 0 {
_ = conf.Cache.Set(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path), rawFiles, nil)
}
}
files := make([]model.File, 0)
for _, file := range rawFiles {
files = append(files, *c.FormatFile(&file))
}
return files, nil
}
func (c Cloud189) Path(path string, account *model.Account) (*model.File, []model.File, error) {
path = utils.ParsePath(path)
log.Debugf("189 path: %s", path)
file, err := c.File(path, account)
if err != nil {
return nil, nil, err
}
if file.Type != conf.FOLDER {
file.Url, _ = c.Link(path, account)
return file, nil, nil
}
files, err := c.Files(path, account)
if err != nil {
return nil, nil, err
}
return nil, files, nil
}
//func (c Cloud189) GetFile(path string, account *model.Account) (*Cloud189File, error) {
// dir, name := filepath.Split(path)
// dir = utils.ParsePath(dir)
@ -210,63 +76,8 @@ type Cloud189Down struct {
FileDownloadUrl string `json:"fileDownloadUrl"`
}
func (c Cloud189) Link(path string, account *model.Account) (string, error) {
file, err := c.File(utils.ParsePath(path), account)
if err != nil {
return "", err
}
if file.Type == conf.FOLDER {
return "", NotFile
}
client, ok := client189Map[account.Name]
if !ok {
return "", fmt.Errorf("can't find [%s] client", account.Name)
}
var e Cloud189Error
var resp Cloud189Down
_, err = client.R().SetResult(&resp).SetError(&e).
SetHeader("Accept", "application/json;charset=UTF-8").
SetQueryParams(map[string]string{
"noCache": random(),
"fileId": file.Id,
}).Get("https://cloud.189.cn/api/open/file/getFileDownloadUrl.action")
if err != nil {
return "", err
}
if e.ErrorCode != "" {
if e.ErrorCode == "InvalidSessionKey" {
err = c.Login(account)
if err != nil {
return "", err
}
return c.Link(path, account)
}
}
if resp.ResCode != 0 {
return "", fmt.Errorf(resp.ResMessage)
}
res, err := noRedirectClient.R().Get(resp.FileDownloadUrl)
if err != nil {
return "", err
}
if res.StatusCode() == 302 {
return res.Header().Get("location"), nil
}
return resp.FileDownloadUrl, nil
}
func (c Cloud189) Proxy(ctx *gin.Context, account *model.Account) {
ctx.Request.Header.Del("Origin")
}
func (c Cloud189) Preview(path string, account *model.Account) (interface{}, error) {
return nil, nil
}
var _ Driver = (*Cloud189)(nil)
func init() {
RegisterDriver("189Cloud", &Cloud189{})
drivers.RegisterDriver("189Cloud", &Cloud189{})
client189Map = make(map[string]*resty.Client, 0)
}
@ -277,7 +88,7 @@ type LoginResp struct {
}
// Login refer to PanIndex
func (c Cloud189) Login(account *model.Account) error {
func (driver Cloud189) Login(account *model.Account) error {
client, ok := client189Map[account.Name]
if !ok {
//cookieJar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
@ -394,7 +205,7 @@ type Cloud189Files struct {
} `json:"fileListAO"`
}
func (c Cloud189) GetFiles(fileId string, account *model.Account) ([]Cloud189File, error) {
func (driver Cloud189) GetFiles(fileId string, account *model.Account) ([]Cloud189File, error) {
client, ok := client189Map[account.Name]
if !ok {
return nil, fmt.Errorf("can't find [%s] client", account.Name)
@ -421,11 +232,11 @@ func (c Cloud189) GetFiles(fileId string, account *model.Account) ([]Cloud189Fil
}
if e.ErrorCode != "" {
if e.ErrorCode == "InvalidSessionKey" {
err = c.Login(account)
err = driver.Login(account)
if err != nil {
return nil, err
}
return c.GetFiles(fileId, account)
return driver.GetFiles(fileId, account)
}
}
if resp.ResCode != 0 {

203
drivers/189cloud/driver.go Normal file
View File

@ -0,0 +1,203 @@
package _89cloud
import (
"fmt"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/drivers"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"path/filepath"
)
type Cloud189 struct {}
var driverName = "189Cloud"
func (driver Cloud189) Items() []drivers.Item {
return []drivers.Item{
{
Name: "proxy",
Label: "proxy",
Type: "bool",
Required: true,
Description: "allow proxy",
},
{
Name: "username",
Label: "username",
Type: "string",
Required: true,
Description: "account username/phone number",
},
{
Name: "password",
Label: "password",
Type: "string",
Required: true,
Description: "account password",
},
{
Name: "root_folder",
Label: "root folder file_id",
Type: "string",
Required: true,
},
{
Name: "order_by",
Label: "order_by",
Type: "select",
Values: "name,size,lastOpTime,createdDate",
Required: true,
},
{
Name: "order_direction",
Label: "desc",
Type: "select",
Values: "true,false",
Required: true,
},
}
}
func (driver Cloud189) Save(account *model.Account, old *model.Account) error {
if old != nil && old.Name != account.Name {
delete(client189Map, old.Name)
}
if err := driver.Login(account); err != nil {
account.Status = err.Error()
_ = model.SaveAccount(account)
return err
}
account.Status = "work"
err := model.SaveAccount(account)
if err != nil {
return err
}
return nil
}
func (driver Cloud189) File(path string, account *model.Account) (*model.File, error) {
path = utils.ParsePath(path)
if path == "/" {
return &model.File{
Id: account.RootFolder,
Name: account.Name,
Size: 0,
Type: conf.FOLDER,
Driver: driverName,
UpdatedAt: account.UpdatedAt,
}, nil
}
dir, name := filepath.Split(path)
files, err := driver.Files(dir, account)
if err != nil {
return nil, err
}
for _, file := range files {
if file.Name == name {
return &file, nil
}
}
return nil, drivers.PathNotFound
}
func (driver Cloud189) Files(path string, account *model.Account) ([]model.File, error) {
path = utils.ParsePath(path)
var rawFiles []Cloud189File
cache, err := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path))
if err == nil {
rawFiles, _ = cache.([]Cloud189File)
} else {
file, err := driver.File(path, account)
if err != nil {
return nil, err
}
rawFiles, err = driver.GetFiles(file.Id, account)
if err != nil {
return nil, err
}
if len(rawFiles) > 0 {
_ = conf.Cache.Set(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path), rawFiles, nil)
}
}
files := make([]model.File, 0)
for _, file := range rawFiles {
files = append(files, *driver.FormatFile(&file))
}
return files, nil
}
func (driver Cloud189) Link(path string, account *model.Account) (string, error) {
file, err := driver.File(utils.ParsePath(path), account)
if err != nil {
return "", err
}
if file.Type == conf.FOLDER {
return "", drivers.NotFile
}
client, ok := client189Map[account.Name]
if !ok {
return "", fmt.Errorf("can't find [%s] client", account.Name)
}
var e Cloud189Error
var resp Cloud189Down
_, err = client.R().SetResult(&resp).SetError(&e).
SetHeader("Accept", "application/json;charset=UTF-8").
SetQueryParams(map[string]string{
"noCache": random(),
"fileId": file.Id,
}).Get("https://cloud.189.cn/api/open/file/getFileDownloadUrl.action")
if err != nil {
return "", err
}
if e.ErrorCode != "" {
if e.ErrorCode == "InvalidSessionKey" {
err = driver.Login(account)
if err != nil {
return "", err
}
return driver.Link(path, account)
}
}
if resp.ResCode != 0 {
return "", fmt.Errorf(resp.ResMessage)
}
res, err := drivers.NoRedirectClient.R().Get(resp.FileDownloadUrl)
if err != nil {
return "", err
}
if res.StatusCode() == 302 {
return res.Header().Get("location"), nil
}
return resp.FileDownloadUrl, nil
}
func (driver Cloud189) Path(path string, account *model.Account) (*model.File, []model.File, error) {
path = utils.ParsePath(path)
log.Debugf("189 path: %s", path)
file, err := driver.File(path, account)
if err != nil {
return nil, nil, err
}
if file.Type != conf.FOLDER {
file.Url, _ = driver.Link(path, account)
return file, nil, nil
}
files, err := driver.Files(path, account)
if err != nil {
return nil, nil, err
}
return nil, files, nil
}
func (driver Cloud189) Proxy(ctx *gin.Context, account *model.Account) {
ctx.Request.Header.Del("Origin")
}
func (driver Cloud189) Preview(path string, account *model.Account) (interface{}, error) {
return nil, nil
}
var _ drivers.Driver = (*Cloud189)(nil)

View File

@ -1,394 +0,0 @@
package drivers
import (
"fmt"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/gin-gonic/gin"
"github.com/go-resty/resty/v2"
"github.com/robfig/cron/v3"
log "github.com/sirupsen/logrus"
"path/filepath"
"time"
)
var aliClient = resty.New()
func init() {
RegisterDriver("AliDrive", &AliDrive{})
aliClient.
SetRetryCount(3).
SetHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36").
SetHeader("content-type", "application/json").
SetHeader("origin", "https://aliyundrive.com")
}
type AliDrive struct{}
func (a AliDrive) Preview(path string, account *model.Account) (interface{}, error) {
file, err := a.GetFile(path, account)
if err != nil {
return nil, err
}
// office
var resp Json
var e AliRespError
var url string
req := Json{
"drive_id": account.DriveId,
"file_id": file.FileId,
}
switch file.Category {
case "doc":
{
url = "https://api.aliyundrive.com/v2/file/get_office_preview_url"
req["access_token"] = account.AccessToken
}
case "video":
{
url = "https://api.aliyundrive.com/v2/file/get_video_preview_play_info"
req["category"] = "live_transcoding"
}
default:
return nil, fmt.Errorf("don't support")
}
_, err = aliClient.R().SetResult(&resp).SetError(&e).
SetHeader("authorization", "Bearer\t"+account.AccessToken).
SetBody(req).Post(url)
if err != nil {
return nil, err
}
if e.Code != "" {
return nil, fmt.Errorf("%s", e.Message)
}
return resp, nil
}
func (a AliDrive) Items() []Item {
return []Item{
{
Name: "proxy",
Label: "proxy",
Type: "bool",
Required: true,
Description: "allow proxy",
},
{
Name: "order_by",
Label: "order_by",
Type: "select",
Values: "name,size,updated_at,created_at",
Required: false,
},
{
Name: "order_direction",
Label: "order_direction",
Type: "select",
Values: "ASC,DESC",
Required: false,
},
{
Name: "refresh_token",
Label: "refresh token",
Type: "string",
Required: true,
},
{
Name: "root_folder",
Label: "root folder file_id",
Type: "string",
Required: false,
},
{
Name: "limit",
Label: "limit",
Type: "number",
Required: false,
Description: ">0 and <=200",
},
}
}
func (a AliDrive) Proxy(c *gin.Context, account *model.Account) {
c.Request.Header.Del("Origin")
c.Request.Header.Set("Referer", "https://www.aliyundrive.com/")
}
type AliRespError struct {
Code string `json:"code"`
Message string `json:"message"`
}
type AliFiles struct {
Items []AliFile `json:"items"`
NextMarker string `json:"next_marker"`
}
type AliFile struct {
DriveId string `json:"drive_id"`
CreatedAt *time.Time `json:"created_at"`
FileExtension string `json:"file_extension"`
FileId string `json:"file_id"`
Type string `json:"type"`
Name string `json:"name"`
Category string `json:"category"`
ParentFileId string `json:"parent_file_id"`
UpdatedAt *time.Time `json:"updated_at"`
Size int64 `json:"size"`
Thumbnail string `json:"thumbnail"`
Url string `json:"url"`
}
func (a AliDrive) FormatFile(file *AliFile) *model.File {
f := &model.File{
Name: file.Name,
Size: file.Size,
UpdatedAt: file.UpdatedAt,
Thumbnail: file.Thumbnail,
Driver: "AliDrive",
Url: file.Url,
}
if file.Type == "folder" {
f.Type = conf.FOLDER
} else {
f.Type = utils.GetFileType(file.FileExtension)
}
if file.Category == "video" {
f.Type = conf.VIDEO
}
if file.Category == "image" {
f.Type = conf.IMAGE
}
return f
}
func (a AliDrive) GetFiles(fileId string, account *model.Account) ([]AliFile, error) {
marker := "first"
res := make([]AliFile, 0)
for marker != "" {
if marker == "first" {
marker = ""
}
var resp AliFiles
var e AliRespError
_, err := aliClient.R().
SetResult(&resp).
SetError(&e).
SetHeader("authorization", "Bearer\t"+account.AccessToken).
SetBody(Json{
"drive_id": account.DriveId,
"fields": "*",
"image_thumbnail_process": "image/resize,w_400/format,jpeg",
"image_url_process": "image/resize,w_1920/format,jpeg",
"limit": account.Limit,
"marker": marker,
"order_by": account.OrderBy,
"order_direction": account.OrderDirection,
"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")
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
res = append(res, resp.Items...)
}
return res, nil
}
func (a AliDrive) GetFile(path string, account *model.Account) (*AliFile, error) {
dir, name := filepath.Split(path)
dir = utils.ParsePath(dir)
_, _, err := a.Path(dir, account)
if err != nil {
return nil, err
}
parentFiles_, _ := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, dir))
parentFiles, _ := parentFiles_.([]AliFile)
for _, file := range parentFiles {
if file.Name == name {
if file.Type == "file" {
return &file, err
} else {
return nil, fmt.Errorf("not file")
}
}
}
return nil, fmt.Errorf("path not found")
}
// path: /aaa/bbb
func (a AliDrive) Path(path string, account *model.Account) (*model.File, []model.File, error) {
path = utils.ParsePath(path)
log.Debugf("ali path: %s", path)
cache, err := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path))
if err == nil {
files, _ := cache.([]AliFile)
if len(files) != 0 {
res := make([]model.File, 0)
for _, file := range files {
res = append(res, *a.FormatFile(&file))
}
return nil, res, nil
}
}
// no cache or len(files) == 0
fileId := account.RootFolder
if path != "/" {
dir, name := filepath.Split(path)
dir = utils.ParsePath(dir)
_, _, err = a.Path(dir, account)
if err != nil {
return nil, nil, err
}
parentFiles_, _ := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, dir))
parentFiles, _ := parentFiles_.([]AliFile)
found := false
for _, file := range parentFiles {
if file.Name == name {
found = true
if file.Type == "file" {
url, err := a.Link(path, account)
if err != nil {
return nil, nil, err
}
file.Url = url
return a.FormatFile(&file), nil, nil
} else {
fileId = file.FileId
break
}
}
}
if !found {
return nil, nil, fmt.Errorf("path not found")
}
}
files, err := a.GetFiles(fileId, account)
if err != nil {
return nil, nil, err
}
_ = 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, *a.FormatFile(&file))
}
return nil, res, nil
}
func (a AliDrive) Link(path string, account *model.Account) (string, error) {
file, err := a.GetFile(utils.ParsePath(path), account)
if err != nil {
return "", err
}
var resp Json
var e AliRespError
_, err = aliClient.R().SetResult(&resp).
SetError(&e).
SetHeader("authorization", "Bearer\t"+account.AccessToken).
SetBody(Json{
"drive_id": account.DriveId,
"file_id": file.FileId,
"expire_sec": 14400,
}).Post("https://api.aliyundrive.com/v2/file/get_download_url")
if err != nil {
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
}
func (a AliDrive) RefreshToken(account *model.Account) error {
url := "https://auth.aliyundrive.com/v2/account/token"
var resp TokenResp
var e AliRespError
_, err := aliClient.R().
//ForceContentType("application/json").
SetBody(Json{"refresh_token": account.RefreshToken, "grant_type": "refresh_token"}).
SetResult(&resp).
SetError(&e).
Post(url)
if err != nil {
account.Status = err.Error()
return err
}
log.Debugf("%+v,%+v", resp, e)
if e.Code != "" {
account.Status = e.Message
return fmt.Errorf("failed to refresh token: %s", e.Message)
}else {
account.Status = "work"
}
account.RefreshToken, account.AccessToken = resp.RefreshToken, resp.AccessToken
return nil
}
func (a AliDrive) Save(account *model.Account, old *model.Account) error {
if old != nil {
conf.Cron.Remove(cron.EntryID(old.CronId))
}
if account.RootFolder == "" {
account.RootFolder = "root"
}
if account.Limit == 0 {
account.Limit = 200
}
err := a.RefreshToken(account)
if err != nil {
return err
}
var resp Json
_, _ = aliClient.R().SetResult(&resp).
SetBody("{}").
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)
cronId, err := conf.Cron.AddFunc("@every 2h", func() {
name := account.Name
log.Debugf("ali account name: %s", name)
newAccount, ok := model.GetAccount(name)
log.Debugf("ali account: %+v", newAccount)
if !ok {
return
}
err = a.RefreshToken(&newAccount)
_ = model.SaveAccount(&newAccount)
})
if err != nil {
return err
}
account.CronId = int(cronId)
err = model.SaveAccount(account)
if err != nil {
return err
}
return nil
}
var _ Driver = (*AliDrive)(nil)

View File

@ -0,0 +1,165 @@
package alidrive
import (
"fmt"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/drivers"
"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 aliClient = resty.New()
type AliRespError struct {
Code string `json:"code"`
Message string `json:"message"`
}
type AliFiles struct {
Items []AliFile `json:"items"`
NextMarker string `json:"next_marker"`
}
type AliFile struct {
DriveId string `json:"drive_id"`
CreatedAt *time.Time `json:"created_at"`
FileExtension string `json:"file_extension"`
FileId string `json:"file_id"`
Type string `json:"type"`
Name string `json:"name"`
Category string `json:"category"`
ParentFileId string `json:"parent_file_id"`
UpdatedAt *time.Time `json:"updated_at"`
Size int64 `json:"size"`
Thumbnail string `json:"thumbnail"`
Url string `json:"url"`
}
func (driver AliDrive) FormatFile(file *AliFile) *model.File {
f := &model.File{
Id: file.FileId,
Name: file.Name,
Size: file.Size,
UpdatedAt: file.UpdatedAt,
Thumbnail: file.Thumbnail,
Driver: driverName,
Url: file.Url,
}
if file.Type == "folder" {
f.Type = conf.FOLDER
} else {
f.Type = utils.GetFileType(file.FileExtension)
}
if file.Category == "video" {
f.Type = conf.VIDEO
}
if file.Category == "image" {
f.Type = conf.IMAGE
}
return f
}
func (driver AliDrive) GetFiles(fileId string, account *model.Account) ([]AliFile, error) {
marker := "first"
res := make([]AliFile, 0)
for marker != "" {
if marker == "first" {
marker = ""
}
var resp AliFiles
var e AliRespError
_, err := aliClient.R().
SetResult(&resp).
SetError(&e).
SetHeader("authorization", "Bearer\t"+account.AccessToken).
SetBody(drivers.Json{
"drive_id": account.DriveId,
"fields": "*",
"image_thumbnail_process": "image/resize,w_400/format,jpeg",
"image_url_process": "image/resize,w_1920/format,jpeg",
"limit": account.Limit,
"marker": marker,
"order_by": account.OrderBy,
"order_direction": account.OrderDirection,
"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")
if err != nil {
return nil, err
}
if e.Code != "" {
if e.Code == "AccessTokenInvalid" {
err = driver.RefreshToken(account)
if err != nil {
return nil, err
} else {
_ = model.SaveAccount(account)
return driver.GetFiles(fileId, account)
}
}
return nil, fmt.Errorf("%s", e.Message)
}
marker = resp.NextMarker
res = append(res, resp.Items...)
}
return res, nil
}
func (driver AliDrive) GetFile(path string, account *model.Account) (*AliFile, error) {
dir, name := filepath.Split(path)
_, err := driver.Files(dir, account)
if err != nil {
return nil, err
}
parentFiles_, _ := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, dir))
parentFiles, _ := parentFiles_.([]AliFile)
for _, file := range parentFiles {
if file.Name == name {
if file.Type == "file" {
return &file, err
} else {
return nil, fmt.Errorf("not file")
}
}
}
return nil, drivers.PathNotFound
}
func (driver AliDrive) RefreshToken(account *model.Account) error {
url := "https://auth.aliyundrive.com/v2/account/token"
var resp drivers.TokenResp
var e AliRespError
_, err := aliClient.R().
//ForceContentType("application/json").
SetBody(drivers.Json{"refresh_token": account.RefreshToken, "grant_type": "refresh_token"}).
SetResult(&resp).
SetError(&e).
Post(url)
if err != nil {
account.Status = err.Error()
return err
}
log.Debugf("%+v,%+v", resp, e)
if e.Code != "" {
account.Status = e.Message
return fmt.Errorf("failed to refresh token: %s", e.Message)
} else {
account.Status = "work"
}
account.RefreshToken, account.AccessToken = resp.RefreshToken, resp.AccessToken
return nil
}
func init() {
drivers.RegisterDriver(driverName, &AliDrive{})
aliClient.
SetRetryCount(3).
SetHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36").
SetHeader("content-type", "application/json").
SetHeader("origin", "https://aliyundrive.com")
}

253
drivers/alidrive/driver.go Normal file
View File

@ -0,0 +1,253 @@
package alidrive
import (
"fmt"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/drivers"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/gin-gonic/gin"
"github.com/robfig/cron/v3"
log "github.com/sirupsen/logrus"
"path/filepath"
)
type AliDrive struct{}
var driverName = "AliDrive"
func (driver AliDrive) Items() []drivers.Item {
return []drivers.Item{
{
Name: "proxy",
Label: "proxy",
Type: "bool",
Required: true,
Description: "allow proxy",
},
{
Name: "order_by",
Label: "order_by",
Type: "select",
Values: "name,size,updated_at,created_at",
Required: false,
},
{
Name: "order_direction",
Label: "order_direction",
Type: "select",
Values: "ASC,DESC",
Required: false,
},
{
Name: "refresh_token",
Label: "refresh token",
Type: "string",
Required: true,
},
{
Name: "root_folder",
Label: "root folder file_id",
Type: "string",
Required: false,
},
{
Name: "limit",
Label: "limit",
Type: "number",
Required: false,
Description: ">0 and <=200",
},
}
}
func (driver AliDrive) Save(account *model.Account, old *model.Account) error {
if old != nil {
conf.Cron.Remove(cron.EntryID(old.CronId))
}
if account.RootFolder == "" {
account.RootFolder = "root"
}
if account.Limit == 0 {
account.Limit = 200
}
err := driver.RefreshToken(account)
if err != nil {
return err
}
var resp drivers.Json
_, _ = aliClient.R().SetResult(&resp).
SetBody("{}").
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)
cronId, err := conf.Cron.AddFunc("@every 2h", func() {
name := account.Name
log.Debugf("ali account name: %s", name)
newAccount, ok := model.GetAccount(name)
log.Debugf("ali account: %+v", newAccount)
if !ok {
return
}
err = driver.RefreshToken(&newAccount)
_ = model.SaveAccount(&newAccount)
})
if err != nil {
return err
}
account.CronId = int(cronId)
err = model.SaveAccount(account)
if err != nil {
return err
}
return nil
}
func (driver AliDrive) File(path string, account *model.Account) (*model.File, error) {
path = utils.ParsePath(path)
if path == "/" {
return &model.File{
Id: account.RootFolder,
Name: account.Name,
Size: 0,
Type: conf.FOLDER,
Driver: driverName,
UpdatedAt: account.UpdatedAt,
}, nil
}
dir, name := filepath.Split(path)
files, err := driver.Files(dir, account)
if err != nil {
return nil, err
}
for _, file := range files {
if file.Name == name {
return &file, nil
}
}
return nil, drivers.PathNotFound
}
func (driver AliDrive) Files(path string, account *model.Account) ([]model.File, error) {
path = utils.ParsePath(path)
var rawFiles []AliFile
cache, err := conf.Cache.Get(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path))
if err == nil {
rawFiles, _ = cache.([]AliFile)
} else {
file, err := driver.File(path, account)
if err != nil {
return nil, err
}
rawFiles, err = driver.GetFiles(file.Id, account)
if err != nil {
return nil, err
}
if len(rawFiles) > 0 {
_ = conf.Cache.Set(conf.Ctx, fmt.Sprintf("%s%s", account.Name, path), rawFiles, nil)
}
}
files := make([]model.File, 0)
for _, file := range rawFiles {
files = append(files, *driver.FormatFile(&file))
}
return files, nil
}
func (driver AliDrive) Link(path string, account *model.Account) (string, error) {
file, err := driver.File(path, account)
if err != nil {
return "", err
}
var resp drivers.Json
var e AliRespError
_, err = aliClient.R().SetResult(&resp).
SetError(&e).
SetHeader("authorization", "Bearer\t"+account.AccessToken).
SetBody(drivers.Json{
"drive_id": account.DriveId,
"file_id": file.Id,
"expire_sec": 14400,
}).Post("https://api.aliyundrive.com/v2/file/get_download_url")
if err != nil {
return "", err
}
if e.Code != "" {
if e.Code == "AccessTokenInvalid" {
err = driver.RefreshToken(account)
if err != nil {
return "", err
} else {
_ = model.SaveAccount(account)
return driver.Link(path, account)
}
}
return "", fmt.Errorf("%s", e.Message)
}
return resp["url"].(string), nil
}
func (driver AliDrive) Path(path string, account *model.Account) (*model.File, []model.File, error) {
path = utils.ParsePath(path)
log.Debugf("ali path: %s", path)
file, err := driver.File(path, account)
if err != nil {
return nil, nil, err
}
if file.Type != conf.FOLDER {
file.Url, _ = driver.Link(path, account)
return file, nil, nil
}
files, err := driver.Files(path, account)
if err != nil {
return nil, nil, err
}
return nil, files, nil
}
func (driver AliDrive) Proxy(c *gin.Context, account *model.Account) {
c.Request.Header.Del("Origin")
c.Request.Header.Set("Referer", "https://www.aliyundrive.com/")
}
func (driver AliDrive) Preview(path string, account *model.Account) (interface{}, error) {
file, err := driver.GetFile(path, account)
if err != nil {
return nil, err
}
// office
var resp drivers.Json
var e AliRespError
var url string
req := drivers.Json{
"drive_id": account.DriveId,
"file_id": file.FileId,
}
switch file.Category {
case "doc":
{
url = "https://api.aliyundrive.com/v2/file/get_office_preview_url"
req["access_token"] = account.AccessToken
}
case "video":
{
url = "https://api.aliyundrive.com/v2/file/get_video_preview_play_info"
req["category"] = "live_transcoding"
}
default:
return nil, fmt.Errorf("don't support")
}
_, err = aliClient.R().SetResult(&resp).SetError(&e).
SetHeader("authorization", "Bearer\t"+account.AccessToken).
SetBody(req).Post(url)
if err != nil {
return nil, err
}
if e.Code != "" {
return nil, fmt.Errorf("%s", e.Message)
}
return resp, nil
}
var _ drivers.Driver = (*AliDrive)(nil)

View File

@ -4,16 +4,17 @@ import (
"github.com/Xhofe/alist/model"
"github.com/gin-gonic/gin"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
"net/http"
)
type Driver interface {
Items() []Item
Save(account *model.Account, old *model.Account) error
//File(path string, account *model.Account) (*model.File, error)
//Files(path string, account *model.Account) ([]model.File, error)
Path(path string, account *model.Account) (*model.File, []model.File, error)
File(path string, account *model.Account) (*model.File, error)
Files(path string, account *model.Account) ([]model.File, error)
Link(path string, account *model.Account) (string, error)
Path(path string, account *model.Account) (*model.File, []model.File, error)
Proxy(c *gin.Context, account *model.Account)
Preview(path string, account *model.Account) (interface{}, error)
// TODO
@ -41,6 +42,7 @@ type TokenResp struct {
var driversMap = map[string]Driver{}
func RegisterDriver(name string, driver Driver) {
log.Infof("register driver: [%s]", name)
driversMap[name] = driver
}
@ -59,10 +61,10 @@ func GetDrivers() map[string][]Item {
type Json map[string]interface{}
var noRedirectClient *resty.Client
var NoRedirectClient *resty.Client
func init() {
noRedirectClient = resty.New().SetRedirectPolicy(
NoRedirectClient = resty.New().SetRedirectPolicy(
resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}),

View File

@ -16,6 +16,14 @@ import (
type GoogleDrive struct {
}
func (g GoogleDrive) File(path string, account *model.Account) (*model.File, error) {
panic("implement me")
}
func (g GoogleDrive) Files(path string, account *model.Account) ([]model.File, error) {
panic("implement me")
}
var googleClient = resty.New()
func (g GoogleDrive) Items() []Item {

View File

@ -16,6 +16,14 @@ import (
type Native struct {
}
func (n Native) File(path string, account *model.Account) (*model.File, error) {
panic("implement me")
}
func (n Native) Files(path string, account *model.Account) ([]model.File, error) {
panic("implement me")
}
func (n Native) Preview(path string, account *model.Account) (interface{}, error) {
return nil, fmt.Errorf("no need")
}

View File

@ -15,6 +15,14 @@ import (
type Onedrive struct{}
func (o Onedrive) File(path string, account *model.Account) (*model.File, error) {
panic("implement me")
}
func (o Onedrive) Files(path string, account *model.Account) ([]model.File, error) {
panic("implement me")
}
var oneClient = resty.New()
type OnedriveHost struct {