alist/drivers/kodbox/driver.go

274 lines
6.7 KiB
Go

package kodbox
import (
"context"
"fmt"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
"net/http"
"path/filepath"
"strings"
"time"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
)
type KodBox struct {
model.Storage
Addition
authorization string
}
func (d *KodBox) Config() driver.Config {
return config
}
func (d *KodBox) GetAddition() driver.Additional {
return &d.Addition
}
func (d *KodBox) Init(ctx context.Context) error {
d.Address = strings.TrimSuffix(d.Address, "/")
d.RootFolderPath = strings.TrimPrefix(utils.FixAndCleanPath(d.RootFolderPath), "/")
return d.getToken()
}
func (d *KodBox) Drop(ctx context.Context) error {
return nil
}
func (d *KodBox) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
var (
resp *CommonResp
listPathData *ListPathData
)
_, err := d.request(http.MethodPost, "/?explorer/list/path", func(req *resty.Request) {
req.SetResult(&resp).SetFormData(map[string]string{
"path": dir.GetPath(),
})
}, true)
if err != nil {
return nil, err
}
dataBytes, err := utils.Json.Marshal(resp.Data)
if err != nil {
return nil, err
}
err = utils.Json.Unmarshal(dataBytes, &listPathData)
if err != nil {
return nil, err
}
FolderAndFiles := append(listPathData.FolderList, listPathData.FileList...)
return utils.SliceConvert(FolderAndFiles, func(f FolderOrFile) (model.Obj, error) {
return &model.ObjThumb{
Object: model.Object{
Path: f.Path,
Name: f.Name,
Ctime: time.Unix(f.CreateTime, 0),
Modified: time.Unix(f.ModifyTime, 0),
Size: f.Size,
IsFolder: f.Type == "folder",
},
//Thumbnail: model.Thumbnail{},
}, nil
})
}
func (d *KodBox) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
path := file.GetPath()
return &model.Link{
URL: fmt.Sprintf("%s/?explorer/index/fileOut&path=%s&download=1&accessToken=%s",
d.Address,
path,
d.authorization)}, nil
}
func (d *KodBox) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {
var resp *CommonResp
newDirPath := filepath.Join(parentDir.GetPath(), dirName)
_, err := d.request(http.MethodPost, "/?explorer/index/mkdir", func(req *resty.Request) {
req.SetResult(&resp).SetFormData(map[string]string{
"path": newDirPath,
})
})
if err != nil {
return nil, err
}
code := resp.Code.(bool)
if !code {
return nil, fmt.Errorf("%s", resp.Data)
}
return &model.ObjThumb{
Object: model.Object{
Path: resp.Info.(string),
Name: dirName,
IsFolder: true,
Modified: time.Now(),
Ctime: time.Now(),
},
}, nil
}
func (d *KodBox) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
var resp *CommonResp
_, err := d.request(http.MethodPost, "/?explorer/index/pathCuteTo", func(req *resty.Request) {
req.SetResult(&resp).SetFormData(map[string]string{
"dataArr": fmt.Sprintf("[{\"path\": \"%s\", \"name\": \"%s\"}]",
srcObj.GetPath(),
srcObj.GetName()),
"path": dstDir.GetPath(),
})
}, true)
if err != nil {
return nil, err
}
code := resp.Code.(bool)
if !code {
return nil, fmt.Errorf("%s", resp.Data)
}
return &model.ObjThumb{
Object: model.Object{
Path: srcObj.GetPath(),
Name: srcObj.GetName(),
IsFolder: srcObj.IsDir(),
Modified: srcObj.ModTime(),
Ctime: srcObj.CreateTime(),
},
}, nil
}
func (d *KodBox) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) {
var resp *CommonResp
_, err := d.request(http.MethodPost, "/?explorer/index/pathRename", func(req *resty.Request) {
req.SetResult(&resp).SetFormData(map[string]string{
"path": srcObj.GetPath(),
"newName": newName,
})
}, true)
if err != nil {
return nil, err
}
code := resp.Code.(bool)
if !code {
return nil, fmt.Errorf("%s", resp.Data)
}
return &model.ObjThumb{
Object: model.Object{
Path: srcObj.GetPath(),
Name: newName,
IsFolder: srcObj.IsDir(),
Modified: time.Now(),
Ctime: srcObj.CreateTime(),
},
}, nil
}
func (d *KodBox) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
var resp *CommonResp
_, err := d.request(http.MethodPost, "/?explorer/index/pathCopyTo", func(req *resty.Request) {
req.SetResult(&resp).SetFormData(map[string]string{
"dataArr": fmt.Sprintf("[{\"path\": \"%s\", \"name\": \"%s\"}]",
srcObj.GetPath(),
srcObj.GetName()),
"path": dstDir.GetPath(),
})
})
if err != nil {
return nil, err
}
code := resp.Code.(bool)
if !code {
return nil, fmt.Errorf("%s", resp.Data)
}
path := resp.Info.([]interface{})[0].(string)
objectName, err := d.getFileOrFolderName(ctx, path)
if err != nil {
return nil, err
}
return &model.ObjThumb{
Object: model.Object{
Path: path,
Name: *objectName,
IsFolder: srcObj.IsDir(),
Modified: time.Now(),
Ctime: time.Now(),
},
}, nil
}
func (d *KodBox) Remove(ctx context.Context, obj model.Obj) error {
var resp *CommonResp
_, err := d.request(http.MethodPost, "/?explorer/index/pathDelete", func(req *resty.Request) {
req.SetResult(&resp).SetFormData(map[string]string{
"dataArr": fmt.Sprintf("[{\"path\": \"%s\", \"name\": \"%s\"}]",
obj.GetPath(),
obj.GetName()),
"shiftDelete": "1",
})
})
if err != nil {
return err
}
code := resp.Code.(bool)
if !code {
return fmt.Errorf("%s", resp.Data)
}
return nil
}
func (d *KodBox) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) {
var resp *CommonResp
_, err := d.request(http.MethodPost, "/?explorer/upload/fileUpload", func(req *resty.Request) {
req.SetFileReader("file", stream.GetName(), stream).
SetResult(&resp).
SetFormData(map[string]string{
"path": dstDir.GetPath(),
})
})
if err != nil {
return nil, err
}
code := resp.Code.(bool)
if !code {
return nil, fmt.Errorf("%s", resp.Data)
}
return &model.ObjThumb{
Object: model.Object{
Path: resp.Info.(string),
Name: stream.GetName(),
Size: stream.GetSize(),
IsFolder: false,
Modified: time.Now(),
Ctime: time.Now(),
},
}, nil
}
func (d *KodBox) getFileOrFolderName(ctx context.Context, path string) (*string, error) {
var resp *CommonResp
_, err := d.request(http.MethodPost, "/?explorer/index/pathInfo", func(req *resty.Request) {
req.SetResult(&resp).SetFormData(map[string]string{
"dataArr": fmt.Sprintf("[{\"path\": \"%s\"}]", path)})
})
if err != nil {
return nil, err
}
code := resp.Code.(bool)
if !code {
return nil, fmt.Errorf("%s", resp.Data)
}
folderOrFileName := resp.Data.(map[string]any)["name"].(string)
return &folderOrFileName, nil
}
var _ driver.Driver = (*KodBox)(nil)