Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/internal/offline_download/aria2/aria2.go
1562 views
1
package aria2
2
3
import (
4
"context"
5
"fmt"
6
"strconv"
7
"time"
8
9
"github.com/alist-org/alist/v3/internal/errs"
10
11
"github.com/alist-org/alist/v3/internal/conf"
12
"github.com/alist-org/alist/v3/internal/model"
13
"github.com/alist-org/alist/v3/internal/offline_download/tool"
14
"github.com/alist-org/alist/v3/internal/setting"
15
"github.com/alist-org/alist/v3/pkg/aria2/rpc"
16
"github.com/pkg/errors"
17
log "github.com/sirupsen/logrus"
18
)
19
20
var notify = NewNotify()
21
22
type Aria2 struct {
23
client rpc.Client
24
}
25
26
func (a *Aria2) Run(task *tool.DownloadTask) error {
27
return errs.NotSupport
28
}
29
30
func (a *Aria2) Name() string {
31
return "aria2"
32
}
33
34
func (a *Aria2) Items() []model.SettingItem {
35
// aria2 settings
36
return []model.SettingItem{
37
{Key: conf.Aria2Uri, Value: "http://localhost:6800/jsonrpc", Type: conf.TypeString, Group: model.OFFLINE_DOWNLOAD, Flag: model.PRIVATE},
38
{Key: conf.Aria2Secret, Value: "", Type: conf.TypeString, Group: model.OFFLINE_DOWNLOAD, Flag: model.PRIVATE},
39
}
40
}
41
42
func (a *Aria2) Init() (string, error) {
43
a.client = nil
44
uri := setting.GetStr(conf.Aria2Uri)
45
secret := setting.GetStr(conf.Aria2Secret)
46
c, err := rpc.New(context.Background(), uri, secret, 4*time.Second, notify)
47
if err != nil {
48
return "", errors.Wrap(err, "failed to init aria2 client")
49
}
50
version, err := c.GetVersion()
51
if err != nil {
52
return "", errors.Wrapf(err, "failed get aria2 version")
53
}
54
a.client = c
55
log.Infof("using aria2 version: %s", version.Version)
56
return fmt.Sprintf("aria2 version: %s", version.Version), nil
57
}
58
59
func (a *Aria2) IsReady() bool {
60
return a.client != nil
61
}
62
63
func (a *Aria2) AddURL(args *tool.AddUrlArgs) (string, error) {
64
options := map[string]interface{}{
65
"dir": args.TempDir,
66
}
67
gid, err := a.client.AddURI([]string{args.Url}, options)
68
if err != nil {
69
return "", err
70
}
71
notify.Signals.Store(gid, args.Signal)
72
return gid, nil
73
}
74
75
func (a *Aria2) Remove(task *tool.DownloadTask) error {
76
_, err := a.client.Remove(task.GID)
77
return err
78
}
79
80
func (a *Aria2) Status(task *tool.DownloadTask) (*tool.Status, error) {
81
info, err := a.client.TellStatus(task.GID)
82
if err != nil {
83
return nil, err
84
}
85
total, err := strconv.ParseInt(info.TotalLength, 10, 64)
86
if err != nil {
87
total = 0
88
}
89
downloaded, err := strconv.ParseUint(info.CompletedLength, 10, 64)
90
if err != nil {
91
downloaded = 0
92
}
93
s := &tool.Status{
94
Completed: info.Status == "complete",
95
Err: err,
96
TotalBytes: total,
97
}
98
s.Progress = float64(downloaded) / float64(total) * 100
99
if len(info.FollowedBy) != 0 {
100
s.NewGID = info.FollowedBy[0]
101
notify.Signals.Delete(task.GID)
102
notify.Signals.Store(s.NewGID, task.Signal)
103
}
104
switch info.Status {
105
case "complete":
106
s.Completed = true
107
case "error":
108
s.Err = errors.Errorf("failed to download %s, error: %s", task.GID, info.ErrorMessage)
109
case "active":
110
s.Status = "aria2: " + info.Status
111
if info.Seeder == "true" {
112
s.Completed = true
113
}
114
case "waiting", "paused":
115
s.Status = "aria2: " + info.Status
116
case "removed":
117
s.Err = errors.Errorf("failed to download %s, removed", task.GID)
118
default:
119
return nil, errors.Errorf("[aria2] unknown status %s", info.Status)
120
}
121
return s, nil
122
}
123
124
var _ tool.Tool = (*Aria2)(nil)
125
126
func init() {
127
tool.Tools.Add(&Aria2{})
128
}
129
130