2022-06-15 10:58:26 +00:00
package fs
import (
"context"
2022-06-17 13:23:44 +00:00
"fmt"
"github.com/alist-org/alist/v3/pkg/task"
"github.com/alist-org/alist/v3/pkg/utils"
2022-06-15 10:58:26 +00:00
stdpath "path"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/operations"
"github.com/pkg/errors"
)
2022-06-17 07:57:16 +00:00
var copyTaskManager = task . NewTaskManager ( )
2022-06-17 13:23:44 +00:00
func CopyBetween2Accounts ( ctx context . Context , srcAccount , dstAccount driver . Driver , srcPath , dstPath string , setStatus func ( status string ) ) error {
setStatus ( "getting src object" )
srcObj , err := operations . Get ( ctx , srcAccount , srcPath )
2022-06-15 10:58:26 +00:00
if err != nil {
return errors . WithMessagef ( err , "failed get src [%s] file" , srcPath )
}
2022-06-17 13:23:44 +00:00
if srcObj . IsDir ( ) {
2022-06-17 13:30:16 +00:00
setStatus ( "src object is dir, listing objs" )
objs , err := operations . List ( ctx , srcAccount , srcPath )
2022-06-15 10:58:26 +00:00
if err != nil {
2022-06-17 13:30:16 +00:00
return errors . WithMessagef ( err , "failed list src [%s] objs" , srcPath )
2022-06-15 10:58:26 +00:00
}
2022-06-17 13:30:16 +00:00
for _ , obj := range objs {
2022-06-17 13:23:44 +00:00
if utils . IsCanceled ( ctx ) {
return nil
}
2022-06-17 13:30:16 +00:00
srcObjPath := stdpath . Join ( srcPath , obj . GetName ( ) )
dstObjPath := stdpath . Join ( dstPath , obj . GetName ( ) )
copyTaskManager . Add ( fmt . Sprintf ( "copy [%s](%s) to [%s](%s)" , srcAccount . GetAccount ( ) . VirtualPath , srcObjPath , dstAccount . GetAccount ( ) . VirtualPath , dstObjPath ) , func ( task * task . Task ) error {
return CopyBetween2Accounts ( ctx , srcAccount , dstAccount , srcObjPath , dstObjPath , task . SetStatus )
2022-06-17 13:23:44 +00:00
} )
2022-06-15 10:58:26 +00:00
}
2022-06-17 13:23:44 +00:00
} else {
2022-06-17 13:30:16 +00:00
copyTaskManager . Add ( fmt . Sprintf ( "copy [%s](%s) to [%s](%s)" , srcAccount . GetAccount ( ) . VirtualPath , srcPath , dstAccount . GetAccount ( ) . VirtualPath , dstPath ) , func ( task * task . Task ) error {
2022-06-17 13:23:44 +00:00
return CopyFileBetween2Accounts ( task . Ctx , srcAccount , dstAccount , srcPath , dstPath , func ( percentage float64 ) {
task . SetStatus ( fmt . Sprintf ( "uploading: %2.f%" , percentage ) )
} )
} )
}
return nil
}
func CopyFileBetween2Accounts ( ctx context . Context , srcAccount , dstAccount driver . Driver , srcPath , dstPath string , up driver . UpdateProgress ) error {
srcFile , err := operations . Get ( ctx , srcAccount , srcPath )
if err != nil {
return errors . WithMessagef ( err , "failed get src [%s] file" , srcPath )
2022-06-15 10:58:26 +00:00
}
link , err := operations . Link ( ctx , srcAccount , srcPath , model . LinkArgs { } )
if err != nil {
return errors . WithMessagef ( err , "failed get [%s] link" , srcPath )
}
stream , err := getFileStreamFromLink ( srcFile , link )
if err != nil {
return errors . WithMessagef ( err , "failed get [%s] stream" , srcPath )
}
2022-06-17 13:23:44 +00:00
return operations . Put ( ctx , dstAccount , dstPath , stream , up )
2022-06-15 10:58:26 +00:00
}