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