mirror of https://github.com/Xhofe/alist
- kodbox: https://github.com/kalcaddle/kodboxrenovate/github.com-meilisearch-meilisearch-go-0.x
parent
34b6785fab
commit
d2514d236f
|
@ -28,6 +28,7 @@ import (
|
||||||
_ "github.com/alist-org/alist/v3/drivers/halalcloud"
|
_ "github.com/alist-org/alist/v3/drivers/halalcloud"
|
||||||
_ "github.com/alist-org/alist/v3/drivers/ilanzou"
|
_ "github.com/alist-org/alist/v3/drivers/ilanzou"
|
||||||
_ "github.com/alist-org/alist/v3/drivers/ipfs_api"
|
_ "github.com/alist-org/alist/v3/drivers/ipfs_api"
|
||||||
|
_ "github.com/alist-org/alist/v3/drivers/kodbox"
|
||||||
_ "github.com/alist-org/alist/v3/drivers/lanzou"
|
_ "github.com/alist-org/alist/v3/drivers/lanzou"
|
||||||
_ "github.com/alist-org/alist/v3/drivers/lenovonas_share"
|
_ "github.com/alist-org/alist/v3/drivers/lenovonas_share"
|
||||||
_ "github.com/alist-org/alist/v3/drivers/local"
|
_ "github.com/alist-org/alist/v3/drivers/local"
|
||||||
|
|
|
@ -0,0 +1,273 @@
|
||||||
|
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)
|
|
@ -0,0 +1,25 @@
|
||||||
|
package kodbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
|
"github.com/alist-org/alist/v3/internal/op"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Addition struct {
|
||||||
|
driver.RootPath
|
||||||
|
|
||||||
|
Address string `json:"address" required:"true"`
|
||||||
|
UserName string `json:"username" required:"false"`
|
||||||
|
Password string `json:"password" required:"false"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = driver.Config{
|
||||||
|
Name: "KodBox",
|
||||||
|
DefaultRoot: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
op.RegisterDriver(func() driver.Driver {
|
||||||
|
return &KodBox{}
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package kodbox
|
||||||
|
|
||||||
|
type CommonResp struct {
|
||||||
|
Code any `json:"code"`
|
||||||
|
TimeUse string `json:"timeUse"`
|
||||||
|
TimeNow string `json:"timeNow"`
|
||||||
|
Data any `json:"data"`
|
||||||
|
Info any `json:"info"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListPathData struct {
|
||||||
|
FolderList []FolderOrFile `json:"folderList"`
|
||||||
|
FileList []FolderOrFile `json:"fileList"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FolderOrFile struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Ext string `json:"ext,omitempty"` // 文件特有字段
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
CreateTime int64 `json:"createTime"`
|
||||||
|
ModifyTime int64 `json:"modifyTime"`
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package kodbox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/alist-org/alist/v3/drivers/base"
|
||||||
|
"github.com/alist-org/alist/v3/pkg/utils"
|
||||||
|
"github.com/go-resty/resty/v2"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (d *KodBox) getToken() error {
|
||||||
|
var authResp CommonResp
|
||||||
|
res, err := base.RestyClient.R().
|
||||||
|
SetResult(&authResp).
|
||||||
|
SetQueryParams(map[string]string{
|
||||||
|
"name": d.UserName,
|
||||||
|
"password": d.Password,
|
||||||
|
}).
|
||||||
|
Post(d.Address + "/?user/index/loginSubmit")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if res.StatusCode() >= 400 {
|
||||||
|
return fmt.Errorf("get token failed: %s", res.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.StatusCode() == 200 && authResp.Code.(bool) == false {
|
||||||
|
return fmt.Errorf("get token failed: %s", res.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
d.authorization = fmt.Sprintf("%s", authResp.Info)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *KodBox) request(method string, pathname string, callback base.ReqCallback, noRedirect ...bool) ([]byte, error) {
|
||||||
|
full := pathname
|
||||||
|
if !strings.HasPrefix(pathname, "http") {
|
||||||
|
full = d.Address + pathname
|
||||||
|
}
|
||||||
|
req := base.RestyClient.R()
|
||||||
|
if len(noRedirect) > 0 && noRedirect[0] {
|
||||||
|
req = base.NoRedirectClient.R()
|
||||||
|
}
|
||||||
|
req.SetFormData(map[string]string{
|
||||||
|
"accessToken": d.authorization,
|
||||||
|
})
|
||||||
|
callback(req)
|
||||||
|
|
||||||
|
var (
|
||||||
|
res *resty.Response
|
||||||
|
commonResp *CommonResp
|
||||||
|
err error
|
||||||
|
skip bool
|
||||||
|
)
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
if skip {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
res, err = req.Execute(method, full)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err := utils.Json.Unmarshal(res.Body(), &commonResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch commonResp.Code.(type) {
|
||||||
|
case bool:
|
||||||
|
skip = true
|
||||||
|
case string:
|
||||||
|
if commonResp.Code.(string) == "10001" {
|
||||||
|
err = d.getToken()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.SetFormData(map[string]string{"accessToken": d.authorization})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if commonResp.Code.(bool) == false {
|
||||||
|
return nil, fmt.Errorf("request failed: %s", commonResp.Data)
|
||||||
|
}
|
||||||
|
return res.Body(), nil
|
||||||
|
}
|
Loading…
Reference in New Issue