github.com/fzfile/BaiduPCS-Go@v0.0.0-20200606205115-4408961cf336/baidupcs/cloud_dl.go (about) 1 package baidupcs 2 3 import ( 4 "errors" 5 "github.com/fzfile/BaiduPCS-Go/baidupcs/pcserror" 6 "github.com/fzfile/BaiduPCS-Go/pcstable" 7 "github.com/fzfile/BaiduPCS-Go/pcsutil/converter" 8 "github.com/fzfile/BaiduPCS-Go/pcsutil/pcstime" 9 "io" 10 "path" 11 "strconv" 12 "strings" 13 ) 14 15 type ( 16 // CloudDlFileInfo 离线下载的文件信息 17 CloudDlFileInfo struct { 18 FileName string `json:"file_name"` 19 FileSize int64 `json:"file_size"` 20 } 21 22 // CloudDlTaskInfo 离线下载的任务信息 23 CloudDlTaskInfo struct { 24 TaskID int64 25 Status int // 0下载成功, 1下载进行中, 2系统错误, 3资源不存在, 4下载超时, 5资源存在但下载失败, 6存储空间不足, 7任务取消 26 StatusText string 27 FileSize int64 // 文件大小 28 FinishedSize int64 // 文件大小 29 CreateTime int64 // 创建时间 30 StartTime int64 // 开始时间 31 FinishTime int64 // 结束时间 32 SavePath string // 保存的路径 33 SourceURL string // 资源地址 34 TaskName string // 任务名称, 一般为文件名 35 OdType int 36 FileList []*CloudDlFileInfo 37 Result int // 0查询成功,结果有效,1要查询的task_id不存在 38 } 39 40 // CloudDlTaskList 离线下载的任务信息列表 41 CloudDlTaskList []*CloudDlTaskInfo 42 43 // cloudDlTaskInfo 用于解析远程返回的JSON 44 cloudDlTaskInfo struct { 45 Status string `json:"status"` 46 FileSize string `json:"file_size"` 47 FinishedSize string `json:"finished_size"` 48 CreateTime string `json:"create_time"` 49 StartTime string `json:"start_time"` 50 FinishTime string `json:"finish_time"` 51 SavePath string `json:"save_path"` 52 SourceURL string `json:"source_url"` 53 TaskName string `json:"task_name"` 54 OdType string `json:"od_type"` 55 FileList []*struct { 56 FileName string `json:"file_name"` 57 FileSize string `json:"file_size"` 58 } `json:"file_list"` 59 Result int `json:"result"` 60 } 61 62 taskIDJSON struct { 63 TaskID string `json:"task_id"` 64 } 65 66 taskIDInt64JSON struct { 67 TaskID int64 `json:"task_id"` 68 } 69 70 cloudDlAddTaskJSON struct { 71 *pcserror.PCSErrInfo 72 taskIDInt64JSON 73 } 74 75 cloudDlQueryTaskJSON struct { 76 TaskInfo map[string]*cloudDlTaskInfo `json:"task_info"` 77 *pcserror.PCSErrInfo 78 } 79 80 cloudDlListTaskJSON struct { 81 TaskInfo []*taskIDJSON `json:"task_info"` 82 *pcserror.PCSErrInfo 83 } 84 85 cloudDlClearJSON struct { 86 Total int `json:"total"` 87 *pcserror.PCSErrInfo 88 } 89 ) 90 91 func (ci *cloudDlTaskInfo) convert() *CloudDlTaskInfo { 92 ci2 := &CloudDlTaskInfo{ 93 Status: converter.MustInt(ci.Status), 94 FileSize: converter.MustInt64(ci.FileSize), 95 FinishedSize: converter.MustInt64(ci.FinishedSize), 96 CreateTime: converter.MustInt64(ci.CreateTime), 97 StartTime: converter.MustInt64(ci.StartTime), 98 FinishTime: converter.MustInt64(ci.FinishTime), 99 SavePath: ci.SavePath, 100 SourceURL: ci.SourceURL, 101 TaskName: ci.TaskName, 102 OdType: converter.MustInt(ci.OdType), 103 Result: ci.Result, 104 } 105 106 ci2.FileList = make([]*CloudDlFileInfo, 0, len(ci.FileList)) 107 for _, v := range ci.FileList { 108 if v == nil { 109 continue 110 } 111 112 ci2.FileList = append(ci2.FileList, &CloudDlFileInfo{ 113 FileName: v.FileName, 114 FileSize: converter.MustInt64(v.FileSize), 115 }) 116 } 117 118 return ci2 119 } 120 121 // CloudDlAddTask 添加离线下载任务 122 func (pcs *BaiduPCS) CloudDlAddTask(sourceURL, savePath string) (taskID int64, pcsError pcserror.Error) { 123 dataReadCloser, pcsError := pcs.PrepareCloudDlAddTask(sourceURL, savePath) 124 if pcsError != nil { 125 return 126 } 127 128 defer dataReadCloser.Close() 129 130 errInfo := pcserror.NewPCSErrorInfo(OperationCloudDlAddTask) 131 taskInfo := cloudDlAddTaskJSON{ 132 PCSErrInfo: errInfo, 133 } 134 135 pcsError = pcserror.HandleJSONParse(OperationCloudDlAddTask, dataReadCloser, &taskInfo) 136 if pcsError != nil { 137 return 138 } 139 140 return taskInfo.TaskID, nil 141 } 142 143 func (pcs *BaiduPCS) cloudDlQueryTask(op string, taskIDs []int64) (cl CloudDlTaskList, pcsError pcserror.Error) { 144 errInfo := pcserror.NewPCSErrorInfo(op) 145 if len(taskIDs) == 0 { 146 errInfo.ErrType = pcserror.ErrTypeOthers 147 errInfo.Err = errors.New("no input any task_ids") 148 return nil, errInfo 149 } 150 151 // TODO: 支持100条以上的task_id查询 152 if len(taskIDs) > 100 { 153 taskIDs = taskIDs[:100] 154 } 155 156 taskStrIDs := make([]string, len(taskIDs)) 157 for k := range taskStrIDs { 158 taskStrIDs[k] = strconv.FormatInt(taskIDs[k], 10) 159 } 160 161 dataReadCloser, pcsError := pcs.PrepareCloudDlQueryTask(strings.Join(taskStrIDs, ",")) 162 if pcsError != nil { 163 return 164 } 165 166 defer dataReadCloser.Close() 167 168 taskInfo := cloudDlQueryTaskJSON{ 169 PCSErrInfo: errInfo, 170 } 171 172 pcsError = pcserror.HandleJSONParse(OperationCloudDlQueryTask, dataReadCloser, &taskInfo) 173 if pcsError != nil { 174 return 175 } 176 177 var v2 *CloudDlTaskInfo 178 cl = make(CloudDlTaskList, 0, len(taskStrIDs)) 179 for k := range taskStrIDs { 180 var err error 181 v := taskInfo.TaskInfo[taskStrIDs[k]] 182 if v == nil { 183 continue 184 } 185 186 v2 = v.convert() 187 188 v2.TaskID, err = strconv.ParseInt(taskStrIDs[k], 10, 64) 189 if err != nil { 190 continue 191 } 192 193 v2.ParseText() 194 cl = append(cl, v2) 195 } 196 197 return cl, nil 198 } 199 200 // CloudDlQueryTask 精确查询离线下载任务 201 func (pcs *BaiduPCS) CloudDlQueryTask(taskIDs []int64) (cl CloudDlTaskList, pcsError pcserror.Error) { 202 return pcs.cloudDlQueryTask(OperationCloudDlQueryTask, taskIDs) 203 } 204 205 // CloudDlListTask 查询离线下载任务列表 206 func (pcs *BaiduPCS) CloudDlListTask() (cl CloudDlTaskList, pcsError pcserror.Error) { 207 dataReadCloser, pcsError := pcs.PrepareCloudDlListTask() 208 if pcsError != nil { 209 return 210 } 211 212 defer dataReadCloser.Close() 213 214 errInfo := pcserror.NewPCSErrorInfo(OperationCloudDlListTask) 215 taskInfo := cloudDlListTaskJSON{ 216 PCSErrInfo: errInfo, 217 } 218 219 pcsError = pcserror.HandleJSONParse(OperationCloudDlListTask, dataReadCloser, &taskInfo) 220 if pcsError != nil { 221 return 222 } 223 224 // 没有任务 225 if len(taskInfo.TaskInfo) <= 0 { 226 return CloudDlTaskList{}, nil 227 } 228 229 var ( 230 taskID int64 231 taskIDs = make([]int64, 0, len(taskInfo.TaskInfo)) 232 ) 233 for _, v := range taskInfo.TaskInfo { 234 if v == nil { 235 continue 236 } 237 var err error 238 if taskID, err = strconv.ParseInt(v.TaskID, 10, 64); err == nil { 239 taskIDs = append(taskIDs, taskID) 240 } 241 } 242 243 cl, pcsError = pcs.cloudDlQueryTask(OperationCloudDlListTask, taskIDs) 244 if pcsError != nil { 245 return nil, pcsError 246 } 247 248 return cl, nil 249 } 250 251 func (pcs *BaiduPCS) cloudDlManipTask(op string, taskID int64) (pcsError pcserror.Error) { 252 var dataReadCloser io.ReadCloser 253 254 switch op { 255 case OperationCloudDlCancelTask: 256 dataReadCloser, pcsError = pcs.PrepareCloudDlCancelTask(taskID) 257 case OperationCloudDlDeleteTask: 258 dataReadCloser, pcsError = pcs.PrepareCloudDlDeleteTask(taskID) 259 default: 260 panic("unknown op, " + op) 261 } 262 if pcsError != nil { 263 return 264 } 265 266 defer dataReadCloser.Close() 267 268 errInfo := pcserror.DecodePCSJSONError(op, dataReadCloser) 269 return errInfo 270 } 271 272 // CloudDlCancelTask 取消离线下载任务 273 func (pcs *BaiduPCS) CloudDlCancelTask(taskID int64) (pcsError pcserror.Error) { 274 return pcs.cloudDlManipTask(OperationCloudDlCancelTask, taskID) 275 } 276 277 // CloudDlDeleteTask 删除离线下载任务 278 func (pcs *BaiduPCS) CloudDlDeleteTask(taskID int64) (pcsError pcserror.Error) { 279 return pcs.cloudDlManipTask(OperationCloudDlDeleteTask, taskID) 280 } 281 282 // CloudDlClearTask 清空离线下载任务记录 283 func (pcs *BaiduPCS) CloudDlClearTask() (total int, pcsError pcserror.Error) { 284 dataReadCloser, pcsError := pcs.PrepareCloudDlClearTask() 285 if pcsError != nil { 286 return 287 } 288 289 defer dataReadCloser.Close() 290 291 errInfo := pcserror.NewPCSErrorInfo(OperationCloudDlClearTask) 292 clearInfo := cloudDlClearJSON{ 293 PCSErrInfo: errInfo, 294 } 295 296 pcsError = pcserror.HandleJSONParse(OperationCloudDlClearTask, dataReadCloser, &clearInfo) 297 if pcsError != nil { 298 return 299 } 300 301 return clearInfo.Total, nil 302 } 303 304 // ParseText 解析状态码 305 func (ci *CloudDlTaskInfo) ParseText() { 306 switch ci.Status { 307 case 0: 308 ci.StatusText = "下载成功" 309 case 1: 310 ci.StatusText = "下载进行中" 311 case 2: 312 ci.StatusText = "系统错误" 313 case 3: 314 ci.StatusText = "资源不存在" 315 case 4: 316 ci.StatusText = "下载超时" 317 case 5: 318 ci.StatusText = "资源存在但下载失败" 319 case 6: 320 ci.StatusText = "存储空间不足" 321 case 7: 322 ci.StatusText = "任务取消" 323 default: 324 ci.StatusText = "未知状态码: " + strconv.Itoa(ci.Status) 325 } 326 } 327 328 func (cl CloudDlTaskList) String() string { 329 builder := &strings.Builder{} 330 tb := pcstable.NewTable(builder) 331 tb.SetHeader([]string{"#", "任务ID", "任务名称", "文件大小", "创建日期", "保存路径", "资源地址", "状态"}) 332 for k, v := range cl { 333 tb.Append([]string{strconv.Itoa(k), strconv.FormatInt(v.TaskID, 10), v.TaskName, converter.ConvertFileSize(v.FileSize), pcstime.FormatTime(v.CreateTime), path.Clean(v.SavePath), v.SourceURL, v.StatusText}) 334 } 335 tb.Render() 336 return builder.String() 337 }