Spaces:
Runtime error
Runtime error
package alist_v3 | |
import ( | |
"context" | |
"fmt" | |
"io" | |
"net/http" | |
"path" | |
"strconv" | |
"strings" | |
"time" | |
"github.com/alist-org/alist/v3/drivers/base" | |
"github.com/alist-org/alist/v3/internal/conf" | |
"github.com/alist-org/alist/v3/internal/driver" | |
"github.com/alist-org/alist/v3/internal/model" | |
"github.com/alist-org/alist/v3/pkg/utils" | |
"github.com/alist-org/alist/v3/server/common" | |
"github.com/go-resty/resty/v2" | |
) | |
type AListV3 struct { | |
model.Storage | |
Addition | |
} | |
func (d *AListV3) Config() driver.Config { | |
return config | |
} | |
func (d *AListV3) GetAddition() driver.Additional { | |
return &d.Addition | |
} | |
func (d *AListV3) Init(ctx context.Context) error { | |
d.Addition.Address = strings.TrimSuffix(d.Addition.Address, "/") | |
var resp common.Resp[MeResp] | |
_, err := d.request("/me", http.MethodGet, func(req *resty.Request) { | |
req.SetResult(&resp) | |
}) | |
if err != nil { | |
return err | |
} | |
// if the username is not empty and the username is not the same as the current username, then login again | |
if d.Username != "" && d.Username != resp.Data.Username { | |
err = d.login() | |
if err != nil { | |
return err | |
} | |
} | |
// re-get the user info | |
_, err = d.request("/me", http.MethodGet, func(req *resty.Request) { | |
req.SetResult(&resp) | |
}) | |
if err != nil { | |
return err | |
} | |
if resp.Data.Role == model.GUEST { | |
url := d.Address + "/api/public/settings" | |
res, err := base.RestyClient.R().Get(url) | |
if err != nil { | |
return err | |
} | |
allowMounted := utils.Json.Get(res.Body(), "data", conf.AllowMounted).ToString() == "true" | |
if !allowMounted { | |
return fmt.Errorf("the site does not allow mounted") | |
} | |
} | |
return err | |
} | |
func (d *AListV3) Drop(ctx context.Context) error { | |
return nil | |
} | |
func (d *AListV3) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { | |
var resp common.Resp[FsListResp] | |
_, err := d.request("/fs/list", http.MethodPost, func(req *resty.Request) { | |
req.SetResult(&resp).SetBody(ListReq{ | |
PageReq: model.PageReq{ | |
Page: 1, | |
PerPage: 0, | |
}, | |
Path: dir.GetPath(), | |
Password: d.MetaPassword, | |
Refresh: false, | |
}) | |
}) | |
if err != nil { | |
return nil, err | |
} | |
var files []model.Obj | |
for _, f := range resp.Data.Content { | |
file := model.ObjThumb{ | |
Object: model.Object{ | |
Name: f.Name, | |
Modified: f.Modified, | |
Ctime: f.Created, | |
Size: f.Size, | |
IsFolder: f.IsDir, | |
HashInfo: utils.FromString(f.HashInfo), | |
}, | |
Thumbnail: model.Thumbnail{Thumbnail: f.Thumb}, | |
} | |
files = append(files, &file) | |
} | |
return files, nil | |
} | |
func (d *AListV3) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { | |
var resp common.Resp[FsGetResp] | |
_, err := d.request("/fs/get", http.MethodPost, func(req *resty.Request) { | |
req.SetResult(&resp).SetBody(FsGetReq{ | |
Path: file.GetPath(), | |
Password: d.MetaPassword, | |
}) | |
}) | |
if err != nil { | |
return nil, err | |
} | |
return &model.Link{ | |
URL: resp.Data.RawURL, | |
}, nil | |
} | |
func (d *AListV3) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error { | |
_, err := d.request("/fs/mkdir", http.MethodPost, func(req *resty.Request) { | |
req.SetBody(MkdirOrLinkReq{ | |
Path: path.Join(parentDir.GetPath(), dirName), | |
}) | |
}) | |
return err | |
} | |
func (d *AListV3) Move(ctx context.Context, srcObj, dstDir model.Obj) error { | |
_, err := d.request("/fs/move", http.MethodPost, func(req *resty.Request) { | |
req.SetBody(MoveCopyReq{ | |
SrcDir: path.Dir(srcObj.GetPath()), | |
DstDir: dstDir.GetPath(), | |
Names: []string{srcObj.GetName()}, | |
}) | |
}) | |
return err | |
} | |
func (d *AListV3) Rename(ctx context.Context, srcObj model.Obj, newName string) error { | |
_, err := d.request("/fs/rename", http.MethodPost, func(req *resty.Request) { | |
req.SetBody(RenameReq{ | |
Path: srcObj.GetPath(), | |
Name: newName, | |
}) | |
}) | |
return err | |
} | |
func (d *AListV3) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { | |
_, err := d.request("/fs/copy", http.MethodPost, func(req *resty.Request) { | |
req.SetBody(MoveCopyReq{ | |
SrcDir: path.Dir(srcObj.GetPath()), | |
DstDir: dstDir.GetPath(), | |
Names: []string{srcObj.GetName()}, | |
}) | |
}) | |
return err | |
} | |
func (d *AListV3) Remove(ctx context.Context, obj model.Obj) error { | |
_, err := d.request("/fs/remove", http.MethodPost, func(req *resty.Request) { | |
req.SetBody(RemoveReq{ | |
Dir: path.Dir(obj.GetPath()), | |
Names: []string{obj.GetName()}, | |
}) | |
}) | |
return err | |
} | |
func (d *AListV3) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error { | |
_, err := d.requestWithTimeout("/fs/put", http.MethodPut, func(req *resty.Request) { | |
req.SetHeader("File-Path", path.Join(dstDir.GetPath(), stream.GetName())). | |
SetHeader("Password", d.MetaPassword). | |
SetHeader("Content-Length", strconv.FormatInt(stream.GetSize(), 10)). | |
SetContentLength(true). | |
SetBody(io.ReadCloser(stream)) | |
}, time.Hour*6) | |
return err | |
} | |
//func (d *AList) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) { | |
// return nil, errs.NotSupport | |
//} | |
var _ driver.Driver = (*AListV3)(nil) | |