File size: 2,411 Bytes
7107f0b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package tool

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/alist-org/alist/v3/internal/model"
	"github.com/alist-org/alist/v3/internal/op"
	"github.com/alist-org/alist/v3/internal/stream"
	"github.com/alist-org/alist/v3/pkg/tache"
	"github.com/alist-org/alist/v3/pkg/utils"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
)

type TransferTask struct {
	tache.Base
	file         File
	FileDir      string       `json:"file_dir"`
	DstDirPath   string       `json:"dst_dir_path"`
	TempDir      string       `json:"temp_dir"`
	DeletePolicy DeletePolicy `json:"delete_policy"`
}

func (t *TransferTask) Run() error {
	// check dstDir again
	var err error
	if (t.file == File{}) {
		t.file, err = GetFile(t.FileDir)
		if err != nil {
			return errors.Wrapf(err, "failed to get file %s", t.FileDir)
		}
	}

	storage, dstDirActualPath, err := op.GetStorageAndActualPath(t.DstDirPath)
	if err != nil {
		return errors.WithMessage(err, "failed get storage")
	}
	mimetype := utils.GetMimeType(t.file.Path)
	rc, err := t.file.GetReadCloser()
	if err != nil {
		return errors.Wrapf(err, "failed to open file %s", t.file.Path)
	}
	s := &stream.FileStream{
		Ctx: nil,
		Obj: &model.Object{
			Name:     filepath.Base(t.file.Path),
			Size:     t.file.Size,
			Modified: t.file.Modified,
			IsFolder: false,
		},
		Reader:   rc,
		Mimetype: mimetype,
		Closers:  utils.NewClosers(rc),
	}
	relDir, err := filepath.Rel(t.TempDir, filepath.Dir(t.file.Path))
	if err != nil {
		log.Errorf("find relation directory error: %v", err)
	}
	newDistDir := filepath.Join(dstDirActualPath, relDir)
	return op.Put(t.Ctx(), storage, newDistDir, s, t.SetProgress)
}

func (t *TransferTask) GetName() string {
	return fmt.Sprintf("transfer %s to [%s]", t.file.Path, t.DstDirPath)
}

func (t *TransferTask) GetStatus() string {
	return "transferring"
}

func (t *TransferTask) OnSucceeded() {
	if t.DeletePolicy == DeleteOnUploadSucceed || t.DeletePolicy == DeleteAlways {
		err := os.Remove(t.file.Path)
		if err != nil {
			log.Errorf("failed to delete file %s, error: %s", t.file.Path, err.Error())
		}
	}
}

func (t *TransferTask) OnFailed() {
	if t.DeletePolicy == DeleteOnUploadFailed || t.DeletePolicy == DeleteAlways {
		err := os.Remove(t.file.Path)
		if err != nil {
			log.Errorf("failed to delete file %s, error: %s", t.file.Path, err.Error())
		}
	}
}

var (
	TransferTaskManager *tache.Manager[*TransferTask]
)