Skip to content

Commit

Permalink
feat: add baidu_netdisk driver
Browse files Browse the repository at this point in the history
  • Loading branch information
xhofe committed Sep 2, 2022
1 parent decea4a commit 611457c
Show file tree
Hide file tree
Showing 21 changed files with 711 additions and 48 deletions.
2 changes: 1 addition & 1 deletion drivers/123/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (d *Pan123) List(ctx context.Context, dir model.Obj, args model.ListArgs) (
}

//func (d *Pan123) Get(ctx context.Context, path string) (model.Obj, error) {
// // TODO this is optional
// // this is optional
// return nil, errs.NotImplement
//}

Expand Down
4 changes: 4 additions & 0 deletions drivers/123/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ type File struct {
DownloadUrl string `json:"DownloadUrl"`
}

func (f File) GetPath() string {
return ""
}

func (f File) GetSize() int64 {
return f.Size
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/123/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (d *Pan123) login() error {
return err
}

func (d *Pan123) request(url string, method string, callback func(*resty.Request), resp interface{}) ([]byte, error) {
func (d *Pan123) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
req := base.RestyClient.R()
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
if callback != nil {
Expand Down
2 changes: 1 addition & 1 deletion drivers/aliyundrive/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (d *AliDrive) refreshToken() error {
return nil
}

func (d *AliDrive) request(url, method string, callback func(*resty.Request), resp interface{}) ([]byte, error, RespErr) {
func (d *AliDrive) request(url, method string, callback base.ReqCallback, resp interface{}) ([]byte, error, RespErr) {
req := base.RestyClient.R()
req.SetHeader("Authorization", "Bearer\t"+d.AccessToken)
req.SetHeader("content-type", "application/json")
Expand Down
1 change: 1 addition & 0 deletions drivers/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package drivers
import (
_ "github.com/alist-org/alist/v3/drivers/123"
_ "github.com/alist-org/alist/v3/drivers/aliyundrive"
_ "github.com/alist-org/alist/v3/drivers/baidu_netdisk"
_ "github.com/alist-org/alist/v3/drivers/local"
_ "github.com/alist-org/alist/v3/drivers/onedrive"
_ "github.com/alist-org/alist/v3/drivers/pikpak"
Expand Down
252 changes: 252 additions & 0 deletions drivers/baidu_netdisk/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
package baidu_netdisk

import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"math"
"os"
stdpath "path"
"strconv"
"strings"

"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/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
log "github.com/sirupsen/logrus"
)

type BaiduNetdisk struct {
model.Storage
Addition
AccessToken string
}

func (d *BaiduNetdisk) Config() driver.Config {
return config
}

func (d *BaiduNetdisk) GetAddition() driver.Additional {
return d.Addition
}

func (d *BaiduNetdisk) Init(ctx context.Context, storage model.Storage) error {
d.Storage = storage
err := utils.Json.UnmarshalFromString(d.Storage.Addition, &d.Addition)
if err != nil {
return err
}
return d.refreshToken()
}

func (d *BaiduNetdisk) Drop(ctx context.Context) error {
return nil
}

func (d *BaiduNetdisk) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
files, err := d.getFiles(dir.GetPath())
if err != nil {
return nil, err
}
objs := make([]model.Obj, len(files))
for i := 0; i < len(files); i++ {
objs[i] = fileToObj(files[i])
}
return objs, nil
}

//func (d *BaiduNetdisk) Get(ctx context.Context, path string) (model.Obj, error) {
// // this is optional
// return nil, errs.NotImplement
//}

func (d *BaiduNetdisk) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
if d.DownloadAPI == "crack" {
return d.linkCrack(file, args)
}
return d.linkOfficial(file, args)
}

func (d *BaiduNetdisk) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
_, err := d.create(stdpath.Join(parentDir.GetPath(), dirName), 0, 1, "", "")
return err
}

func (d *BaiduNetdisk) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
data := []base.Json{
{
"path": srcObj.GetPath(),
"dest": dstDir.GetPath(),
"newname": srcObj.GetName(),
},
}
_, err := d.manage("move", data)
return err
}

func (d *BaiduNetdisk) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
data := []base.Json{
{
"path": srcObj.GetPath(),
"newname": newName,
},
}
_, err := d.manage("rename", data)
return err
}

func (d *BaiduNetdisk) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
dest, newname := stdpath.Split(dstDir.GetPath())
data := []base.Json{
{
"path": srcObj.GetPath(),
"dest": dest,
"newname": newname,
},
}
_, err := d.manage("copy", data)
return err
}

func (d *BaiduNetdisk) Remove(ctx context.Context, obj model.Obj) error {
data := []string{obj.GetPath()}
_, err := d.manage("delete", data)
return err
}

