mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2025-07-18 17:38:07 +08:00
feat(115_open): add offline download (#683)
This commit is contained in:
@ -306,6 +306,22 @@ func (d *Open115) Put(ctx context.Context, dstDir model.Obj, file model.FileStre
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Open115) OfflineDownload(ctx context.Context, uris []string, dstDir model.Obj) ([]string, error) {
|
||||
return d.client.AddOfflineTaskURIs(ctx, uris, dstDir.GetID())
|
||||
}
|
||||
|
||||
func (d *Open115) DeleteOfflineTask(ctx context.Context, infoHash string, deleteFiles bool) error {
|
||||
return d.client.DeleteOfflineTask(ctx, infoHash, deleteFiles)
|
||||
}
|
||||
|
||||
func (d *Open115) OfflineList(ctx context.Context) (*sdk.OfflineTaskListResp, error) {
|
||||
resp, err := d.client.OfflineTaskList(ctx, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// func (d *Open115) GetArchiveMeta(ctx context.Context, obj model.Obj, args model.ArchiveArgs) (model.ArchiveMeta, error) {
|
||||
// // TODO get archive file meta-info, return errs.NotImplement to use an internal archive tool, optional
|
||||
// return nil, errs.NotImplement
|
||||
|
2
go.mod
2
go.mod
@ -89,7 +89,7 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/OpenListTeam/115-sdk-go v0.2.0
|
||||
github.com/OpenListTeam/115-sdk-go v0.2.1
|
||||
github.com/STARRY-S/zip v0.2.1 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/blevesearch/go-faiss v1.0.25 // indirect
|
||||
|
2
go.sum
2
go.sum
@ -36,6 +36,8 @@ github.com/Max-Sum/base32768 v0.0.0-20230304063302-18e6ce5945fd h1:nzE1YQBdx1bq9
|
||||
github.com/Max-Sum/base32768 v0.0.0-20230304063302-18e6ce5945fd/go.mod h1:C8yoIfvESpM3GD07OCHU7fqI7lhwyZ2Td1rbNbTAhnc=
|
||||
github.com/OpenListTeam/115-sdk-go v0.2.0 h1:qNEYpGQg++INLFXYzVW94uGFzCKAIoJJx19DBrsDvlU=
|
||||
github.com/OpenListTeam/115-sdk-go v0.2.0/go.mod h1:cfvitk2lwe6036iNi2h+iNxwxWDifKZsSvNtrur5BqU=
|
||||
github.com/OpenListTeam/115-sdk-go v0.2.1 h1:tzRUqdktS3h4o69+CXRDVwL0jYN7ccuX8TZWmLxkBGo=
|
||||
github.com/OpenListTeam/115-sdk-go v0.2.1/go.mod h1:cfvitk2lwe6036iNi2h+iNxwxWDifKZsSvNtrur5BqU=
|
||||
github.com/OpenListTeam/go-cache v0.1.0 h1:eV2+FCP+rt+E4OCJqLUW7wGccWZNJMV0NNkh+uChbAI=
|
||||
github.com/OpenListTeam/go-cache v0.1.0/go.mod h1:AHWjKhNK3LE4rorVdKyEALDHoeMnP8SjiNyfVlB+Pz4=
|
||||
github.com/OpenListTeam/gsync v0.1.0 h1:ywzGybOvA3lW8K1BUjKZ2IUlT2FSlzPO4DOazfYXjcs=
|
||||
|
@ -63,6 +63,9 @@ const (
|
||||
// 115
|
||||
Pan115TempDir = "115_temp_dir"
|
||||
|
||||
// 115_open
|
||||
Pan115OpenTempDir = "115_open_temp_dir"
|
||||
|
||||
// pikpak
|
||||
PikPakTempDir = "pikpak_temp_dir"
|
||||
|
||||
|
139
internal/offline_download/115_open/client.go
Normal file
139
internal/offline_download/115_open/client.go
Normal file
@ -0,0 +1,139 @@
|
||||
package _115_open
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
_115_open "github.com/OpenListTeam/OpenList/v4/drivers/115_open"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/conf"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/setting"
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/errs"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/offline_download/tool"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/op"
|
||||
)
|
||||
|
||||
type Open115 struct {
|
||||
}
|
||||
|
||||
func (o *Open115) Name() string {
|
||||
return "115 Open"
|
||||
}
|
||||
|
||||
func (o *Open115) Items() []model.SettingItem {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Open115) Run(task *tool.DownloadTask) error {
|
||||
return errs.NotSupport
|
||||
}
|
||||
|
||||
func (o *Open115) Init() (string, error) {
|
||||
return "ok", nil
|
||||
}
|
||||
|
||||
func (o *Open115) IsReady() bool {
|
||||
tempDir := setting.GetStr(conf.Pan115OpenTempDir)
|
||||
if tempDir == "" {
|
||||
return false
|
||||
}
|
||||
storage, _, err := op.GetStorageAndActualPath(tempDir)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if _, ok := storage.(*_115_open.Open115); !ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (o *Open115) AddURL(args *tool.AddUrlArgs) (string, error) {
|
||||
storage, actualPath, err := op.GetStorageAndActualPath(args.TempDir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
driver115Open, ok := storage.(*_115_open.Open115)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("unsupported storage driver for offline download, only 115 Cloud is supported")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if err := op.MakeDir(ctx, storage, actualPath); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
parentDir, err := op.GetUnwrap(ctx, storage, actualPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hashs, err := driver115Open.OfflineDownload(ctx, []string{args.Url}, parentDir)
|
||||
if err != nil || len(hashs) < 1 {
|
||||
return "", fmt.Errorf("failed to add offline download task: %w", err)
|
||||
}
|
||||
|
||||
return hashs[0], nil
|
||||
}
|
||||
|
||||
func (o *Open115) Remove(task *tool.DownloadTask) error {
|
||||
storage, _, err := op.GetStorageAndActualPath(task.TempDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
driver115Open, ok := storage.(*_115_open.Open115)
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported storage driver for offline download, only 115 Open is supported")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if err := driver115Open.DeleteOfflineTask(ctx, task.GID, false); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Open115) Status(task *tool.DownloadTask) (*tool.Status, error) {
|
||||
storage, _, err := op.GetStorageAndActualPath(task.TempDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
driver115Open, ok := storage.(*_115_open.Open115)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsupported storage driver for offline download, only 115 Open is supported")
|
||||
}
|
||||
|
||||
tasks, err := driver115Open.OfflineList(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &tool.Status{
|
||||
Progress: 0,
|
||||
NewGID: "",
|
||||
Completed: false,
|
||||
Status: "the task has been deleted",
|
||||
Err: nil,
|
||||
}
|
||||
|
||||
for _, t := range tasks.Tasks {
|
||||
if t.InfoHash == task.GID {
|
||||
s.Progress = float64(t.PercentDone)
|
||||
s.Status = t.GetStatus()
|
||||
s.Completed = t.IsDone()
|
||||
s.TotalBytes = t.Size
|
||||
if t.IsFailed() {
|
||||
s.Err = fmt.Errorf(t.GetStatus())
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
}
|
||||
s.Err = fmt.Errorf("the task has been deleted")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var _ tool.Tool = (*Open115)(nil)
|
||||
|
||||
func init() {
|
||||
tool.Tools.Add(&Open115{})
|
||||
}
|
@ -2,6 +2,7 @@ package offline_download
|
||||
|
||||
import (
|
||||
_ "github.com/OpenListTeam/OpenList/v4/internal/offline_download/115"
|
||||
_ "github.com/OpenListTeam/OpenList/v4/internal/offline_download/115_open"
|
||||
_ "github.com/OpenListTeam/OpenList/v4/internal/offline_download/aria2"
|
||||
_ "github.com/OpenListTeam/OpenList/v4/internal/offline_download/http"
|
||||
_ "github.com/OpenListTeam/OpenList/v4/internal/offline_download/pikpak"
|
||||
|
@ -2,6 +2,7 @@ package tool
|
||||
|
||||
import (
|
||||
"context"
|
||||
_115_open "github.com/OpenListTeam/OpenList/v4/drivers/115_open"
|
||||
|
||||
"net/url"
|
||||
stdpath "path"
|
||||
@ -94,6 +95,12 @@ func AddURL(ctx context.Context, args *AddURLArgs) (task.TaskExtensionInfo, erro
|
||||
} else {
|
||||
tempDir = filepath.Join(setting.GetStr(conf.Pan115TempDir), uid)
|
||||
}
|
||||
case "115 Open":
|
||||
if _, ok := storage.(*_115_open.Open115); ok {
|
||||
tempDir = args.DstDirPath
|
||||
} else {
|
||||
tempDir = filepath.Join(setting.GetStr(conf.Pan115OpenTempDir), uid)
|
||||
}
|
||||
case "PikPak":
|
||||
if _, ok := storage.(*pikpak.PikPak); ok {
|
||||
tempDir = args.DstDirPath
|
||||
|
@ -103,6 +103,9 @@ outer:
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if t.tool.Name() == "115 Open" {
|
||||
return nil
|
||||
}
|
||||
t.Status = "offline download completed, maybe transferring"
|
||||
// hack for qBittorrent
|
||||
if t.tool.Name() == "qBittorrent" {
|
||||
@ -166,7 +169,7 @@ func (t *DownloadTask) Update() (bool, error) {
|
||||
|
||||
func (t *DownloadTask) Transfer() error {
|
||||
toolName := t.tool.Name()
|
||||
if toolName == "115 Cloud" || toolName == "PikPak" || toolName == "Thunder" || toolName == "ThunderBrowser" {
|
||||
if toolName == "115 Cloud" || toolName == "115 Open" || toolName == "PikPak" || toolName == "Thunder" || toolName == "ThunderBrowser" {
|
||||
// 如果不是直接下载到目标路径,则进行转存
|
||||
if t.TempDir != t.DstDirPath {
|
||||
return transferObj(t.Ctx(), t.TempDir, t.DstDirPath, t.DeletePolicy)
|
||||
|
@ -2,6 +2,7 @@ package handles
|
||||
|
||||
import (
|
||||
_115 "github.com/OpenListTeam/OpenList/v4/drivers/115"
|
||||
_115_open "github.com/OpenListTeam/OpenList/v4/drivers/115_open"
|
||||
"github.com/OpenListTeam/OpenList/v4/drivers/pikpak"
|
||||
"github.com/OpenListTeam/OpenList/v4/drivers/thunder"
|
||||
"github.com/OpenListTeam/OpenList/v4/drivers/thunder_browser"
|
||||
@ -152,6 +153,50 @@ func Set115(c *gin.Context) {
|
||||
common.SuccessResp(c, "ok")
|
||||
}
|
||||
|
||||
type Set115OpenReq struct {
|
||||
TempDir string `json:"temp_dir" form:"temp_dir"`
|
||||
}
|
||||
|
||||
func Set115Open(c *gin.Context) {
|
||||
var req Set115OpenReq
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
common.ErrorResp(c, err, 400)
|
||||
return
|
||||
}
|
||||
if req.TempDir != "" {
|
||||
storage, _, err := op.GetStorageAndActualPath(req.TempDir)
|
||||
if err != nil {
|
||||
common.ErrorStrResp(c, "storage does not exists", 400)
|
||||
return
|
||||
}
|
||||
if storage.Config().CheckStatus && storage.GetStorage().Status != op.WORK {
|
||||
common.ErrorStrResp(c, "storage not init: "+storage.GetStorage().Status, 400)
|
||||
return
|
||||
}
|
||||
if _, ok := storage.(*_115_open.Open115); !ok {
|
||||
common.ErrorStrResp(c, "unsupported storage driver for offline download, only 115 Open is supported", 400)
|
||||
return
|
||||
}
|
||||
}
|
||||
items := []model.SettingItem{
|
||||
{Key: conf.Pan115OpenTempDir, Value: req.TempDir, Type: conf.TypeString, Group: model.OFFLINE_DOWNLOAD, Flag: model.PRIVATE},
|
||||
}
|
||||
if err := op.SaveSettingItems(items); err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
_tool, err := tool.Tools.Get("115 Open")
|
||||
if err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
if _, err := _tool.Init(); err != nil {
|
||||
common.ErrorResp(c, err, 500)
|
||||
return
|
||||
}
|
||||
common.SuccessResp(c, "ok")
|
||||
}
|
||||
|
||||
type SetPikPakReq struct {
|
||||
TempDir string `json:"temp_dir" form:"temp_dir"`
|
||||
}
|
||||
|
@ -145,6 +145,7 @@ func admin(g *gin.RouterGroup) {
|
||||
setting.POST("/set_qbit", handles.SetQbittorrent)
|
||||
setting.POST("/set_transmission", handles.SetTransmission)
|
||||
setting.POST("/set_115", handles.Set115)
|
||||
setting.POST("/set_115_open", handles.Set115Open)
|
||||
setting.POST("/set_pikpak", handles.SetPikPak)
|
||||
setting.POST("/set_thunder", handles.SetThunder)
|
||||
setting.POST("/set_thunder_browser", handles.SetThunderBrowser)
|
||||
|
Reference in New Issue
Block a user