github.com/fzfile/BaiduPCS-Go@v0.0.0-20200606205115-4408961cf336/baidupcs/prepare.go (about) 1 package baidupcs 2 3 import ( 4 "bytes" 5 "fmt" 6 "github.com/fzfile/BaiduPCS-Go/baidupcs/netdisksign" 7 "github.com/fzfile/BaiduPCS-Go/baidupcs/pcserror" 8 "github.com/fzfile/BaiduPCS-Go/pcsutil/converter" 9 "github.com/fzfile/BaiduPCS-Go/requester/multipartreader" 10 "github.com/fzfile/baidu-tools/tieba" 11 "github.com/json-iterator/go" 12 "io" 13 "net/http" 14 "net/url" 15 "strconv" 16 "strings" 17 "unsafe" 18 ) 19 20 type ( 21 reqType int 22 ) 23 24 const ( 25 reqTypePCS = iota 26 reqTypePan 27 ) 28 29 func handleRespClose(resp *http.Response) error { 30 if resp != nil { 31 return resp.Body.Close() 32 } 33 return nil 34 } 35 36 func handleRespStatusError(opreation string, resp *http.Response) pcserror.Error { 37 errInfo := pcserror.NewPCSErrorInfo(opreation) 38 // http 响应错误处理 39 switch resp.StatusCode / 100 { 40 case 4, 5: 41 resp.Body.Close() 42 errInfo.SetNetError(fmt.Errorf("http 响应错误, %s", resp.Status)) 43 return errInfo 44 } 45 46 return nil 47 } 48 49 func (pcs *BaiduPCS) sendReqReturnResp(rt reqType, op, method, urlStr string, post interface{}, header map[string]string) (resp *http.Response, pcsError pcserror.Error) { 50 if header == nil { 51 header = map[string]string{} 52 } 53 54 var ( 55 _, uaok = header["User-Agent"] 56 ) 57 58 if !uaok { 59 switch rt { 60 case reqTypePCS: 61 header["User-Agent"] = pcs.pcsUA 62 case reqTypePan: 63 header["User-Agent"] = pcs.panUA 64 } 65 } 66 67 resp, err := pcs.client.Req(method, urlStr, post, header) 68 if err != nil { 69 handleRespClose(resp) 70 switch rt { 71 case reqTypePCS: 72 return nil, &pcserror.PCSErrInfo{ 73 Operation: op, 74 ErrType: pcserror.ErrTypeNetError, 75 Err: err, 76 } 77 case reqTypePan: 78 return nil, &pcserror.PanErrorInfo{ 79 Operation: op, 80 ErrType: pcserror.ErrTypeNetError, 81 Err: err, 82 } 83 } 84 panic("unreachable") 85 } 86 return resp, nil 87 } 88 89 func (pcs *BaiduPCS) sendReqReturnReadCloser(rt reqType, op, method, urlStr string, post interface{}, header map[string]string) (readCloser io.ReadCloser, pcsError pcserror.Error) { 90 resp, pcsError := pcs.sendReqReturnResp(rt, op, method, urlStr, post, header) 91 if pcsError != nil { 92 return 93 } 94 return resp.Body, nil 95 } 96 97 // PrepareUK 获取用户 UK, 只返回服务器响应数据和错误信息 98 func (pcs *BaiduPCS) PrepareUK() (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 99 pcs.lazyInit() 100 101 query := url.Values{} 102 query.Set("need_selfinfo", "1") 103 104 panURL := &url.URL{ 105 Scheme: "https", 106 Host: PanBaiduCom, 107 Path: "api/user/getinfo", 108 RawQuery: query.Encode(), 109 } 110 111 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationGetUK, http.MethodGet, panURL.String(), nil, nil) 112 return 113 } 114 115 // PrepareQuotaInfo 获取当前用户空间配额信息, 只返回服务器响应数据和错误信息 116 func (pcs *BaiduPCS) PrepareQuotaInfo() (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 117 pcs.lazyInit() 118 pcsURL := pcs.generatePCSURL("quota", "info") 119 baiduPCSVerbose.Infof("%s URL: %s\n", OperationQuotaInfo, pcsURL) 120 121 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationQuotaInfo, http.MethodGet, pcsURL.String(), nil, nil) 122 return 123 } 124 125 // PrepareFilesDirectoriesBatchMeta 获取多个文件/目录的元信息, 只返回服务器响应数据和错误信息 126 func (pcs *BaiduPCS) PrepareFilesDirectoriesBatchMeta(paths ...string) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 127 pcs.lazyInit() 128 sendData, err := (&PathsListJSON{}).JSON(paths...) 129 if err != nil { 130 panic(OperationFilesDirectoriesMeta + ", json 数据构造失败, " + err.Error()) 131 } 132 133 pcsURL := pcs.generatePCSURL("file", "meta") 134 baiduPCSVerbose.Infof("%s URL: %s\n", OperationFilesDirectoriesMeta, pcsURL) 135 136 // 表单上传 137 mr := multipartreader.NewMultipartReader() 138 mr.AddFormFeild("param", bytes.NewReader(sendData)) 139 mr.CloseMultipart() 140 141 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationFilesDirectoriesMeta, http.MethodPost, pcsURL.String(), mr, nil) 142 return 143 } 144 145 // PrepareFilesDirectoriesList 获取目录下的文件和目录列表, 只返回服务器响应数据和错误信息 146 func (pcs *BaiduPCS) PrepareFilesDirectoriesList(path string, options *OrderOptions) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 147 pcs.lazyInit() 148 if options == nil { 149 options = DefaultOrderOptions 150 } 151 if path == "" { 152 path = PathSeparator 153 } 154 155 pcsURL := pcs.generatePCSURL("file", "list", map[string]string{ 156 "path": path, 157 "by": *(*string)(unsafe.Pointer(&options.By)), 158 "order": *(*string)(unsafe.Pointer(&options.Order)), 159 "limit": "0-2147483647", 160 }) 161 baiduPCSVerbose.Infof("%s URL: %s\n", OperationFilesDirectoriesList, pcsURL) 162 163 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationFilesDirectoriesList, http.MethodGet, pcsURL.String(), nil, nil) 164 return 165 } 166 167 // PrepareSearch 按文件名搜索文件, 只返回服务器响应数据和错误信息 168 func (pcs *BaiduPCS) PrepareSearch(targetPath, keyword string, recursive bool) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 169 pcs.lazyInit() 170 var re string 171 if recursive { 172 re = "1" 173 } else { 174 re = "0" 175 } 176 pcsURL := pcs.generatePCSURL("file", "search", map[string]string{ 177 "path": targetPath, 178 "wd": keyword, 179 "re": re, 180 }) 181 baiduPCSVerbose.Infof("%s URL: %s\n", OperationSearch, pcsURL) 182 183 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationSearch, http.MethodGet, pcsURL.String(), nil, nil) 184 return 185 } 186 187 // PrepareRemove 批量删除文件/目录, 只返回服务器响应数据和错误信息 188 func (pcs *BaiduPCS) PrepareRemove(paths ...string) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 189 pcs.lazyInit() 190 sendData, err := (&PathsListJSON{}).JSON(paths...) 191 if err != nil { 192 panic(OperationMove + ", json 数据构造失败, " + err.Error()) 193 } 194 195 pcsURL := pcs.generatePCSURL("file", "delete") 196 baiduPCSVerbose.Infof("%s URL: %s\n", OperationRemove, pcsURL) 197 198 // 表单上传 199 mr := multipartreader.NewMultipartReader() 200 mr.AddFormFeild("param", bytes.NewReader(sendData)) 201 mr.CloseMultipart() 202 203 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationRemove, http.MethodPost, pcsURL.String(), mr, nil) 204 return 205 } 206 207 // PrepareMkdir 创建目录, 只返回服务器响应数据和错误信息 208 func (pcs *BaiduPCS) PrepareMkdir(pcspath string) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 209 pcs.lazyInit() 210 pcsURL := pcs.generatePCSURL("file", "mkdir", map[string]string{ 211 "path": pcspath, 212 }) 213 baiduPCSVerbose.Infof("%s URL: %s", OperationMkdir, pcsURL) 214 215 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationMkdir, http.MethodPost, pcsURL.String(), nil, nil) 216 return 217 } 218 219 func (pcs *BaiduPCS) prepareCpMvOp(op string, cpmvJSON ...*CpMvJSON) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 220 pcs.lazyInit() 221 var method string 222 switch op { 223 case OperationCopy: 224 method = "copy" 225 case OperationMove, OperationRename: 226 method = "move" 227 default: 228 panic("Unknown opreation: " + op) 229 } 230 231 sendData, err := (&CpMvListJSON{ 232 List: cpmvJSON, 233 }).JSON() 234 if err != nil { 235 //json 数据生成失败 236 panic(err) 237 } 238 239 pcsURL := pcs.generatePCSURL("file", method) 240 baiduPCSVerbose.Infof("%s URL: %s\n", op, pcsURL) 241 242 // 表单上传 243 mr := multipartreader.NewMultipartReader() 244 mr.AddFormFeild("param", bytes.NewReader(sendData)) 245 mr.CloseMultipart() 246 247 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, op, http.MethodPost, pcsURL.String(), mr, nil) 248 return 249 } 250 251 // PrepareRename 重命名文件/目录, 只返回服务器响应数据和错误信息 252 func (pcs *BaiduPCS) PrepareRename(from, to string) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 253 return pcs.prepareCpMvOp(OperationRename, &CpMvJSON{ 254 From: from, 255 To: to, 256 }) 257 } 258 259 // PrepareCopy 批量拷贝文件/目录, 只返回服务器响应数据和错误信息 260 func (pcs *BaiduPCS) PrepareCopy(cpmvJSON ...*CpMvJSON) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 261 return pcs.prepareCpMvOp(OperationCopy, cpmvJSON...) 262 } 263 264 // PrepareMove 批量移动文件/目录, 只返回服务器响应数据和错误信息 265 func (pcs *BaiduPCS) PrepareMove(cpmvJSON ...*CpMvJSON) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 266 return pcs.prepareCpMvOp(OperationMove, cpmvJSON...) 267 } 268 269 // prepareRapidUpload 秒传文件, 不进行文件夹检查 270 func (pcs *BaiduPCS) prepareRapidUpload(targetPath, contentMD5, sliceMD5, crc32 string, length int64) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 271 pcs.lazyInit() 272 pcsURL := pcs.generatePCSURL("file", "rapidupload", map[string]string{ 273 "path": targetPath, // 上传文件的全路径名 274 "content-length": strconv.FormatInt(length, 10), // 待秒传的文件长度 275 "content-md5": contentMD5, // 待秒传的文件的MD5 276 "slice-md5": sliceMD5, // 待秒传的文件前256kb的MD5 277 "content-crc32": crc32, // 待秒传文件CRC32 278 "ondup": "overwrite", // overwrite: 表示覆盖同名文件; newcopy: 表示生成文件副本并进行重命名,命名规则为“文件名_日期.后缀” 279 }) 280 baiduPCSVerbose.Infof("%s URL: %s\n", OperationRapidUpload, pcsURL) 281 282 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationRapidUpload, http.MethodGet, pcsURL.String(), nil, nil) 283 return 284 } 285 286 // PrepareRapidUpload 秒传文件, 只返回服务器响应数据和错误信息 287 func (pcs *BaiduPCS) PrepareRapidUpload(targetPath, contentMD5, sliceMD5, crc32 string, length int64) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 288 pcs.lazyInit() 289 pcsError = pcs.checkIsdir(OperationRapidUpload, targetPath) 290 if pcsError != nil { 291 return nil, pcsError 292 } 293 294 return pcs.prepareRapidUpload(targetPath, contentMD5, sliceMD5, crc32, length) 295 } 296 297 // PrepareLocateDownload 获取下载链接, 只返回服务器响应数据和错误信息 298 func (pcs *BaiduPCS) PrepareLocateDownload(pcspath string) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 299 pcs.lazyInit() 300 bduss := pcs.GetBDUSS() 301 // 检测uid 302 if pcs.uid == 0 { 303 t, err := tieba.NewUserInfoByBDUSS(bduss) 304 if err != nil { 305 return nil, &pcserror.PCSErrInfo{ 306 Operation: OperationLocateDownload, 307 ErrType: pcserror.ErrTypeNetError, 308 Err: err, 309 } 310 } 311 pcs.uid = t.Baidu.UID 312 } 313 314 ns := netdisksign.NewLocateDownloadSign(pcs.uid, bduss) 315 pcsURL := &url.URL{ 316 Scheme: GetHTTPScheme(pcs.isHTTPS), 317 Host: PCSBaiduCom, 318 Path: "/rest/2.0/pcs/file", 319 RawQuery: (url.Values{ 320 "app_id": []string{PanAppID}, 321 "method": []string{"locatedownload"}, 322 "path": []string{pcspath}, 323 "ver": []string{"2"}, 324 }).Encode() + "&" + ns.URLParam(), 325 } 326 baiduPCSVerbose.Infof("%s URL: %s\n", OperationLocateDownload, pcsURL) 327 328 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationLocateDownload, http.MethodGet, pcsURL.String(), nil, pcs.getPanUAHeader()) 329 return 330 } 331 332 // PrepareLocatePanAPIDownload 从百度网盘首页获取下载链接, 只返回服务器响应数据和错误信息 333 func (pcs *BaiduPCS) PrepareLocatePanAPIDownload(fidList ...int64) (dataReadCloser io.ReadCloser, panError pcserror.Error) { 334 pcs.lazyInit() 335 // 初始化 336 var ( 337 sign, err = pcs.ph.CacheSignature() 338 ) 339 if err != nil { 340 return nil, &pcserror.PanErrorInfo{ 341 Operation: OperationLocatePanAPIDownload, 342 ErrType: pcserror.ErrTypeOthers, 343 Err: err, 344 } 345 } 346 347 panURL := pcs.generatePanURL("download", nil) 348 baiduPCSVerbose.Infof("%s URL: %s\n", OperationLocatePanAPIDownload, panURL) 349 350 dataReadCloser, panError = pcs.sendReqReturnReadCloser(reqTypePan, OperationLocatePanAPIDownload, http.MethodPost, panURL.String(), map[string]string{ 351 "sign": sign.Sign(), 352 "timestamp": sign.Timestamp(), 353 "fidlist": mergeInt64List(fidList...), 354 }, map[string]string{ 355 "Content-Type": "application/x-www-form-urlencoded", 356 }) 357 return 358 } 359 360 // PrepareUpload 上传单个文件, 只返回服务器响应数据和错误信息 361 func (pcs *BaiduPCS) PrepareUpload(targetPath string, uploadFunc UploadFunc) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 362 pcs.lazyInit() 363 pcsError = pcs.checkIsdir(OperationUpload, targetPath) 364 if pcsError != nil { 365 return nil, pcsError 366 } 367 368 pcsURL := pcs.generatePCSURL("file", "upload", map[string]string{ 369 "path": targetPath, 370 "ondup": "overwrite", 371 }) 372 baiduPCSVerbose.Infof("%s URL: %s\n", OperationUpload, pcsURL) 373 374 resp, err := uploadFunc(pcsURL.String(), pcs.client.Jar) 375 if err != nil { 376 handleRespClose(resp) 377 return nil, &pcserror.PCSErrInfo{ 378 Operation: OperationUpload, 379 ErrType: pcserror.ErrTypeNetError, 380 Err: err, 381 } 382 } 383 384 pcsError = handleRespStatusError(OperationUpload, resp) 385 if pcsError != nil { 386 return 387 } 388 389 return resp.Body, nil 390 } 391 392 // PrepareUploadTmpFile 分片上传—文件分片及上传, 只返回服务器响应数据和错误信息 393 func (pcs *BaiduPCS) PrepareUploadTmpFile(uploadFunc UploadFunc) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 394 pcs.lazyInit() 395 pcsURL := pcs.generatePCSURL("file", "upload", map[string]string{ 396 "type": "tmpfile", 397 }) 398 baiduPCSVerbose.Infof("%s URL: %s\n", OperationUploadTmpFile, pcsURL) 399 400 resp, err := uploadFunc(pcsURL.String(), pcs.client.Jar) 401 if err != nil { 402 handleRespClose(resp) 403 return nil, &pcserror.PCSErrInfo{ 404 Operation: OperationUploadTmpFile, 405 ErrType: pcserror.ErrTypeNetError, 406 Err: err, 407 } 408 } 409 410 pcsError = handleRespStatusError(OperationUploadTmpFile, resp) 411 if pcsError != nil { 412 return 413 } 414 415 return resp.Body, nil 416 } 417 418 // PrepareUploadCreateSuperFile 分片上传—合并分片文件, 只返回服务器响应数据和错误信息 419 func (pcs *BaiduPCS) PrepareUploadCreateSuperFile(checkDir bool, targetPath string, blockList ...string) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 420 pcs.lazyInit() 421 422 if checkDir { 423 // 检查是否为目录 424 pcsError = pcs.checkIsdir(OperationUploadCreateSuperFile, targetPath) 425 if pcsError != nil { 426 return nil, pcsError 427 } 428 } 429 430 bl := BlockListJSON{ 431 BlockList: blockList, 432 } 433 434 sendData, err := jsoniter.Marshal(&bl) 435 if err != nil { 436 panic(err) 437 } 438 439 pcsURL := pcs.generatePCSURL("file", "createsuperfile", map[string]string{ 440 "path": targetPath, 441 "ondup": "overwrite", 442 }) 443 baiduPCSVerbose.Infof("%s URL: %s\n", OperationUploadCreateSuperFile, pcsURL) 444 445 // 表单上传 446 mr := multipartreader.NewMultipartReader() 447 mr.AddFormFeild("param", bytes.NewReader(sendData)) 448 mr.CloseMultipart() 449 450 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationUploadCreateSuperFile, http.MethodPost, pcsURL.String(), mr, nil) 451 return 452 } 453 454 // PrepareUploadPrecreate 分片上传—Precreate, 只返回服务器响应数据和错误信息 455 func (pcs *BaiduPCS) PrepareUploadPrecreate(targetPath, contentMD5, sliceMD5, crc32 string, size int64, bolckList ...string) (dataReadCloser io.ReadCloser, panError pcserror.Error) { 456 pcs.lazyInit() 457 panURL := &url.URL{ 458 Scheme: "https", 459 Host: PanBaiduCom, 460 Path: "api/precreate", 461 } 462 baiduPCSVerbose.Infof("%s URL: %s\n", OperationUploadPrecreate, panURL) 463 464 dataReadCloser, panError = pcs.sendReqReturnReadCloser(reqTypePan, OperationUploadPrecreate, http.MethodPost, panURL.String(), map[string]string{ 465 "path": targetPath, 466 "size": strconv.FormatInt(size, 10), 467 "isdir": "0", 468 "block_list": mergeStringList(bolckList...), 469 "autoinit": "1", 470 "content-md5": contentMD5, 471 "slice-md5": sliceMD5, 472 "contentCrc32": crc32, 473 "rtype": "2", 474 }, map[string]string{ 475 "Content-Type": "application/x-www-form-urlencoded", 476 }) 477 return 478 } 479 480 // PrepareUploadSuperfile2 另一个上传接口 481 func (pcs *BaiduPCS) PrepareUploadSuperfile2(uploadid, targetPath string, partseq int, partOffset int64, uploadFunc UploadFunc) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 482 pcs.lazyInit() 483 pcsURL := pcs.generatePCSURL("superfile2", "upload", map[string]string{ 484 "type": "tmpfile", 485 "path": targetPath, 486 "partseq": strconv.Itoa(partseq), 487 "partoffset": strconv.FormatInt(partOffset, 10), 488 "uploadid": uploadid, 489 "vip": "1", 490 }) 491 baiduPCSVerbose.Infof("%s URL: %s\n", OperationUploadSuperfile2, pcsURL) 492 493 resp, err := uploadFunc(pcsURL.String(), pcs.client.Jar) 494 if err != nil { 495 handleRespClose(resp) 496 return nil, &pcserror.PCSErrInfo{ 497 Operation: OperationUploadSuperfile2, 498 ErrType: pcserror.ErrTypeNetError, 499 Err: err, 500 } 501 } 502 503 pcsError = handleRespStatusError(OperationUpload, resp) 504 if pcsError != nil { 505 return 506 } 507 return resp.Body, nil 508 } 509 510 // PrepareCloudDlAddTask 添加离线下载任务, 只返回服务器响应数据和错误信息 511 func (pcs *BaiduPCS) PrepareCloudDlAddTask(sourceURL, savePath string) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 512 pcs.lazyInit() 513 pcsURL2 := pcs.generatePCSURL2("services/cloud_dl", "add_task", map[string]string{ 514 "save_path": savePath, 515 "source_url": sourceURL, 516 "timeout": "2147483647", 517 }) 518 baiduPCSVerbose.Infof("%s URL: %s\n", OperationCloudDlAddTask, pcsURL2) 519 520 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationCloudDlAddTask, http.MethodPost, pcsURL2.String(), nil, nil) 521 return 522 } 523 524 // PrepareCloudDlQueryTask 精确查询离线下载任务, 只返回服务器响应数据和错误信息, 525 // taskids 例子: 12123,234234,2344, 用逗号隔开多个 task_id 526 func (pcs *BaiduPCS) PrepareCloudDlQueryTask(taskIDs string) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 527 pcs.lazyInit() 528 pcsURL2 := pcs.generatePCSURL2("services/cloud_dl", "query_task", map[string]string{ 529 "op_type": "1", 530 }) 531 baiduPCSVerbose.Infof("%s URL: %s\n", OperationCloudDlQueryTask, pcsURL2) 532 533 // 表单上传 534 mr := multipartreader.NewMultipartReader() 535 mr.AddFormFeild("task_ids", strings.NewReader(taskIDs)) 536 mr.CloseMultipart() 537 538 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationCloudDlQueryTask, http.MethodPost, pcsURL2.String(), mr, nil) 539 return 540 } 541 542 // PrepareCloudDlListTask 查询离线下载任务列表, 只返回服务器响应数据和错误信息 543 func (pcs *BaiduPCS) PrepareCloudDlListTask() (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 544 pcs.lazyInit() 545 pcsURL2 := pcs.generatePCSURL2("services/cloud_dl", "list_task", map[string]string{ 546 "need_task_info": "1", 547 "status": "255", 548 "start": "0", 549 "limit": "1000", 550 }) 551 baiduPCSVerbose.Infof("%s URL: %s\n", OperationCloudDlListTask, pcsURL2) 552 553 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationCloudDlListTask, http.MethodPost, pcsURL2.String(), nil, nil) 554 return 555 } 556 557 func (pcs *BaiduPCS) prepareCloudDlCDTask(opreation, method string, taskID int64) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 558 pcs.lazyInit() 559 pcsURL2 := pcs.generatePCSURL2("services/cloud_dl", method, map[string]string{ 560 "task_id": strconv.FormatInt(taskID, 10), 561 }) 562 baiduPCSVerbose.Infof("%s URL: %s\n", opreation, pcsURL2) 563 564 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, opreation, http.MethodPost, pcsURL2.String(), nil, nil) 565 return 566 } 567 568 // PrepareCloudDlCancelTask 取消离线下载任务, 只返回服务器响应数据和错误信息 569 func (pcs *BaiduPCS) PrepareCloudDlCancelTask(taskID int64) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 570 return pcs.prepareCloudDlCDTask(OperationCloudDlCancelTask, "cancel_task", taskID) 571 } 572 573 // PrepareCloudDlDeleteTask 取消离线下载任务, 只返回服务器响应数据和错误信息 574 func (pcs *BaiduPCS) PrepareCloudDlDeleteTask(taskID int64) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 575 return pcs.prepareCloudDlCDTask(OperationCloudDlDeleteTask, "delete_task", taskID) 576 } 577 578 // PrepareCloudDlClearTask 清空离线下载任务记录, 只返回服务器响应数据和错误信息 579 func (pcs *BaiduPCS) PrepareCloudDlClearTask() (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 580 pcs.lazyInit() 581 pcsURL2 := pcs.generatePCSURL2("services/cloud_dl", "clear_task") 582 baiduPCSVerbose.Infof("%s URL: %s\n", OperationCloudDlClearTask, pcsURL2) 583 584 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationCloudDlClearTask, http.MethodPost, pcsURL2.String(), nil, nil) 585 return 586 } 587 588 // PrepareSharePSet 私密分享文件, 只返回服务器响应数据和错误信息 589 func (pcs *BaiduPCS) PrepareSharePSet(paths []string, period int) (dataReadCloser io.ReadCloser, panError pcserror.Error) { 590 pcs.lazyInit() 591 panURL := &url.URL{ 592 Scheme: "https", 593 Host: PanBaiduCom, 594 Path: "share/pset", 595 } 596 baiduPCSVerbose.Infof("%s URL: %s\n", OperationShareSet, panURL) 597 598 dataReadCloser, panError = pcs.sendReqReturnReadCloser(reqTypePan, OperationShareSet, http.MethodPost, panURL.String(), map[string]string{ 599 "path_list": mergeStringList(paths...), 600 "schannel": "0", 601 "channel_list": "[]", 602 "period": strconv.Itoa(period), 603 }, map[string]string{ 604 "Content-Type": "application/x-www-form-urlencoded", 605 }) 606 return 607 } 608 609 // PrepareShareCancel 取消分享, 只返回服务器响应数据和错误信息 610 func (pcs *BaiduPCS) PrepareShareCancel(shareIDs []int64) (dataReadCloser io.ReadCloser, panError pcserror.Error) { 611 pcs.lazyInit() 612 panURL := &url.URL{ 613 Scheme: "https", 614 Host: PanBaiduCom, 615 Path: "share/cancel", 616 } 617 618 baiduPCSVerbose.Infof("%s URL: %s\n", OperationShareCancel, panURL) 619 620 ss := converter.SliceInt64ToString(shareIDs) 621 dataReadCloser, panError = pcs.sendReqReturnReadCloser(reqTypePan, OperationShareCancel, http.MethodPost, panURL.String(), map[string]string{ 622 "shareid_list": "[" + strings.Join(ss, ",") + "]", 623 }, map[string]string{ 624 "Content-Type": "application/x-www-form-urlencoded", 625 }) 626 return 627 } 628 629 // PrepareShareList 列出分享列表, 只返回服务器响应数据和错误信息 630 func (pcs *BaiduPCS) PrepareShareList(page int) (dataReadCloser io.ReadCloser, panError pcserror.Error) { 631 pcs.lazyInit() 632 633 query := url.Values{} 634 query.Set("page", strconv.Itoa(page)) 635 query.Set("desc", "1") 636 query.Set("order", "time") 637 638 panURL := &url.URL{ 639 Scheme: "https", 640 Host: PanBaiduCom, 641 Path: "share/record", 642 RawQuery: query.Encode(), 643 } 644 baiduPCSVerbose.Infof("%s URL: %s\n", OperationShareList, panURL) 645 646 dataReadCloser, panError = pcs.sendReqReturnReadCloser(reqTypePan, OperationShareList, http.MethodGet, panURL.String(), nil, nil) 647 return 648 } 649 650 // PrepareShareSURLInfo 获取分享的详细信息, 包含密码, 只返回服务器响应数据和错误信息 651 func (pcs *BaiduPCS) PrepareShareSURLInfo(shareID int64) (dataReadCloser io.ReadCloser, panError pcserror.Error) { 652 pcs.lazyInit() 653 654 query := url.Values{} 655 query.Set("shareid", strconv.FormatInt(shareID, 10)) 656 query.Set("sign", converter.ToString(netdisksign.ShareSURLInfoSign(shareID))) 657 658 panURL := &url.URL{ 659 Scheme: "https", 660 Host: PanBaiduCom, 661 Path: "share/surlinfoinrecord", 662 RawQuery: query.Encode(), 663 } 664 baiduPCSVerbose.Infof("%s URL: %s\n", OperationShareSURLInfo, panURL) 665 666 dataReadCloser, panError = pcs.sendReqReturnReadCloser(reqTypePan, OperationShareSURLInfo, http.MethodGet, panURL.String(), nil, nil) 667 return 668 } 669 670 // PrepareRecycleList 列出回收站文件列表, 只返回服务器响应数据和错误信息 671 func (pcs *BaiduPCS) PrepareRecycleList(page int) (dataReadCloser io.ReadCloser, panError pcserror.Error) { 672 pcs.lazyInit() 673 674 panURL := pcs.generatePanURL("recycle/list", map[string]string{ 675 "num": "100", 676 "page": strconv.Itoa(page), 677 }) 678 679 baiduPCSVerbose.Infof("%s URL: %s\n", OperationRecycleList, panURL) 680 681 dataReadCloser, panError = pcs.sendReqReturnReadCloser(reqTypePan, OperationRecycleList, http.MethodGet, panURL.String(), nil, nil) 682 return 683 } 684 685 // PrepareRecycleRestore 还原回收站文件或目录, 只返回服务器响应数据和错误信息 686 func (pcs *BaiduPCS) PrepareRecycleRestore(fidList ...int64) (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 687 pcs.lazyInit() 688 689 pcsURL := pcs.generatePCSURL("file", "restore") 690 baiduPCSVerbose.Infof("%s URL: %s\n", OperationRecycleRestore, pcsURL) 691 692 fsIDList := make([]*FsIDJSON, 0, len(fidList)) 693 for k := range fidList { 694 fsIDList = append(fsIDList, &FsIDJSON{ 695 FsID: fidList[k], 696 }) 697 } 698 fsIDListJSON := FsIDListJSON{ 699 List: fsIDList, 700 } 701 702 sendData, err := jsoniter.Marshal(&fsIDListJSON) 703 if err != nil { 704 panic(err) 705 } 706 707 // 表单上传 708 mr := multipartreader.NewMultipartReader() 709 mr.AddFormFeild("param", bytes.NewReader(sendData)) 710 mr.CloseMultipart() 711 712 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationRecycleRestore, http.MethodPost, pcsURL.String(), mr, nil) 713 return 714 } 715 716 // PrepareRecycleDelete 删除回收站文件或目录, 只返回服务器响应数据和错误信息 717 func (pcs *BaiduPCS) PrepareRecycleDelete(fidList ...int64) (dataReadCloser io.ReadCloser, panError pcserror.Error) { 718 pcs.lazyInit() 719 720 panURL := pcs.generatePanURL("recycle/delete", nil) 721 baiduPCSVerbose.Infof("%s URL: %s\n", OperationRecycleDelete, panURL) 722 723 dataReadCloser, panError = pcs.sendReqReturnReadCloser(reqTypePan, OperationRecycleDelete, http.MethodPost, panURL.String(), map[string]string{ 724 "fidlist": mergeInt64List(fidList...), 725 }, map[string]string{ 726 "Content-Type": "application/x-www-form-urlencoded", 727 }) 728 return 729 } 730 731 // PrepareRecycleClear 清空回收站, 只返回服务器响应数据和错误信息 732 func (pcs *BaiduPCS) PrepareRecycleClear() (dataReadCloser io.ReadCloser, pcsError pcserror.Error) { 733 pcs.lazyInit() 734 735 pcsURL := pcs.generatePCSURL("file", "delete", map[string]string{ 736 "type": "recycle", 737 }) 738 739 baiduPCSVerbose.Infof("%s URL: %s\n", OperationRecycleClear, pcsURL) 740 741 dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationRecycleClear, http.MethodGet, pcsURL.String(), nil, nil) 742 return 743 }