func (d *BaiduNetdisk) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
var tempFile *os.File
var err error
if f, ok := stream.GetReadCloser().(*os.File); ok {
tempFile = f
} else {
tempFile, err = os.CreateTemp(conf.Conf.TempDir, "file-*")
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
_, err = io.Copy(tempFile, stream)
if err != nil {
return err
}
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
}
var Default int64 = 4 * 1024 * 1024
defaultByteData := make([]byte, Default)
count := int(math.Ceil(float64(stream.GetSize()) / float64(Default)))
var SliceSize int64 = 256 * 1024
// cal md5
h1 := md5.New()
h2 := md5.New()
block_list := make([]string, 0)
content_md5 := ""
slice_md5 := ""
left := stream.GetSize()
for i := 0; i < count; i++ {
byteSize := Default
var byteData []byte
if left < Default {
byteSize = left
byteData = make([]byte, byteSize)
} else {
byteData = defaultByteData
}
left -= byteSize
_, err = io.ReadFull(tempFile, byteData)
if err != nil {
return err
}
h1.Write(byteData)
h2.Write(byteData)
block_list = append(block_list, fmt.Sprintf("\"%s\"", hex.EncodeToString(h2.Sum(nil))))
h2.Reset()
}
content_md5 = hex.EncodeToString(h1.Sum(nil))
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
if stream.GetSize() <= SliceSize {
slice_md5 = content_md5
} else {
sliceData := make([]byte, SliceSize)
_, err = io.ReadFull(tempFile, sliceData)
if err != nil {
return err
}
h2.Write(sliceData)
slice_md5 = hex.EncodeToString(h2.Sum(nil))
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
}
path := encodeURIComponent(stdpath.Join(dstDir.GetPath(), stream.GetName()))
block_list_str := fmt.Sprintf("[%s]", strings.Join(block_list, ","))
data := fmt.Sprintf("path=%s&size=%d&isdir=0&autoinit=1&block_list=%s&content-md5=%s&slice-md5=%s",
path, stream.GetSize(),
block_list_str,
content_md5, slice_md5)
params := map[string]string{
"method": "precreate",
}
var precreateResp PrecreateResp
_, err = d.post("/xpan/file", params, data, &precreateResp)
if err != nil {
return err
}
log.Debugf("%+v", precreateResp)
if precreateResp.ReturnType == 2 {
return nil
}
params = map[string]string{
"method": "upload",
"access_token": d.AccessToken,
"type": "tmpfile",
"path": path,
"uploadid": precreateResp.Uploadid,
}
left = stream.GetSize()
for _, partseq := range precreateResp.BlockList {
byteSize := Default
var byteData []byte
if left < Default {
byteSize = left
byteData = make([]byte, byteSize)
} else {
byteData = defaultByteData
}
left -= byteSize
_, err = io.ReadFull(tempFile, byteData)
if err != nil {
return err
}
u := "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2"
params["partseq"] = strconv.Itoa(partseq)
res, err := base.RestyClient.R().SetQueryParams(params).SetFileReader("file", stream.GetName(), bytes.NewReader(byteData)).Post(u)
if err != nil {
return err
}
log.Debugln(res.String())
}
_, err = d.create(path, stream.GetSize(), 0, precreateResp.Uploadid, block_list_str)
return err
}

func (d *BaiduNetdisk) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
return nil, errs.NotSupport
}

var _ driver.Driver = (*BaiduNetdisk)(nil)
35 changes: 35 additions & 0 deletions drivers/baidu_netdisk/meta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package baidu_netdisk

import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)

type Addition struct {
RefreshToken string `json:"refresh_token" required:"true"`
driver.RootFolderPath
OrderBy string `json:"order_by" type:"select" options:"name,time,size" default:"name"`
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
DownloadAPI string `json:"download_api" type:"select" options:"official,crack" default:"official"`
ClientID string `json:"client_id" required:"true" default:"iYCeC9g08h5vuP9UqvPHKKSVrKFXGa1v"`
ClientSecret string `json:"client_secret" required:"true" default:"jXiFMOPVPCWlO2M5CwWQzffpNPaGTRBG"`
}

var config = driver.Config{
Name: "BaiduNetdisk",
LocalSort: false,
OnlyLocal: false,
OnlyProxy: false,
NoCache: false,
NoUpload: false,
NeedMs: false,
DefaultRoot: "root, / or other",
}

func New() driver.Driver {
return &BaiduNetdisk{}
}

func init() {
op.RegisterDriver(config, New)
}
Loading

0 comments on commit 611457c

Please sign in to comment.