|
package baidu_share |
|
|
|
import ( |
|
"context" |
|
"encoding/json" |
|
"fmt" |
|
"io" |
|
"net/http" |
|
"net/url" |
|
"path" |
|
"time" |
|
|
|
"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/go-resty/resty/v2" |
|
) |
|
|
|
type BaiduShare struct { |
|
model.Storage |
|
Addition |
|
client *resty.Client |
|
info struct { |
|
Root string |
|
Seckey string |
|
Shareid string |
|
Uk string |
|
} |
|
} |
|
|
|
func (d *BaiduShare) Config() driver.Config { |
|
return config |
|
} |
|
|
|
func (d *BaiduShare) GetAddition() driver.Additional { |
|
return &d.Addition |
|
} |
|
|
|
func (d *BaiduShare) Init(ctx context.Context) error { |
|
|
|
|
|
d.client = resty.New(). |
|
SetBaseURL("https://pan.baidu.com"). |
|
SetHeader("User-Agent", "netdisk"). |
|
SetCookie(&http.Cookie{Name: "BDUSS", Value: d.BDUSS}). |
|
SetCookie(&http.Cookie{Name: "ndut_fmt"}) |
|
respJson := struct { |
|
Errno int64 `json:"errno"` |
|
Data struct { |
|
List [1]struct { |
|
Path string `json:"path"` |
|
} `json:"list"` |
|
Uk json.Number `json:"uk"` |
|
Shareid json.Number `json:"shareid"` |
|
Seckey string `json:"seckey"` |
|
} `json:"data"` |
|
}{} |
|
resp, err := d.client.R(). |
|
SetBody(url.Values{ |
|
"pwd": {d.Pwd}, |
|
"root": {"1"}, |
|
"shorturl": {d.Surl}, |
|
}.Encode()). |
|
SetResult(&respJson). |
|
Post("share/wxlist?channel=weixin&version=2.2.2&clienttype=25&web=1") |
|
if err == nil { |
|
if resp.IsSuccess() && respJson.Errno == 0 { |
|
d.info.Root = path.Dir(respJson.Data.List[0].Path) |
|
d.info.Seckey = respJson.Data.Seckey |
|
d.info.Shareid = respJson.Data.Shareid.String() |
|
d.info.Uk = respJson.Data.Uk.String() |
|
} else { |
|
err = fmt.Errorf(" %s; %s; ", resp.Status(), resp.Body()) |
|
} |
|
} |
|
return err |
|
} |
|
|
|
func (d *BaiduShare) Drop(ctx context.Context) error { |
|
return nil |
|
} |
|
|
|
func (d *BaiduShare) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { |
|
|
|
reqDir := dir.GetPath() |
|
isRoot := "0" |
|
if reqDir == d.RootFolderPath { |
|
reqDir = path.Join(d.info.Root, reqDir) |
|
} |
|
if reqDir == d.info.Root { |
|
isRoot = "1" |
|
} |
|
objs := []model.Obj{} |
|
var err error |
|
var page uint64 = 1 |
|
more := true |
|
for more && err == nil { |
|
respJson := struct { |
|
Errno int64 `json:"errno"` |
|
Data struct { |
|
More bool `json:"has_more"` |
|
List []struct { |
|
Fsid json.Number `json:"fs_id"` |
|
Isdir json.Number `json:"isdir"` |
|
Path string `json:"path"` |
|
Name string `json:"server_filename"` |
|
Mtime json.Number `json:"server_mtime"` |
|
Size json.Number `json:"size"` |
|
} `json:"list"` |
|
} `json:"data"` |
|
}{} |
|
resp, e := d.client.R(). |
|
SetBody(url.Values{ |
|
"dir": {reqDir}, |
|
"num": {"1000"}, |
|
"order": {"time"}, |
|
"page": {fmt.Sprint(page)}, |
|
"pwd": {d.Pwd}, |
|
"root": {isRoot}, |
|
"shorturl": {d.Surl}, |
|
}.Encode()). |
|
SetResult(&respJson). |
|
Post("share/wxlist?channel=weixin&version=2.2.2&clienttype=25&web=1") |
|
err = e |
|
if err == nil { |
|
if resp.IsSuccess() && respJson.Errno == 0 { |
|
page++ |
|
more = respJson.Data.More |
|
for _, v := range respJson.Data.List { |
|
size, _ := v.Size.Int64() |
|
mtime, _ := v.Mtime.Int64() |
|
objs = append(objs, &model.Object{ |
|
ID: v.Fsid.String(), |
|
Path: v.Path, |
|
Name: v.Name, |
|
Size: size, |
|
Modified: time.Unix(mtime, 0), |
|
IsFolder: v.Isdir.String() == "1", |
|
}) |
|
} |
|
} else { |
|
err = fmt.Errorf(" %s; %s; ", resp.Status(), resp.Body()) |
|
} |
|
} |
|
} |
|
return objs, err |
|
} |
|
|
|
func (d *BaiduShare) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { |
|
|
|
link := model.Link{Header: d.client.Header} |
|
sign := "" |
|
stamp := "" |
|
signJson := struct { |
|
Errno int64 `json:"errno"` |
|
Data struct { |
|
Stamp json.Number `json:"timestamp"` |
|
Sign string `json:"sign"` |
|
} `json:"data"` |
|
}{} |
|
resp, err := d.client.R(). |
|
SetQueryParam("surl", d.Surl). |
|
SetResult(&signJson). |
|
Get("share/tplconfig?fields=sign,timestamp&channel=chunlei&web=1&app_id=250528&clienttype=0") |
|
if err == nil { |
|
if resp.IsSuccess() && signJson.Errno == 0 { |
|
stamp = signJson.Data.Stamp.String() |
|
sign = signJson.Data.Sign |
|
} else { |
|
err = fmt.Errorf(" %s; %s; ", resp.Status(), resp.Body()) |
|
} |
|
} |
|
if err == nil { |
|
respJson := struct { |
|
Errno int64 `json:"errno"` |
|
List [1]struct { |
|
Dlink string `json:"dlink"` |
|
} `json:"list"` |
|
}{} |
|
resp, err = d.client.R(). |
|
SetQueryParam("sign", sign). |
|
SetQueryParam("timestamp", stamp). |
|
SetBody(url.Values{ |
|
"encrypt": {"0"}, |
|
"extra": {fmt.Sprintf(`{"sekey":"%s"}`, d.info.Seckey)}, |
|
"fid_list": {fmt.Sprintf("[%s]", file.GetID())}, |
|
"primaryid": {d.info.Shareid}, |
|
"product": {"share"}, |
|
"type": {"nolimit"}, |
|
"uk": {d.info.Uk}, |
|
}.Encode()). |
|
SetResult(&respJson). |
|
Post("api/sharedownload?app_id=250528&channel=chunlei&clienttype=12&web=1") |
|
if err == nil { |
|
if resp.IsSuccess() && respJson.Errno == 0 && respJson.List[0].Dlink != "" { |
|
link.URL = respJson.List[0].Dlink |
|
} else { |
|
err = fmt.Errorf(" %s; %s; ", resp.Status(), resp.Body()) |
|
} |
|
} |
|
if err == nil { |
|
resp, err = d.client.R(). |
|
SetDoNotParseResponse(true). |
|
Get(link.URL) |
|
if err == nil { |
|
defer resp.RawBody().Close() |
|
if resp.IsError() { |
|
byt, _ := io.ReadAll(resp.RawBody()) |
|
err = fmt.Errorf(" %s; %s; ", resp.Status(), byt) |
|
} |
|
} |
|
} |
|
} |
|
return &link, err |
|
} |
|
|
|
func (d *BaiduShare) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error { |
|
|
|
return errs.NotSupport |
|
} |
|
|
|
func (d *BaiduShare) Move(ctx context.Context, srcObj, dstDir model.Obj) error { |
|
|
|
return errs.NotSupport |
|
} |
|
|
|
func (d *BaiduShare) Rename(ctx context.Context, srcObj model.Obj, newName string) error { |
|
|
|
return errs.NotSupport |
|
} |
|
|
|
func (d *BaiduShare) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { |
|
|
|
return errs.NotSupport |
|
} |
|
|
|
func (d *BaiduShare) Remove(ctx context.Context, obj model.Obj) error { |
|
|
|
return errs.NotSupport |
|
} |
|
|
|
func (d *BaiduShare) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error { |
|
|
|
return errs.NotSupport |
|
} |
|
|
|
|
|
|
|
|
|
|
|
var _ driver.Driver = (*BaiduShare)(nil) |
|
|