diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 55f5d04..543ecbf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,7 +30,7 @@ jobs: - name: Setup Go environment uses: actions/setup-go@v2.1.3 with: - go-version: 1.16 + go-version: 1.17 - name: Cache downloaded module uses: actions/cache@v2 with: diff --git a/README.md b/README.md index b1d3168..686c5eb 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,9 @@ iikira/BaiduPCS-Go was largely inspired by [GangZhuo/BaiduPCS](https://github.co [离线下载](#离线下载), 支持http/https/ftp/电驴/磁力链协议. # 版本更新 +**2022.11.12** v3.8.8: +- fix #234, 修复无法转存文件 + **2022.2.18** v3.8.7: - fix #175, 在正式上传前即进行文件大小检测 diff --git a/baidupcs/baidupcs.go b/baidupcs/baidupcs.go index 26a3c12..b5c5a46 100644 --- a/baidupcs/baidupcs.go +++ b/baidupcs/baidupcs.go @@ -18,6 +18,10 @@ import ( const ( // OperationGetUK 获取UK OperationGetUK = "获取UK" + // OperationGetBDSToken + OperationGetBDSToken = "获取bdstoken" + // OperationGetCursorDiff + OperationGetCursorDiff = "获取cursor后文件列表diff信息" // OperationQuotaInfo 获取当前用户空间配额信息 OperationQuotaInfo = "获取当前用户空间配额信息" // OperationFilesDirectoriesMeta 获取文件/目录的元信息 @@ -149,6 +153,13 @@ type ( Uk int64 `json:"uk"` } `json:"records"` } + + userVarJSON struct { + *pcserror.PanErrorInfo + Result struct { + BDSToken string `json:"bdstoken"` + } `json:"result"` + } ) //UpdatePCSCookies 去除重名Cookies, 同名cookeis只保留最新的 @@ -451,3 +462,30 @@ func (pcs *BaiduPCS) UK() (uk int64, pcsError pcserror.Error) { return jsonData.Records[0].Uk, nil } + +func (pcs *BaiduPCS) BDSToken() (bdstoken string, pcsError pcserror.Error) { + dataReadCloser, pcsError := pcs.PrepareBDStoken() + if pcsError != nil { + return + } + + defer dataReadCloser.Close() + + errInfo := pcserror.NewPanErrorInfo(OperationGetBDSToken) + jsonData := userVarJSON{ + PanErrorInfo: errInfo, + } + + pcsError = pcserror.HandleJSONParse(OperationGetBDSToken, dataReadCloser, &jsonData) + if pcsError != nil { + return + } + + if jsonData.Result.BDSToken == "" { + errInfo.ErrType = pcserror.ErrTypeOthers + errInfo.Err = errors.New("Unknown remote data") + return "", errInfo + } + + return jsonData.Result.BDSToken, nil +} diff --git a/baidupcs/prepare.go b/baidupcs/prepare.go index 6316ed5..3a421d1 100644 --- a/baidupcs/prepare.go +++ b/baidupcs/prepare.go @@ -166,6 +166,37 @@ func (pcs *BaiduPCS) PrepareFilesDirectoriesList(path string, options *OrderOpti return } +func (pcs *BaiduPCS) PrepareFilesDirectoriesDiff(cursor string) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { + pcs.lazyInit() + //bdstoken, pcsError := pcs.BDSToken() + //if pcsError != nil { + // return + //} + if cursor == "" { + cursor = "null" + } + ns := netdisksign.NewLocateDownloadSign(pcs.uid, pcs.GetBDUSS()) + pcsURL := pcs.generatePanURL("batch/filediff", map[string]string{ + "cursor": cursor, + //"bdstoken": bdstoken, + "clienttype": "1", + }) + paramsURL := ns.URLParam() + dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationGetCursorDiff, http.MethodGet, pcsURL.String() + "&"+ paramsURL, nil, nil) + return +} + +func (pcs *BaiduPCS) PrepareBDStoken() (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { + pcs.lazyInit() + pcsURL := pcs.generatePanURL("gettemplatevariable", map[string]string{ + "clienttype": "0", + "app_id": string(pcs.appID), + "fields": `["bdstoken"]`, + }) + dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationGetBDSToken, http.MethodGet, pcsURL.String(), nil, nil) + return +} + // PrepareSearch 按文件名搜索文件, 只返回服务器响应数据和错误信息 func (pcs *BaiduPCS) PrepareSearch(targetPath, keyword string, recursive bool) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { pcs.lazyInit() diff --git a/baidupcs/transfer.go b/baidupcs/transfer.go index a75c61e..3fd6b43 100644 --- a/baidupcs/transfer.go +++ b/baidupcs/transfer.go @@ -2,6 +2,8 @@ package baidupcs import ( "fmt" + "github.com/qjfoidnh/BaiduPCS-Go/baidupcs/netdisksign" + "github.com/tidwall/gjson" "io/ioutil" "net/http" "net/url" @@ -10,8 +12,6 @@ import ( "regexp" "strconv" "strings" - - "github.com/tidwall/gjson" ) type ( @@ -28,11 +28,14 @@ func (pcs *BaiduPCS) GenerateShareQueryURL(subPath string, params map[string]str Host: PanBaiduCom, Path: "/share/" + subPath, } + ns := netdisksign.NewLocateDownloadSign(pcs.uid, pcs.GetBDUSS()) uv := shareURL.Query() - uv.Set("app_id", PanAppID) - uv.Set("channel", "chunlei") - uv.Set("clienttype", "0") - uv.Set("web", "1") + uv.Set("apn_id", "1_0") + uv.Set("channel", "android_7.0_VTR-AL00_bd-netdisk_1026250y") + uv.Set("time", strconv.Itoa(int(ns.Time))) + uv.Set("cuid", ns.DevUID) + uv.Set("devuid", ns.DevUID) + uv.Set("clienttype", "1") for key, value := range params { uv.Set(key, value) } @@ -49,7 +52,7 @@ func (pcs *BaiduPCS) ExtractShareInfo(metajsonstr string) (res map[string]string } errno := gjson.Get(metajsonstr, `file_list.errno`).Int() if errno != 0 { - res["ErrMsg"] = "提取码错误" + res["ErrMsg"] = fmt.Sprintf("未知错误, 错误码%d", errno) return } res["filename"] = gjson.Get(metajsonstr, `file_list.0.server_filename`).String() @@ -83,11 +86,10 @@ func (pcs *BaiduPCS) ExtractShareInfo(metajsonstr string) (res map[string]string return } -func (pcs *BaiduPCS) PostShareQuery(url string, surl string, data map[string]string) (res map[string]string) { +func (pcs *BaiduPCS) PostShareQuery(url string, data map[string]string) (res map[string]string) { dataReadCloser, panError := pcs.sendReqReturnReadCloser(reqTypePan, OperationShareFileSavetoLocal, http.MethodPost, url, data, map[string]string{ - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36", + "User-Agent": pcs.panUA, "Content-Type": "application/x-www-form-urlencoded", - "Referer": fmt.Sprintf("https://pan.baidu.com/share/init?surl=%s", surl), }) res = make(map[string]string) if panError != nil { @@ -98,7 +100,7 @@ func (pcs *BaiduPCS) PostShareQuery(url string, surl string, data map[string]str body, _ := ioutil.ReadAll(dataReadCloser) errno := gjson.Get(string(body), `errno`).String() if errno != "0" { - res["ErrMsg"] = "分享码错误" + res["ErrMsg"] = fmt.Sprintf("未知错误, 错误码%d", errno) return } res["ErrMsg"] = "0" @@ -142,6 +144,9 @@ func (pcs *BaiduPCS) AccessSharePage(featurestr string, first bool) (tokens map[ } tokens["metajson"] = string(sub[1]) tokens["bdstoken"] = gjson.Get(string(sub[1]), `bdstoken`).String() + tokens["uk"] = gjson.Get(string(sub[1]), `uk`).String() + tokens["share_uk"] = gjson.Get(string(sub[1]), `share_uk`).String() + tokens["shareid"] = gjson.Get(string(sub[1]), `shareid`).String() return } @@ -198,8 +203,8 @@ func (pcs *BaiduPCS) GenerateRequestQuery(mode string, params map[string]string) } else { res["ErrMsg"] = fmt.Sprintf("未知错误, 错误代码%d", _errno) } - } else { - res["ErrMsg"] = fmt.Sprintf("未知错误, 错误代码%d", errno) + } else if mode == "POST" && errno == 4 { + res["ErrMsg"] = fmt.Sprintf("文件重复") } return } diff --git a/go.mod b/go.mod index 4a1d378..f4a07a5 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,9 @@ module github.com/qjfoidnh/BaiduPCS-Go -go 1.16 +go 1.17 require ( github.com/GeertJohan/go.incremental v1.0.0 - github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/fatih/color v1.10.0 github.com/golang/protobuf v1.4.3 @@ -21,3 +20,21 @@ require ( golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 ) + +require ( + github.com/GeertJohan/go.rice v1.0.2 // indirect + github.com/astaxie/beego v1.12.3 // indirect + github.com/bitly/go-simplejson v0.5.0 // indirect + github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect + github.com/daaku/go.zipexe v1.0.0 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/russross/blackfriday/v2 v2.0.1 // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/tidwall/match v1.0.1 // indirect + github.com/tidwall/pretty v1.0.2 // indirect + google.golang.org/protobuf v1.23.0 // indirect +) diff --git a/internal/pcscommand/transfer.go b/internal/pcscommand/transfer.go index 3b3b22e..0443523 100644 --- a/internal/pcscommand/transfer.go +++ b/internal/pcscommand/transfer.go @@ -50,25 +50,29 @@ func RunShareTransfer(params []string, opt *baidupcs.TransferOption) { } // pcs.UpdatePCSCookies(true) var vefiryurl string + var randsk string featuremap := make(map[string]string) - featuremap["surl"] = featurestr[1:] - featuremap["bdstoken"] = tokens["bdstoken"] + featuremap["shareid"] = tokens["shareid"] + featuremap["uk"] = tokens["share_uk"] if extracode != "none" { vefiryurl = pcs.GenerateShareQueryURL("verify", featuremap).String() - res := pcs.PostShareQuery(vefiryurl, featurestr[1:], map[string]string{ + res := pcs.PostShareQuery(vefiryurl, map[string]string{ "pwd": extracode, "vcode": "", - "vcode_str": "", + "vcode_str": "null", + "bdstoken": tokens["bdstoken"], }) if res["ErrMsg"] != "0" { fmt.Printf("%s失败: %s\n", baidupcs.OperationShareFileSavetoLocal, res["ErrMsg"]) return } + randsk = res["randsk"] } pcs.UpdatePCSCookies(true) tokens = pcs.AccessSharePage(featurestr, false) + tokens["randsk"] = randsk if tokens["ErrMsg"] != "0" { fmt.Printf("%s失败: %s\n", baidupcs.OperationShareFileSavetoLocal, tokens["ErrMsg"]) return @@ -93,7 +97,7 @@ func RunShareTransfer(params []string, opt *baidupcs.TransferOption) { fmt.Printf("%s失败: %s\n", baidupcs.OperationShareFileSavetoLocal, resp["ErrMsg"]) if resp["ErrNo"] == "4" { trans_metas["shorturl"] = featurestr - pcs.SuperTransfer(trans_metas, resp["limit"]) // 试验性功能 + pcs.SuperTransfer(trans_metas, resp["limit"]) // 试验性功能, 当前未启用 } return } diff --git a/main.go b/main.go index ec67b85..13be5fc 100644 --- a/main.go +++ b/main.go @@ -55,7 +55,7 @@ const ( var ( // Version 版本号 - Version = "v3.8.7-devel" + Version = "v3.8.8-devel" historyFilePath = filepath.Join(pcsconfig.GetConfigDir(), "pcs_command_history.txt") reloadFn = func(c *cli.Context) error { diff --git a/versioninfo.json b/versioninfo.json index 53b3345..aba43b7 100644 --- a/versioninfo.json +++ b/versioninfo.json @@ -2,13 +2,13 @@ "FixedFileInfo": { "FileVersion": { "Major": 3, - "Minor": 7, + "Minor": 8, "Patch": 8, "Build": 0 }, "ProductVersion": { "Major": 3, - "Minor": 7, + "Minor": 8, "Patch": 8, "Build": 0 }, @@ -22,14 +22,14 @@ "Comments": "", "CompanyName": "qjfoidnh", "FileDescription": "百度网盘客户端(加强版)", - "FileVersion": "v3.7.8", + "FileVersion": "v3.8.8", "InternalName": "", "LegalCopyright": "© 2016-2020 iikira.", "LegalTrademarks": "", "OriginalFilename": "", "PrivateBuild": "", "ProductName": "BaiduPCS-Go", - "ProductVersion": "v3.7.8", + "ProductVersion": "v3.8.8", "SpecialBuild": "" }, "VarFileInfo": {