From d30159579f5801374d630807dfca7cbec082a5e6 Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Sat, 8 Feb 2020 15:37:51 +0800 Subject: [PATCH] Feat: list downloading file --- models/download.go | 8 ++++++ pkg/aria2/caller.go | 10 ++++++- pkg/serializer/aria2.go | 54 ++++++++++++++++++++++++++++++++++++ routers/controllers/aria2.go | 11 ++++++++ routers/router.go | 2 ++ service/aria2/manage.go | 11 ++++++++ 6 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 pkg/serializer/aria2.go diff --git a/models/download.go b/models/download.go index 72d69b7..f0c2b74 100644 --- a/models/download.go +++ b/models/download.go @@ -71,6 +71,14 @@ func GetDownloadsByStatus(status ...int) []Download { return tasks } +// GetDownloadsByStatusAndUser 根据状态检索和用户ID下载 +// TODO 测试 +func GetDownloadsByStatusAndUser(uid uint, status ...int) []Download { + var tasks []Download + DB.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{} diff --git a/pkg/aria2/caller.go b/pkg/aria2/caller.go index f5bec63..70a4ad2 100644 --- a/pkg/aria2/caller.go +++ b/pkg/aria2/caller.go @@ -39,7 +39,15 @@ func (client *RPCService) Init(server, secret string, timeout int, options []int // Status 查询下载状态 func (client *RPCService) Status(task *model.Download) (rpc.StatusInfo, error) { - return client.caller.TellStatus(task.GID) + 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 取消下载 diff --git a/pkg/serializer/aria2.go b/pkg/serializer/aria2.go new file mode 100644 index 0000000..a540af5 --- /dev/null +++ b/pkg/serializer/aria2.go @@ -0,0 +1,54 @@ +package serializer + +import ( + model "github.com/HFO4/cloudreve/models" + "github.com/zyxar/argo/rpc" + "path" +) + +// DownloadListResponse 下载列表响应条目 +type DownloadListResponse struct { + UpdateTime int64 `json:"update"` + Name string `json:"name"` + Status int `json:"status"` + UserID uint `json:"uid"` + Error string `json:"error"` + Dst string `json:"dst"` + Total uint64 `json:"total"` + Downloaded uint64 `json:"downloaded"` + Speed int `json:"speed"` + Info rpc.StatusInfo `json:"info"` +} + +// BuildDownloadingResponse 构建正在下载的列表响应 +func BuildDownloadingResponse(tasks []model.Download) Response { + resp := make([]DownloadListResponse, 0, len(tasks)) + + for i := 0; i < len(tasks); i++ { + fileName := "" + if len(tasks[i].StatusInfo.Files) > 0 { + fileName = path.Base(tasks[i].StatusInfo.Files[0].Path) + } + + // 过滤敏感信息 + tasks[i].StatusInfo.Dir = "" + for i2 := 0; i2 < len(tasks[i].StatusInfo.Files); i2++ { + tasks[i].StatusInfo.Files[i2].Path = path.Base(tasks[i].StatusInfo.Files[i2].Path) + } + + resp = append(resp, DownloadListResponse{ + UpdateTime: tasks[i].UpdatedAt.Unix(), + Name: fileName, + Status: tasks[i].Status, + UserID: tasks[i].UserID, + Error: tasks[i].Error, + Dst: tasks[i].Dst, + Total: tasks[i].TotalSize, + Downloaded: tasks[i].DownloadedSize, + Speed: tasks[i].Speed, + Info: tasks[i].StatusInfo, + }) + } + + return Response{Data: resp} +} diff --git a/routers/controllers/aria2.go b/routers/controllers/aria2.go index de087b0..30ed8b4 100644 --- a/routers/controllers/aria2.go +++ b/routers/controllers/aria2.go @@ -81,3 +81,14 @@ func CancelAria2Download(c *gin.Context) { c.JSON(200, ErrorResponse(err)) } } + +// ListDownloading 获取正在下载中的任务 +func ListDownloading(c *gin.Context) { + var service aria2.DownloadListService + if err := c.ShouldBindQuery(&service); err == nil { + res := service.Downloading(c, CurrentUser(c)) + c.JSON(200, res) + } else { + c.JSON(200, ErrorResponse(err)) + } +} diff --git a/routers/router.go b/routers/router.go index ad8b778..56b8fb4 100644 --- a/routers/router.go +++ b/routers/router.go @@ -284,6 +284,8 @@ func InitMasterRouter() *gin.Engine { aria2.PUT("select/:gid", controllers.SelectAria2File) // 取消下载任务 aria2.DELETE("task/:gid", controllers.CancelAria2Download) + // 获取正在下载中的任务 + aria2.GET("downloading", controllers.ListDownloading) } // 目录 diff --git a/service/aria2/manage.go b/service/aria2/manage.go index bf36261..c087903 100644 --- a/service/aria2/manage.go +++ b/service/aria2/manage.go @@ -17,6 +17,17 @@ type DownloadTaskService struct { GID string `uri:"gid" binding:"required"` } +// DownloadListService 下载列表服务 +type DownloadListService struct { +} + +// Downloading 获取正在下载中的任务 +func (service *DownloadListService) Downloading(c *gin.Context, user *model.User) serializer.Response { + // 查找下载记录 + downloads := model.GetDownloadsByStatusAndUser(user.ID, aria2.Downloading, aria2.Paused, aria2.Ready) + return serializer.BuildDownloadingResponse(downloads) +} + // Delete 取消下载任务 func (service *DownloadTaskService) Delete(c *gin.Context) serializer.Response { userCtx, _ := c.Get("user")