github.com/fzfile/BaiduPCS-Go@v0.0.0-20200606205115-4408961cf336/baidupcs/baidupcs.go (about) 1 // Package baidupcs BaiduPCS RESTful API 工具包 2 package baidupcs 3 4 import ( 5 "errors" 6 "github.com/fzfile/BaiduPCS-Go/baidupcs/expires/cachemap" 7 "github.com/fzfile/BaiduPCS-Go/baidupcs/internal/panhome" 8 "github.com/fzfile/BaiduPCS-Go/baidupcs/pcserror" 9 "github.com/fzfile/BaiduPCS-Go/pcsverbose" 10 "github.com/fzfile/BaiduPCS-Go/requester" 11 "net/http" 12 "net/http/cookiejar" 13 "net/url" 14 "strconv" 15 ) 16 17 const ( 18 // OperationGetUK 获取UK 19 OperationGetUK = "获取UK" 20 // OperationQuotaInfo 获取当前用户空间配额信息 21 OperationQuotaInfo = "获取当前用户空间配额信息" 22 // OperationFilesDirectoriesMeta 获取文件/目录的元信息 23 OperationFilesDirectoriesMeta = "获取文件/目录的元信息" 24 // OperationFilesDirectoriesList 获取目录下的文件列表 25 OperationFilesDirectoriesList = "获取目录下的文件列表" 26 // OperationSearch 搜索 27 OperationSearch = "搜索" 28 // OperationRemove 删除文件/目录 29 OperationRemove = "删除文件/目录" 30 // OperationMkdir 创建目录 31 OperationMkdir = "创建目录" 32 // OperationRename 重命名文件/目录 33 OperationRename = "重命名文件/目录" 34 // OperationCopy 拷贝文件/目录 35 OperationCopy = "拷贝文件/目录" 36 // OperationMove 移动文件/目录 37 OperationMove = "移动文件/目录" 38 // OperationRapidUpload 秒传文件 39 OperationRapidUpload = "秒传文件" 40 // OperationUpload 上传单个文件 41 OperationUpload = "上传单个文件" 42 // OperationUploadTmpFile 分片上传—文件分片及上传 43 OperationUploadTmpFile = "分片上传—文件分片及上传" 44 // OperationUploadCreateSuperFile 分片上传—合并分片文件 45 OperationUploadCreateSuperFile = "分片上传—合并分片文件" 46 // OperationUploadPrecreate 分片上传—Precreate 47 OperationUploadPrecreate = "分片上传—Precreate" 48 // OperationUploadSuperfile2 分片上传—Superfile2 49 OperationUploadSuperfile2 = "分片上传—Superfile2" 50 // OperationDownloadFile 下载单个文件 51 OperationDownloadFile = "下载单个文件" 52 // OperationDownloadStreamFile 下载流式文件 53 OperationDownloadStreamFile = "下载流式文件" 54 // OperationLocateDownload 获取下载链接 55 OperationLocateDownload = "获取下载链接" 56 // OperationLocatePanAPIDownload 从百度网盘首页获取下载链接 57 OperationLocatePanAPIDownload = "获取下载链接2" 58 // OperationCloudDlAddTask 添加离线下载任务 59 OperationCloudDlAddTask = "添加离线下载任务" 60 // OperationCloudDlQueryTask 精确查询离线下载任务 61 OperationCloudDlQueryTask = "精确查询离线下载任务" 62 // OperationCloudDlListTask 查询离线下载任务列表 63 OperationCloudDlListTask = "查询离线下载任务列表" 64 // OperationCloudDlCancelTask 取消离线下载任务 65 OperationCloudDlCancelTask = "取消离线下载任务" 66 // OperationCloudDlDeleteTask 删除离线下载任务 67 OperationCloudDlDeleteTask = "删除离线下载任务" 68 // OperationCloudDlClearTask 清空离线下载任务记录 69 OperationCloudDlClearTask = "清空离线下载任务记录" 70 // OperationShareSet 创建分享链接 71 OperationShareSet = "创建分享链接" 72 // OperationShareCancel 取消分享 73 OperationShareCancel = "取消分享" 74 // OperationShareList 列出分享列表 75 OperationShareList = "列出分享列表" 76 // OperationShareSURLInfo 获取分享详细信息 77 OperationShareSURLInfo = "获取分享详细信息" 78 // OperationRecycleList 列出回收站文件列表 79 OperationRecycleList = "列出回收站文件列表" 80 // OperationRecycleRestore 还原回收站文件或目录 81 OperationRecycleRestore = "还原回收站文件或目录" 82 // OperationRecycleDelete 删除回收站文件或目录 83 OperationRecycleDelete = "删除回收站文件或目录" 84 // OperationRecycleClear 清空回收站 85 OperationRecycleClear = "清空回收站" 86 87 // OperationExportFileInfo 导出文件信息 88 OperationExportFileInfo = "导出文件信息" 89 // OperationGetRapidUploadInfo 获取文件秒传信息 90 OperationGetRapidUploadInfo = "获取文件秒传信息" 91 // OperationFixMD5 修复文件md5 92 OperationFixMD5 = "修复文件md5" 93 // OperrationMatchPathByShellPattern 通配符匹配文件路径 94 OperrationMatchPathByShellPattern = "通配符匹配文件路径" 95 96 // PCSBaiduCom pcs api地址 97 PCSBaiduCom = "pcs.baidu.com" 98 // PanBaiduCom 网盘首页api地址 99 PanBaiduCom = "pan.baidu.com" 100 // YunBaiduCom 网盘首页api地址2 101 YunBaiduCom = "yun.baidu.com" 102 // PanAppID 百度网盘appid 103 PanAppID = "250528" 104 // NetdiskUA 网盘客户端ua 105 NetdiskUA = "netdisk;2.2.51.6;netdisk;10.0.63;PC;android-android" 106 // DotBaiduCom .baidu.com 107 DotBaiduCom = ".baidu.com" 108 // PathSeparator 路径分隔符 109 PathSeparator = "/" 110 ) 111 112 var ( 113 baiduPCSVerbose = pcsverbose.New("BAIDUPCS") 114 115 baiduComURL = &url.URL{ 116 Scheme: "http", 117 Host: "baidu.com", 118 } 119 120 baiduPcsComURL = &url.URL{ 121 Scheme: "http", 122 Host: "baidupcs.com", 123 } 124 ) 125 126 type ( 127 // BaiduPCS 百度 PCS API 详情 128 BaiduPCS struct { 129 appID int // app_id 130 isHTTPS bool // 是否启用https 131 uid uint64 // 百度uid 132 client *requester.HTTPClient // http 客户端 133 pcsUA string 134 panUA string 135 isSetPanUA bool 136 ph *panhome.PanHome 137 cacheOpMap cachemap.CacheOpMap 138 } 139 140 userInfoJSON struct { 141 *pcserror.PanErrorInfo 142 Records []struct { 143 Uk int64 `json:"uk"` 144 } `json:"records"` 145 } 146 ) 147 148 // NewPCS 提供app_id, 百度BDUSS, 返回 BaiduPCS 对象 149 func NewPCS(appID int, bduss string) *BaiduPCS { 150 client := requester.NewHTTPClient() 151 client.ResetCookiejar() 152 client.Jar.SetCookies(baiduComURL, []*http.Cookie{ 153 &http.Cookie{ 154 Name: "BDUSS", 155 Value: bduss, 156 Domain: DotBaiduCom, 157 }, 158 }) 159 160 return &BaiduPCS{ 161 appID: appID, 162 client: client, 163 } 164 } 165 166 // NewPCSWithClient 提供app_id, 自定义客户端, 返回 BaiduPCS 对象 167 func NewPCSWithClient(appID int, client *requester.HTTPClient) *BaiduPCS { 168 pcs := &BaiduPCS{ 169 appID: appID, 170 client: client, 171 } 172 return pcs 173 } 174 175 // NewPCSWithCookieStr 提供app_id, cookie 字符串, 返回 BaiduPCS 对象 176 func NewPCSWithCookieStr(appID int, cookieStr string) *BaiduPCS { 177 pcs := &BaiduPCS{ 178 appID: appID, 179 client: requester.NewHTTPClient(), 180 } 181 182 cookies := requester.ParseCookieStr(cookieStr) 183 for _, cookie := range cookies { 184 cookie.Domain = DotBaiduCom 185 } 186 187 jar, _ := cookiejar.New(nil) 188 jar.SetCookies(baiduComURL, cookies) 189 pcs.client.SetCookiejar(jar) 190 191 return pcs 192 } 193 194 func (pcs *BaiduPCS) lazyInit() { 195 if pcs.client == nil { 196 pcs.client = requester.NewHTTPClient() 197 } 198 if pcs.ph == nil { 199 pcs.ph = panhome.NewPanHome(pcs.client) 200 } 201 if !pcs.isSetPanUA { 202 pcs.panUA = NetdiskUA 203 } 204 } 205 206 // GetClient 获取当前的http client 207 func (pcs *BaiduPCS) GetClient() *requester.HTTPClient { 208 pcs.lazyInit() 209 return pcs.client 210 } 211 212 // GetBDUSS 获取BDUSS 213 func (pcs *BaiduPCS) GetBDUSS() (bduss string) { 214 if pcs.client == nil || pcs.client.Jar == nil { 215 return "" 216 } 217 cookies := pcs.client.Jar.Cookies(baiduComURL) 218 for _, cookie := range cookies { 219 if cookie.Name == "BDUSS" { 220 return cookie.Value 221 } 222 } 223 return "" 224 } 225 226 // SetAPPID 设置app_id 227 func (pcs *BaiduPCS) SetAPPID(appID int) { 228 pcs.appID = appID 229 } 230 231 // SetUID 设置百度UID 232 // 只有locatedownload才需要设置此项 233 func (pcs *BaiduPCS) SetUID(uid uint64) { 234 pcs.uid = uid 235 } 236 237 // SetStoken 设置stoken 238 func (pcs *BaiduPCS) SetStoken(stoken string) { 239 pcs.lazyInit() 240 if pcs.client.Jar == nil { 241 pcs.client.ResetCookiejar() 242 } 243 244 pcs.client.Jar.SetCookies(baiduComURL, []*http.Cookie{ 245 &http.Cookie{ 246 Name: "STOKEN", 247 Value: stoken, 248 Domain: DotBaiduCom, 249 }, 250 }) 251 } 252 253 // SetPCSUserAgent 设置 PCS User-Agent 254 func (pcs *BaiduPCS) SetPCSUserAgent(ua string) { 255 pcs.pcsUA = ua 256 } 257 258 // SetPanUserAgent 设置 Pan User-Agent 259 func (pcs *BaiduPCS) SetPanUserAgent(ua string) { 260 pcs.panUA = ua 261 pcs.isSetPanUA = true 262 } 263 264 // SetHTTPS 是否启用https连接 265 func (pcs *BaiduPCS) SetHTTPS(https bool) { 266 pcs.isHTTPS = https 267 } 268 269 // URL 返回 url 270 func (pcs *BaiduPCS) URL() *url.URL { 271 return &url.URL{ 272 Scheme: GetHTTPScheme(pcs.isHTTPS), 273 Host: PCSBaiduCom, 274 } 275 } 276 277 func (pcs *BaiduPCS) getPanUAHeader() (header map[string]string) { 278 return map[string]string{ 279 "User-Agent": pcs.panUA, 280 } 281 } 282 283 func (pcs *BaiduPCS) generatePCSURL(subPath, method string, param ...map[string]string) *url.URL { 284 pcsURL := pcs.URL() 285 pcsURL.Path = "/rest/2.0/pcs/" + subPath 286 287 uv := pcsURL.Query() 288 uv.Set("app_id", strconv.Itoa(pcs.appID)) 289 uv.Set("method", method) 290 for k := range param { 291 for k2 := range param[k] { 292 uv.Set(k2, param[k][k2]) 293 } 294 } 295 296 pcsURL.RawQuery = uv.Encode() 297 return pcsURL 298 } 299 300 func (pcs *BaiduPCS) generatePCSURL2(subPath, method string, param ...map[string]string) *url.URL { 301 pcsURL2 := &url.URL{ 302 Scheme: GetHTTPScheme(pcs.isHTTPS), 303 Host: PanBaiduCom, 304 Path: "/rest/2.0/" + subPath, 305 } 306 307 uv := pcsURL2.Query() 308 uv.Set("app_id", PanAppID) 309 uv.Set("method", method) 310 for k := range param { 311 for k2 := range param[k] { 312 uv.Set(k2, param[k][k2]) 313 } 314 } 315 316 pcsURL2.RawQuery = uv.Encode() 317 return pcsURL2 318 } 319 320 func (pcs *BaiduPCS) generatePanURL(subPath string, param map[string]string) *url.URL { 321 panURL := url.URL{ 322 Scheme: GetHTTPScheme(pcs.isHTTPS), 323 Host: PanBaiduCom, 324 Path: "/api/" + subPath, 325 } 326 327 if param != nil { 328 uv := url.Values{} 329 for k := range param { 330 uv.Set(k, param[k]) 331 } 332 panURL.RawQuery = uv.Encode() 333 } 334 return &panURL 335 } 336 337 // UK 获取用户 UK 338 func (pcs *BaiduPCS) UK() (uk int64, pcsError pcserror.Error) { 339 dataReadCloser, pcsError := pcs.PrepareUK() 340 if pcsError != nil { 341 return 342 } 343 344 defer dataReadCloser.Close() 345 346 errInfo := pcserror.NewPanErrorInfo(OperationGetUK) 347 jsonData := userInfoJSON{ 348 PanErrorInfo: errInfo, 349 } 350 351 pcsError = pcserror.HandleJSONParse(OperationGetUK, dataReadCloser, &jsonData) 352 if pcsError != nil { 353 return 354 } 355 356 if len(jsonData.Records) != 1 { 357 errInfo.ErrType = pcserror.ErrTypeOthers 358 errInfo.Err = errors.New("Unknown remote data") 359 return 0, errInfo 360 } 361 362 return jsonData.Records[0].Uk, nil 363 }