|
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", |
|
}, |
|
|
|
}, 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) |
|
|