feat: add WoPan driver (close #4541)

This commit is contained in:
Andy Hsu
2023-06-17 20:20:00 +08:00
parent 378bab32f1
commit f7baec2e65
7 changed files with 290 additions and 34 deletions

161
drivers/wopan/driver.go Normal file
View File

@ -0,0 +1,161 @@
package template
import (
"context"
"fmt"
"github.com/Xhofe/wopan-sdk-go"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
)
type Wopan struct {
model.Storage
Addition
client *wopan.WoClient
}
func (d *Wopan) Config() driver.Config {
return config
}
func (d *Wopan) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Wopan) Init(ctx context.Context) error {
d.client = wopan.DefaultWithRefreshToken(d.RefreshToken)
d.client.SetAccessToken(d.AccessToken)
d.client.OnRefreshToken(func(accessToken, refreshToken string) {
d.AccessToken = accessToken
d.RefreshToken = refreshToken
op.MustSaveDriverStorage(d)
})
return d.client.InitData()
}
func (d *Wopan) Drop(ctx context.Context) error {
return nil
}
func (d *Wopan) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
var res []model.Obj
pageNum := 0
pageSize := 100
for {
data, err := d.client.QueryAllFiles(d.getSpaceType(), dir.GetID(), pageNum, pageSize, 0, d.FamilyID, func(req *resty.Request) {
req.SetContext(ctx)
})
if err != nil {
return nil, err
}
objs, err := utils.SliceConvert(data.Files, fileToObj)
if err != nil {
return nil, err
}
res = append(res, objs...)
if len(data.Files) < pageSize {
break
}
pageNum++
}
return res, nil
}
func (d *Wopan) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
if f, ok := file.(*Object); ok {
res, err := d.client.GetDownloadUrlV2([]string{f.FID}, func(req *resty.Request) {
req.SetContext(ctx)
})
if err != nil {
return nil, err
}
return &model.Link{
URL: res.List[0].DownloadUrl,
}, nil
}
return nil, fmt.Errorf("unable to convert file to Object")
}
func (d *Wopan) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
_, err := d.client.CreateDirectory(d.getSpaceType(), parentDir.GetID(), dirName, d.FamilyID, func(req *resty.Request) {
req.SetContext(ctx)
})
return err
}
func (d *Wopan) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
dirList := make([]string, 0)
fileList := make([]string, 0)
if srcObj.IsDir() {
dirList = append(dirList, srcObj.GetID())
} else {
fileList = append(fileList, srcObj.GetID())
}
return d.client.MoveFile(dirList, fileList, dstDir.GetID(),
d.getSpaceType(), d.getSpaceType(),
d.FamilyID, d.FamilyID, func(req *resty.Request) {
req.SetContext(ctx)
})
}
func (d *Wopan) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
_type := 1
if srcObj.IsDir() {
_type = 0
}
return d.client.RenameFileOrDirectory(d.getSpaceType(), _type, srcObj.GetID(), newName, d.FamilyID, func(req *resty.Request) {
req.SetContext(ctx)
})
}
func (d *Wopan) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
dirList := make([]string, 0)
fileList := make([]string, 0)
if srcObj.IsDir() {
dirList = append(dirList, srcObj.GetID())
} else {
fileList = append(fileList, srcObj.GetID())
}
return d.client.CopyFile(dirList, fileList, dstDir.GetID(),
d.getSpaceType(), d.getSpaceType(),
d.FamilyID, d.FamilyID, func(req *resty.Request) {
req.SetContext(ctx)
})
}
func (d *Wopan) Remove(ctx context.Context, obj model.Obj) error {
dirList := make([]string, 0)
fileList := make([]string, 0)
if obj.IsDir() {
dirList = append(dirList, obj.GetID())
} else {
fileList = append(fileList, obj.GetID())
}
return d.client.DeleteFile(d.getSpaceType(), dirList, fileList, func(req *resty.Request) {
req.SetContext(ctx)
})
}
func (d *Wopan) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
_, err := d.client.Upload2C(d.getSpaceType(), wopan.Upload2CFile{
Name: stream.GetName(),
Size: stream.GetSize(),
Content: stream,
ContentType: stream.GetMimetype(),
}, dstDir.GetID(), d.FamilyID, wopan.Upload2COption{
OnProgress: func(current, total int64) {
up(int(100 * current / total))
},
})
return err
}
//func (d *Wopan) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
// return nil, errs.NotSupport
//}
var _ driver.Driver = (*Wopan)(nil)

37
drivers/wopan/meta.go Normal file
View File

@ -0,0 +1,37 @@
package template
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
// Usually one of two
driver.RootID
// define other
RefreshToken string `json:"refresh_token" required:"true"`
FamilyID string `json:"family_id" help:"Keep it empty if you want to use your personal drive"`
SortRule string `json:"sort_rule" type:"select" options:"name_asc,name_desc,time_asc,time_desc,size_asc,size_desc" default:"name_asc"`
AccessToken string `json:"access_token"`
}
var config = driver.Config{
Name: "WoPan",
LocalSort: false,
OnlyLocal: false,
OnlyProxy: false,
NoCache: false,
NoUpload: false,
NeedMs: false,
DefaultRoot: "0",
CheckStatus: false,
Alert: "",
NoOverwriteUpload: true,
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Wopan{}
})
}

34
drivers/wopan/types.go Normal file
View File

@ -0,0 +1,34 @@
package template
import (
"github.com/Xhofe/wopan-sdk-go"
"github.com/alist-org/alist/v3/internal/model"
)
type Object struct {
model.ObjThumb
FID string
}
func fileToObj(file wopan.File) (model.Obj, error) {
t, err := getTime(file.CreateTime)
if err != nil {
return nil, err
}
return &Object{
ObjThumb: model.ObjThumb{
Object: model.Object{
ID: file.Id,
//Path: "",
Name: file.Name,
Size: file.Size,
Modified: t,
IsFolder: file.Type == 0,
},
Thumbnail: model.Thumbnail{
Thumbnail: file.ThumbUrl,
},
},
FID: file.Fid,
}, nil
}

40
drivers/wopan/util.go Normal file
View File

@ -0,0 +1,40 @@
package template
import (
"time"
"github.com/Xhofe/wopan-sdk-go"
)
// do others that not defined in Driver interface
func (d *Wopan) getSortRule() int {
switch d.SortRule {
case "name_asc":
return wopan.SortNameAsc
case "name_desc":
return wopan.SortNameDesc
case "time_asc":
return wopan.SortTimeAsc
case "time_desc":
return wopan.SortTimeDesc
case "size_asc":
return wopan.SortSizeAsc
case "size_desc":
return wopan.SortSizeDesc
default:
return wopan.SortNameAsc
}
}
func (d *Wopan) getSpaceType() string {
if d.FamilyID == "" {
return wopan.SpaceTypePersonal
}
return wopan.SpaceTypeFamily
}
// 20230607214351
func getTime(str string) (time.Time, error) {
return time.Parse("20060102150405", str)
}