package aria2 import ( "context" "path/filepath" "strconv" "strings" "time" model "github.com/cloudreve/Cloudreve/v3/models" "github.com/cloudreve/Cloudreve/v3/pkg/aria2/rpc" "github.com/cloudreve/Cloudreve/v3/pkg/util" ) // RPCService 通过RPC服务的Aria2任务管理器 type RPCService struct { options *clientOptions Caller rpc.Client } type clientOptions struct { Options map[string]interface{} // 创建下载时额外添加的设置 } // Init 初始化 func (client *RPCService) Init(server, secret string, timeout int, options map[string]interface{}) error { // 客户端已存在,则关闭先前连接 if client.Caller != nil { client.Caller.Close() } client.options = &clientOptions{ Options: options, } caller, err := rpc.New(context.Background(), server, secret, time.Duration(timeout)*time.Second, EventNotifier) client.Caller = caller return err } // Status 查询下载状态 func (client *RPCService) Status(task *model.Download) (rpc.StatusInfo, error) { res, err := client.Caller.TellStatus(task.GID) if err != nil { // 失败后重试 util.Log().Debug("无法获取离线下载状态,%s,10秒钟后重试", err) time.Sleep(time.Duration(10) * time.Second) res, err = client.Caller.TellStatus(task.GID) } return res, err } // Cancel 取消下载 func (client *RPCService) Cancel(task *model.Download) error { // 取消下载任务 _, err := client.Caller.Remove(task.GID) if err != nil { util.Log().Warning("无法取消离线下载任务[%s], %s", task.GID, err) } //// 删除临时文件 //util.Log().Debug("离线下载任务[%s]已取消,1 分钟后删除临时文件", task.GID) //go func(task *model.Download) { // select { // case <-time.After(time.Duration(60) * time.Second): // err := os.RemoveAll(task.Parent) // if err != nil { // util.Log().Warning("无法删除离线下载临时目录[%s], %s", task.Parent, err) // } // } //}(task) return err } // Select 选取要下载的文件 func (client *RPCService) Select(task *model.Download, files []int) error { var selected = make([]string, len(files)) for i := 0; i < len(files); i++ { selected[i] = strconv.Itoa(files[i]) } _, err := client.Caller.ChangeOption(task.GID, map[string]interface{}{"select-file": strings.Join(selected, ",")}) return err } // CreateTask 创建新任务 func (client *RPCService) CreateTask(task *model.Download, groupOptions map[string]interface{}) error { // 生成存储路径 path := filepath.Join( model.GetSettingByName("aria2_temp_path"), "aria2", strconv.FormatInt(time.Now().UnixNano(), 10), ) // 创建下载任务 options := map[string]interface{}{ "dir": path, } for k, v := range client.options.Options { options[k] = v } for k, v := range groupOptions { options[k] = v } gid, err := client.Caller.AddURI(task.Source, options) if err != nil || gid == "" { return err } // 保存到数据库 task.GID = gid _, err = task.Create() if err != nil { return err } // 创建任务监控 NewMonitor(task) return nil }