feat(115_open): add offline download (#683)

This commit is contained in:
Seven
2025-07-11 20:17:54 +08:00
committed by GitHub
parent eed3c0533c
commit 19c6b6f930
10 changed files with 219 additions and 2 deletions

View File

@ -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
View File

@ -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
View File

@ -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=

View File

@ -63,6 +63,9 @@ const (
// 115
Pan115TempDir = "115_temp_dir"
// 115_open
Pan115OpenTempDir = "115_open_temp_dir"
// pikpak
PikPakTempDir = "pikpak_temp_dir"

View 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{})
}

View File

@ -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"

View File

@ -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

View File

@ -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)

View File

@ -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"`
}

View File

@ -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)