diff --git a/drivers/all.go b/drivers/all.go index 2cb01d748b0..b976f92f2a6 100644 --- a/drivers/all.go +++ b/drivers/all.go @@ -29,6 +29,7 @@ import ( _ "github.com/alist-org/alist/v3/drivers/ilanzou" _ "github.com/alist-org/alist/v3/drivers/ipfs_api" _ "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" _ "github.com/alist-org/alist/v3/drivers/mediatrack" _ "github.com/alist-org/alist/v3/drivers/mega" diff --git a/drivers/lenovonas_share/driver.go b/drivers/lenovonas_share/driver.go new file mode 100644 index 00000000000..12e8514325f --- /dev/null +++ b/drivers/lenovonas_share/driver.go @@ -0,0 +1,121 @@ +package LenovoNasShare + +import ( + "context" + "net/http" + + "github.com/go-resty/resty/v2" + + "github.com/alist-org/alist/v3/internal/driver" + "github.com/alist-org/alist/v3/internal/errs" + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/pkg/utils" +) + +type LenovoNasShare struct { + model.Storage + Addition + stoken string +} + +func (d *LenovoNasShare) Config() driver.Config { + return config +} + +func (d *LenovoNasShare) GetAddition() driver.Additional { + return &d.Addition +} + +func (d *LenovoNasShare) Init(ctx context.Context) error { + if d.Host == "" { + d.Host = "https://siot-share.lenovo.com.cn" + } + query := map[string]string{ + "code": d.ShareId, + "password": d.SharePwd, + } + resp, err := d.request(d.Host+"/oneproxy/api/share/v1/access", http.MethodGet, func(req *resty.Request) { + req.SetQueryParams(query) + }, nil) + if err != nil { + return err + } + d.stoken = utils.Json.Get(resp, "data", "stoken").ToString() + return nil +} + +func (d *LenovoNasShare) Drop(ctx context.Context) error { + return nil +} + +func (d *LenovoNasShare) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { + files := make([]File, 0) + + var resp Files + query := map[string]string{ + "code": d.ShareId, + "num": "5000", + "stoken": d.stoken, + "path": dir.GetPath(), + } + _, err := d.request(d.Host+"/oneproxy/api/share/v1/files", http.MethodGet, func(req *resty.Request) { + req.SetQueryParams(query) + }, &resp) + if err != nil { + return nil, err + } + files = append(files, resp.Data.List...) + + return utils.SliceConvert(files, func(src File) (model.Obj, error) { + return src, nil + }) +} + +func (d *LenovoNasShare) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { + query := map[string]string{ + "code": d.ShareId, + "stoken": d.stoken, + "path": file.GetPath(), + } + resp, err := d.request(d.Host+"/oneproxy/api/share/v1/file/link", http.MethodGet, func(req *resty.Request) { + req.SetQueryParams(query) + }, nil) + if err != nil { + return nil, err + } + downloadUrl := d.Host + "/oneproxy/api/share/v1/file/download?code=" + d.ShareId + "&dtoken=" + utils.Json.Get(resp, "data", "param", "dtoken").ToString() + + link := model.Link{ + URL: downloadUrl, + Header: http.Header{ + "Referer": []string{"https://siot-share.lenovo.com.cn"}, + }, + } + return &link, nil +} + +func (d *LenovoNasShare) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) { + return nil, errs.NotImplement +} + +func (d *LenovoNasShare) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { + return nil, errs.NotImplement +} + +func (d *LenovoNasShare) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) { + return nil, errs.NotImplement +} + +func (d *LenovoNasShare) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { + return nil, errs.NotImplement +} + +func (d *LenovoNasShare) Remove(ctx context.Context, obj model.Obj) error { + return errs.NotImplement +} + +func (d *LenovoNasShare) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) { + return nil, errs.NotImplement +} + +var _ driver.Driver = (*LenovoNasShare)(nil) diff --git a/drivers/lenovonas_share/meta.go b/drivers/lenovonas_share/meta.go new file mode 100644 index 00000000000..0bf80555739 --- /dev/null +++ b/drivers/lenovonas_share/meta.go @@ -0,0 +1,33 @@ +package LenovoNasShare + +import ( + "github.com/alist-org/alist/v3/internal/driver" + "github.com/alist-org/alist/v3/internal/op" +) + +type Addition struct { + driver.RootPath + ShareId string `json:"share_id" required:"true" help:"The part after the last / in the shared link"` + SharePwd string `json:"share_pwd" required:"true" help:"The password of the shared link"` + Host string `json:"host" required:"true" default:"https://siot-share.lenovo.com.cn" help:"You can change it to your local area network"` +} + +var config = driver.Config{ + Name: "LenovoNasShare", + LocalSort: true, + OnlyLocal: false, + OnlyProxy: false, + NoCache: false, + NoUpload: true, + NeedMs: false, + DefaultRoot: "", + CheckStatus: false, + Alert: "", + NoOverwriteUpload: false, +} + +func init() { + op.RegisterDriver(func() driver.Driver { + return &LenovoNasShare{} + }) +} diff --git a/drivers/lenovonas_share/types.go b/drivers/lenovonas_share/types.go new file mode 100644 index 00000000000..77b966d3bee --- /dev/null +++ b/drivers/lenovonas_share/types.go @@ -0,0 +1,82 @@ +package LenovoNasShare + +import ( + "encoding/json" + "time" + + "github.com/alist-org/alist/v3/pkg/utils" + + _ "github.com/alist-org/alist/v3/internal/model" +) + +func (f *File) UnmarshalJSON(data []byte) error { + type Alias File + aux := &struct { + CreateAt int64 `json:"time"` + UpdateAt int64 `json:"chtime"` + *Alias + }{ + Alias: (*Alias)(f), + } + + if err := json.Unmarshal(data, aux); err != nil { + return err + } + + f.CreateAt = time.Unix(aux.CreateAt, 0) + f.UpdateAt = time.Unix(aux.UpdateAt, 0) + + return nil +} + +type File struct { + FileName string `json:"name"` + Size int64 `json:"size"` + CreateAt time.Time `json:"time"` + UpdateAt time.Time `json:"chtime"` + Path string `json:"path"` + Type string `json:"type"` +} + +func (f File) GetHash() utils.HashInfo { + return utils.HashInfo{} +} + +func (f File) GetPath() string { + return f.Path +} + +func (f File) GetSize() int64 { + return f.Size +} + +func (f File) GetName() string { + return f.FileName +} + +func (f File) ModTime() time.Time { + return f.UpdateAt +} + +func (f File) CreateTime() time.Time { + return f.CreateAt +} + +func (f File) IsDir() bool { + return f.Type == "dir" +} + +func (f File) GetID() string { + return f.GetPath() +} + +func (f File) Thumb() string { + return "" +} + +type Files struct { + Data struct { + List []File `json:"list"` + HasMore bool `json:"has_more"` + } `json:"data"` +} diff --git a/drivers/lenovonas_share/util.go b/drivers/lenovonas_share/util.go new file mode 100644 index 00000000000..ccf3af042a4 --- /dev/null +++ b/drivers/lenovonas_share/util.go @@ -0,0 +1,36 @@ +package LenovoNasShare + +import ( + "errors" + + "github.com/alist-org/alist/v3/drivers/base" + "github.com/alist-org/alist/v3/pkg/utils" + jsoniter "github.com/json-iterator/go" +) + +func (d *LenovoNasShare) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) { + req := base.RestyClient.R() + req.SetHeaders(map[string]string{ + "origin": "https://siot-share.lenovo.com.cn", + "referer": "https://siot-share.lenovo.com.cn/", + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) alist-client", + "platform": "web", + "app-version": "3", + }) + if callback != nil { + callback(req) + } + if resp != nil { + req.SetResult(resp) + } + res, err := req.Execute(method, url) + if err != nil { + return nil, err + } + body := res.Body() + result := utils.Json.Get(body, "result").ToBool() + if !result { + return nil, errors.New(jsoniter.Get(body, "error", "msg").ToString()) + } + return body, nil +}