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/ilanzou"
|
||||
_ "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/lenovonas_share"
|
||||
_ "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