diff --git a/drivers/115_open/driver.go b/drivers/115_open/driver.go index 2d184e4d..0f343042 100644 --- a/drivers/115_open/driver.go +++ b/drivers/115_open/driver.go @@ -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 diff --git a/go.mod b/go.mod index 974720a4..a07b4702 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index e6440a3f..a3aceca4 100644 --- a/go.sum +++ b/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= diff --git a/internal/conf/const.go b/internal/conf/const.go index e36ba16e..865f60f4 100644 --- a/internal/conf/const.go +++ b/internal/conf/const.go @@ -63,6 +63,9 @@ const ( // 115 Pan115TempDir = "115_temp_dir" + // 115_open + Pan115OpenTempDir = "115_open_temp_dir" + // pikpak PikPakTempDir = "pikpak_temp_dir" diff --git a/internal/offline_download/115_open/client.go b/internal/offline_download/115_open/client.go new file mode 100644 index 00000000..4b9773cc --- /dev/null +++ b/internal/offline_download/115_open/client.go @@ -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{}) +} diff --git a/internal/offline_download/all.go b/internal/offline_download/all.go index 9a55591b..4dd6eed0 100644 --- a/internal/offline_download/all.go +++ b/internal/offline_download/all.go @@ -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" diff --git a/internal/offline_download/tool/add.go b/internal/offline_download/tool/add.go index 7fc8c278..3b42a050 100644 --- a/internal/offline_download/tool/add.go +++ b/internal/offline_download/tool/add.go @@ -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 diff --git a/internal/offline_download/tool/download.go b/internal/offline_download/tool/download.go index 4ef6c003..dcc8062e 100644 --- a/internal/offline_download/tool/download.go +++ b/internal/offline_download/tool/download.go @@ -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) diff --git a/server/handles/offline_download.go b/server/handles/offline_download.go index 7a1330a9..5ceccbb6 100644 --- a/server/handles/offline_download.go +++ b/server/handles/offline_download.go @@ -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"` } diff --git a/server/router.go b/server/router.go index 5bc8469d..458001d7 100644 --- a/server/router.go +++ b/server/router.go @@ -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)