Cloudreve/models/download.go
AaronLiu 056de22edb
Feat: aria2 download and transfer in slave node (#1040)
* Feat: retrieve nodes from data table

* Feat: master node ping slave node in REST API

* Feat: master send scheduled ping request

* Feat: inactive nodes recover loop

* Modify: remove database operations from aria2 RPC caller implementation

* Feat: init aria2 client in master node

* Feat: Round Robin load balancer

* Feat: create and monitor aria2 task in master node

* Feat: salve receive and handle heartbeat

* Fix: Node ID will be 0 in download record generated in older version

* Feat: sign request headers with all `X-` prefix

* Feat: API call to slave node will carry meta data in headers

* Feat: call slave aria2 rpc method from master

* Feat: get slave aria2 task status
Feat: encode slave response data using gob

* Feat: aria2 callback to master node / cancel or select task to slave node

* Fix: use dummy aria2 client when caller initialize failed in master node

* Feat: slave aria2 status event callback / salve RPC auth

* Feat: prototype for slave driven filesystem

* Feat: retry for init aria2 client in master node

* Feat: init request client with global options

* Feat: slave receive async task from master

* Fix: competition write in request header

* Refactor: dependency initialize order

* Feat: generic message queue implementation

* Feat: message queue implementation

* Feat: master waiting slave transfer result

* Feat: slave transfer file in stateless policy

* Feat: slave transfer file in slave policy

* Feat: slave transfer file in local policy

* Feat: slave transfer file in OneDrive policy

* Fix: failed to initialize update checker http client

* Feat: list slave nodes for dashboard

* Feat: test aria2 rpc connection in slave

* Feat: add and save node

* Feat: add and delete node in node pool

* Fix: temp file cannot be removed when aria2 task fails

* Fix: delete node in admin panel

* Feat: edit node and get node info

* Modify: delete unused settings
2021-10-31 09:41:56 +08:00

127 lines
3.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
import (
"encoding/json"
"github.com/cloudreve/Cloudreve/v3/pkg/aria2/rpc"
"github.com/cloudreve/Cloudreve/v3/pkg/util"
"github.com/jinzhu/gorm"
)
// Download 离线下载队列模型
type Download struct {
gorm.Model
Status int // 任务状态
Type int // 任务类型
Source string `gorm:"type:text"` // 文件下载地址
TotalSize uint64 // 文件大小
DownloadedSize uint64 // 文件大小
GID string `gorm:"size:32,index:gid"` // 任务ID
Speed int // 下载速度
Parent string `gorm:"type:text"` // 存储目录
Attrs string `gorm:"size:4294967295"` // 任务状态属性
Error string `gorm:"type:text"` // 错误描述
Dst string `gorm:"type:text"` // 用户文件系统存储父目录路径
UserID uint // 发起者UID
TaskID uint // 对应的转存任务ID
NodeID uint // 处理任务的节点ID
// 关联模型
User *User `gorm:"PRELOAD:false,association_autoupdate:false"`
// 数据库忽略字段
StatusInfo rpc.StatusInfo `gorm:"-"`
Task *Task `gorm:"-"`
}
// AfterFind 找到下载任务后的钩子处理Status结构
func (task *Download) AfterFind() (err error) {
// 解析状态
if task.Attrs != "" {
err = json.Unmarshal([]byte(task.Attrs), &task.StatusInfo)
}
if task.TaskID != 0 {
task.Task, _ = GetTasksByID(task.TaskID)
}
return err
}
// BeforeSave Save下载任务前的钩子
func (task *Download) BeforeSave() (err error) {
// 解析状态
if task.Attrs != "" {
err = json.Unmarshal([]byte(task.Attrs), &task.StatusInfo)
}
return err
}
// Create 创建离线下载记录
func (task *Download) Create() (uint, error) {
if err := DB.Create(task).Error; err != nil {
util.Log().Warning("无法插入离线下载记录, %s", err)
return 0, err
}
return task.ID, nil
}
// Save 更新
func (task *Download) Save() error {
if err := DB.Save(task).Error; err != nil {
util.Log().Warning("无法更新离线下载记录, %s", err)
return err
}
return nil
}
// GetDownloadsByStatus 根据状态检索下载
func GetDownloadsByStatus(status ...int) []Download {
var tasks []Download
DB.Where("status in (?)", status).Find(&tasks)
return tasks
}
// GetDownloadsByStatusAndUser 根据状态检索和用户ID下载
// page 为 0 表示列出所有,非零时分页
func GetDownloadsByStatusAndUser(page, uid uint, status ...int) []Download {
var tasks []Download
dbChain := DB
if page > 0 {
dbChain = dbChain.Limit(10).Offset((page - 1) * 10).Order("updated_at DESC")
}
dbChain.Where("user_id = ? and status in (?)", uid, status).Find(&tasks)
return tasks
}
// GetDownloadByGid 根据GID和用户ID查找下载
func GetDownloadByGid(gid string, uid uint) (*Download, error) {
download := &Download{}
result := DB.Where("user_id = ? and g_id = ?", uid, gid).First(download)
return download, result.Error
}
// GetOwner 获取下载任务所属用户
func (task *Download) GetOwner() *User {
if task.User == nil {
if user, err := GetUserByID(task.UserID); err == nil {
return &user
}
}
return task.User
}
// Delete 删除离线下载记录
func (download *Download) Delete() error {
return DB.Model(download).Delete(download).Error
}
// GetNodeID 返回任务所属节点ID
func (task *Download) GetNodeID() uint {
// 兼容3.4版本之前生成的下载记录
if task.NodeID == 0 {
return 1
}
return task.NodeID
}