mirror of https://github.com/Xhofe/alist
feat: add support for lenovonas_share driver (#6921)
parent
87caaf2459
commit
a6bead90d7
|
@ -29,6 +29,7 @@ import (
|
||||||
_ "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/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/local"
|
_ "github.com/alist-org/alist/v3/drivers/local"
|
||||||
_ "github.com/alist-org/alist/v3/drivers/mediatrack"
|
_ "github.com/alist-org/alist/v3/drivers/mediatrack"
|
||||||
_ "github.com/alist-org/alist/v3/drivers/mega"
|
_ "github.com/alist-org/alist/v3/drivers/mega"
|
||||||
|
|
|
@ -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)
|
|
@ -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{}
|
||||||
|
})
|
||||||
|
}
|
|
@ -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"`
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue