mirror of https://github.com/cloudreve/Cloudreve
				
				
				
			
		
			
				
	
	
		
			134 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
package aria2
 | 
						|
 | 
						|
import (
 | 
						|
	model "github.com/HFO4/cloudreve/models"
 | 
						|
	"github.com/HFO4/cloudreve/pkg/serializer"
 | 
						|
	"github.com/HFO4/cloudreve/pkg/util"
 | 
						|
	"github.com/zyxar/argo/rpc"
 | 
						|
	"net/url"
 | 
						|
)
 | 
						|
 | 
						|
// Instance 默认使用的Aria2处理实例
 | 
						|
var Instance Aria2 = &DummyAria2{}
 | 
						|
 | 
						|
// EventNotifier 任务状态更新通知处理器
 | 
						|
var EventNotifier = &Notifier{}
 | 
						|
 | 
						|
// Aria2 离线下载处理接口
 | 
						|
type Aria2 interface {
 | 
						|
	// CreateTask 创建新的任务
 | 
						|
	CreateTask(task *model.Download) error
 | 
						|
	// 返回状态信息
 | 
						|
	Status(task *model.Download) (rpc.StatusInfo, error)
 | 
						|
	// 取消任务
 | 
						|
	Cancel(task *model.Download) error
 | 
						|
}
 | 
						|
 | 
						|
const (
 | 
						|
	// URLTask 从URL添加的任务
 | 
						|
	URLTask = iota
 | 
						|
	// TorrentTask 种子任务
 | 
						|
	TorrentTask
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	// Ready 准备就绪
 | 
						|
	Ready = iota
 | 
						|
	// Downloading 下载中
 | 
						|
	Downloading
 | 
						|
	// Paused 暂停中
 | 
						|
	Paused
 | 
						|
	// Error 出错
 | 
						|
	Error
 | 
						|
	// Complete 完成
 | 
						|
	Complete
 | 
						|
	// Canceled 取消/停止
 | 
						|
	Canceled
 | 
						|
	// Unknown 未知状态
 | 
						|
	Unknown
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	// ErrNotEnabled 功能未开启错误
 | 
						|
	ErrNotEnabled   = serializer.NewError(serializer.CodeNoPermissionErr, "离线下载功能未开启", nil)
 | 
						|
	ErrUserNotFound = serializer.NewError(serializer.CodeNotFound, "无法找到任务创建者", nil)
 | 
						|
)
 | 
						|
 | 
						|
// DummyAria2 未开启Aria2功能时使用的默认处理器
 | 
						|
type DummyAria2 struct {
 | 
						|
}
 | 
						|
 | 
						|
// CreateTask 创建新任务,此处直接返回未开启错误
 | 
						|
func (instance *DummyAria2) CreateTask(task *model.Download) error {
 | 
						|
	return ErrNotEnabled
 | 
						|
}
 | 
						|
 | 
						|
// Status 返回未开启错误
 | 
						|
func (instance *DummyAria2) Status(task *model.Download) (rpc.StatusInfo, error) {
 | 
						|
	return rpc.StatusInfo{}, ErrNotEnabled
 | 
						|
}
 | 
						|
 | 
						|
// Cancel 返回未开启错误
 | 
						|
func (instance *DummyAria2) Cancel(task *model.Download) error {
 | 
						|
	return ErrNotEnabled
 | 
						|
}
 | 
						|
 | 
						|
// Init 初始化
 | 
						|
func Init() {
 | 
						|
	options := model.GetSettingByNames("aria2_rpcurl", "aria2_token", "aria2_options")
 | 
						|
	timeout := model.GetIntSetting("aria2_call_timeout", 5)
 | 
						|
	if options["aria2_rpcurl"] == "" {
 | 
						|
		// 未开启Aria2服务
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	util.Log().Info("初始化 aria2 RPC 服务[%s]", options["aria2_rpcurl"])
 | 
						|
	client := &RPCService{}
 | 
						|
	if previousClient, ok := Instance.(*RPCService); ok {
 | 
						|
		client = previousClient
 | 
						|
	}
 | 
						|
 | 
						|
	// 解析RPC服务地址
 | 
						|
	server, err := url.Parse(options["aria2_rpcurl"])
 | 
						|
	if err != nil {
 | 
						|
		util.Log().Warning("无法解析 aria2 RPC 服务地址,%s", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	server.Path = "/jsonrpc"
 | 
						|
 | 
						|
	// todo 加载自定义下载配置
 | 
						|
	if err := client.Init(server.String(), options["aria2_token"], timeout, []interface{}{}); err != nil {
 | 
						|
		util.Log().Warning("初始化 aria2 RPC 服务失败,%s", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	Instance = client
 | 
						|
 | 
						|
	// 从数据库中读取未完成任务,创建监控
 | 
						|
	unfinished := model.GetDownloadsByStatus(Ready, Paused, Downloading)
 | 
						|
	for _, task := range unfinished {
 | 
						|
		// 创建任务监控
 | 
						|
		NewMonitor(&task)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// getStatus 将给定的状态字符串转换为状态标识数字
 | 
						|
func getStatus(status string) int {
 | 
						|
	switch status {
 | 
						|
	case "complete":
 | 
						|
		return Complete
 | 
						|
	case "active":
 | 
						|
		return Downloading
 | 
						|
	case "waiting":
 | 
						|
		return Ready
 | 
						|
	case "paused":
 | 
						|
		return Paused
 | 
						|
	case "error":
 | 
						|
		return Error
 | 
						|
	case "removed":
 | 
						|
		return Canceled
 | 
						|
	default:
 | 
						|
		return Unknown
 | 
						|
	}
 | 
						|
}
 |