@@ -14,6 +14,7 @@ import (
1414 "time"
1515
1616 "github.com/OpenListTeam/OpenList/v4/drivers/base"
17+ "github.com/OpenListTeam/OpenList/v4/internal/model"
1718 "github.com/OpenListTeam/OpenList/v4/pkg/utils"
1819 "github.com/go-resty/resty/v2"
1920 jsoniter "github.com/json-iterator/go"
@@ -43,9 +44,16 @@ const (
4344 S3Auth = MainApi + "/file/s3_upload_object/auth"
4445 UploadCompleteV2 = MainApi + "/file/upload_complete/v2"
4546 S3Complete = MainApi + "/file/s3_complete_multipart_upload"
47+
48+ OfflineResolve = MainApi + "/v2/offline_download/task/resolve"
49+ OfflineSubmit = MainApi + "/v2/offline_download/task/submit"
50+ OfflineTaskList = MainApi + "/offline_download/task/list"
51+ OfflineTaskDelete = MainApi + "/offline_download/task/delete"
4652 // AuthKeySalt = "8-8D$sL8gPjom7bk#cY"
4753)
4854
55+ var ErrOfflineTaskNotFound = errors .New ("offline task not found" )
56+
4957func signPath (path string , os string , version string ) (k string , v string ) {
5058 table := []byte {'a' , 'd' , 'e' , 'f' , 'g' , 'h' , 'l' , 'm' , 'y' , 'i' , 'j' , 'n' , 'o' , 'p' , 'k' , 'q' , 'r' , 's' , 't' , 'u' , 'b' , 'c' , 'v' , 'w' , 's' , 'z' }
5159 random := fmt .Sprintf ("%.f" , math .Round (1e7 * rand .Float64 ()))
@@ -238,6 +246,115 @@ do:
238246 return body , nil
239247}
240248
249+ func (d * Pan123 ) OfflineDownload (ctx context.Context , uri string , dstDir model.Obj ) (int64 , error ) {
250+ var resolveResp offlineResolveResp
251+ _ , err := d .Request (OfflineResolve , http .MethodPost , func (req * resty.Request ) {
252+ req .SetContext (ctx ).SetBody (base.Json {
253+ "urls" : uri ,
254+ })
255+ }, & resolveResp )
256+ if err != nil {
257+ return 0 , err
258+ }
259+ if len (resolveResp .Data .List ) == 0 {
260+ return 0 , fmt .Errorf ("offline resolve failed: empty response" )
261+ }
262+ if resolveResp .Data .List [0 ].Result != 0 {
263+ msg := resolveResp .Data .List [0 ].ErrMsg
264+ if msg == "" {
265+ msg = "offline resolve failed"
266+ }
267+ return 0 , fmt .Errorf ("%s" , msg )
268+ }
269+ resourceID := resolveResp .Data .List [0 ].ID
270+ if resourceID == 0 {
271+ return 0 , fmt .Errorf ("offline resolve failed: empty resource id" )
272+ }
273+ selectFileIDs := make ([]int64 , 0 , len (resolveResp .Data .List [0 ].Files ))
274+ for _ , f := range resolveResp .Data .List [0 ].Files {
275+ if f .ID > 0 {
276+ selectFileIDs = append (selectFileIDs , f .ID )
277+ }
278+ }
279+ if len (selectFileIDs ) == 0 {
280+ return 0 , fmt .Errorf ("offline resolve failed: empty file list" )
281+ }
282+ uploadDir , err := strconv .ParseInt (dstDir .GetID (), 10 , 64 )
283+ if err != nil {
284+ return 0 , fmt .Errorf ("invalid destination dir id: %s" , dstDir .GetID ())
285+ }
286+
287+ var submitResp offlineSubmitResp
288+ _ , err = d .Request (OfflineSubmit , http .MethodPost , func (req * resty.Request ) {
289+ req .SetContext (ctx ).SetBody (base.Json {
290+ "resource_list" : []base.Json {
291+ {
292+ "resource_id" : resourceID ,
293+ "select_file_id" : selectFileIDs ,
294+ },
295+ },
296+ "upload_dir" : uploadDir ,
297+ })
298+ }, & submitResp )
299+ if err != nil {
300+ return 0 , err
301+ }
302+ if len (submitResp .Data .TaskList ) == 0 {
303+ return 0 , fmt .Errorf ("offline submit failed: empty task list" )
304+ }
305+ if submitResp .Data .TaskList [0 ].Result != 0 {
306+ return 0 , fmt .Errorf ("offline submit failed" )
307+ }
308+ if submitResp .Data .TaskList [0 ].TaskID == 0 {
309+ return 0 , fmt .Errorf ("offline submit failed: empty task id" )
310+ }
311+ return submitResp .Data .TaskList [0 ].TaskID , nil
312+ }
313+
314+ func (d * Pan123 ) GetOfflineTask (ctx context.Context , taskID int64 ) (* offlineTask , error ) {
315+ if taskID == 0 {
316+ return nil , fmt .Errorf ("invalid task id" )
317+ }
318+ page := 1
319+ pageSize := 100
320+ statusArr := []int {0 , 1 , 2 , 3 }
321+ for {
322+ var listResp offlineTaskListResp
323+ _ , err := d .Request (OfflineTaskList , http .MethodPost , func (req * resty.Request ) {
324+ req .SetContext (ctx ).SetBody (base.Json {
325+ "current_page" : page ,
326+ "page_size" : pageSize ,
327+ "status_arr" : statusArr ,
328+ })
329+ }, & listResp )
330+ if err != nil {
331+ return nil , err
332+ }
333+ for i := range listResp .Data .List {
334+ if listResp .Data .List [i ].TaskID == taskID {
335+ return & listResp .Data .List [i ], nil
336+ }
337+ }
338+ if len (listResp .Data .List ) == 0 || page * pageSize >= listResp .Data .Total {
339+ break
340+ }
341+ page ++
342+ }
343+ return nil , ErrOfflineTaskNotFound
344+ }
345+
346+ func (d * Pan123 ) DeleteOfflineTasks (ctx context.Context , taskIDs []int64 ) error {
347+ if len (taskIDs ) == 0 {
348+ return nil
349+ }
350+ _ , err := d .Request (OfflineTaskDelete , http .MethodPost , func (req * resty.Request ) {
351+ req .SetContext (ctx ).SetBody (base.Json {
352+ "task_ids" : taskIDs ,
353+ })
354+ }, nil )
355+ return err
356+ }
357+
241358func (d * Pan123 ) getFiles (ctx context.Context , parentId string , name string ) ([]File , error ) {
242359 page := 1
243360 total := 0
0 commit comments