Spaces:
Paused
Paused
| 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 { | |
| // TODO login / refresh token | |
| //op.MustSaveDriverStorage(d) | |
| 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) { | |
| // TODO return the files list, required | |
| 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) { | |
| // TODO return link of file, required | |
| 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 { | |
| // TODO create folder, optional | |
| return errs.NotSupport | |
| } | |
| func (d *BaiduShare) Move(ctx context.Context, srcObj, dstDir model.Obj) error { | |
| // TODO move obj, optional | |
| return errs.NotSupport | |
| } | |
| func (d *BaiduShare) Rename(ctx context.Context, srcObj model.Obj, newName string) error { | |
| // TODO rename obj, optional | |
| return errs.NotSupport | |
| } | |
| func (d *BaiduShare) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { | |
| // TODO copy obj, optional | |
| return errs.NotSupport | |
| } | |
| func (d *BaiduShare) Remove(ctx context.Context, obj model.Obj) error { | |
| // TODO remove obj, optional | |
| return errs.NotSupport | |
| } | |
| func (d *BaiduShare) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error { | |
| // TODO upload file, optional | |
| return errs.NotSupport | |
| } | |
| //func (d *Template) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) { | |
| // return nil, errs.NotSupport | |
| //} | |
| var _ driver.Driver = (*BaiduShare)(nil) | |