Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions drivers/123_open/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ func (d *Open123) GetDetails(ctx context.Context) (*model.StorageDetails, error)
}, nil
}

func (d *Open123) OfflineDownload(ctx context.Context, url string, dir model.Obj, callback string) (int, error) {
return d.createOfflineDownloadTask(ctx, url, dir.GetID(), callback)
}

func (d *Open123) OfflineDownloadProcess(ctx context.Context, taskID int) (float64, int, error) {
return d.queryOfflineDownloadStatus(ctx, taskID)
}

var (
_ driver.Driver = (*Open123)(nil)
_ driver.PutResult = (*Open123)(nil)
Expand Down
19 changes: 19 additions & 0 deletions drivers/123_open/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,24 @@ func (a *ApiInfo) Require() {
a.token <- struct{}{}
}
}

func (a *ApiInfo) Release() {
if a.qps > 0 {
time.AfterFunc(time.Second, func() {
<-a.token
})
}
}

func (a *ApiInfo) SetQPS(qps int) {
a.qps = qps
a.token = make(chan struct{}, qps)
}

func (a *ApiInfo) NowLen() int {
return len(a.token)
}

func InitApiInfo(url string, qps int) *ApiInfo {
return &ApiInfo{
url: url,
Expand Down Expand Up @@ -185,3 +189,18 @@ type UploadCompleteResp struct {
FileID int64 `json:"fileID"`
} `json:"data"`
}

type OfflineDownloadResp struct {
BaseResp
Data struct {
TaskID int `json:"taskID"`
} `json:"data"`
}

type OfflineDownloadProcessResp struct {
BaseResp
Data struct {
Process float64 `json:"process"`
Status int `json:"status"`
} `json:"data"`
}
34 changes: 34 additions & 0 deletions drivers/123_open/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ var ( // 不同情况下获取的AccessTokenQPS限制不同 如下模块化易
Trash = InitApiInfo(Api+"/api/v1/file/trash", 2)
UploadCreate = InitApiInfo(Api+"/upload/v2/file/create", 2)
UploadComplete = InitApiInfo(Api+"/upload/v2/file/upload_complete", 0)

OfflineDownload = InitApiInfo(Api+"/api/v1/offline/download", 1)
OfflineDownloadProcess = InitApiInfo(Api+"/api/v1/offline/download/process", 5)
)

func (d *Open123) Request(apiInfo *ApiInfo, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
Expand Down Expand Up @@ -277,3 +280,34 @@ func (d *Open123) trash(fileId int64) error {

return nil
}

func (d *Open123) createOfflineDownloadTask(ctx context.Context, url string, dirID, callback string) (taskID int, err error) {
body := base.Json{
"url": url,
"dirID": dirID,
}
if len(callback) > 0 {
body["callBackUrl"] = callback
}
var resp OfflineDownloadResp
_, err = d.Request(OfflineDownload, http.MethodPost, func(req *resty.Request) {
req.SetBody(body)
}, &resp)
if err != nil {
return 0, err
}
return resp.Data.TaskID, nil
}

func (d *Open123) queryOfflineDownloadStatus(ctx context.Context, taskID int) (process float64, status int, err error) {
var resp OfflineDownloadProcessResp
_, err = d.Request(OfflineDownloadProcess, http.MethodGet, func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"taskID": strconv.Itoa(taskID),
})
}, &resp)
if err != nil {
return .0, 0, err
}
return resp.Data.Process, resp.Data.Status, nil
}
4 changes: 4 additions & 0 deletions internal/conf/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ const (
QbittorrentUrl = "qbittorrent_url"
QbittorrentSeedtime = "qbittorrent_seedtime"

// 123 open offline download
Pan123OpenOfflineDownloadCallbackUrl = "123_open_callback_url"
Pan123OpenTempDir = "123_open_temp_dir"

// ftp
FTPPublicHost = "ftp_public_host"
FTPPasvPortMap = "ftp_pasv_port_map"
Expand Down
119 changes: 119 additions & 0 deletions internal/offline_download/123_open/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package _123_open

import (
"context"
"fmt"
"strconv"

_123_open "github.com/OpenListTeam/OpenList/v4/drivers/123_open"
"github.com/OpenListTeam/OpenList/v4/internal/conf"
"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"
"github.com/OpenListTeam/OpenList/v4/internal/setting"
)

type Open123 struct{}

func (*Open123) Name() string {
return "123 Open"
}

func (*Open123) Items() []model.SettingItem {
return nil
}

func (*Open123) Run(_ *tool.DownloadTask) error {
return errs.NotSupport
}

func (*Open123) Init() (string, error) {
return "ok", nil
}

func (*Open123) IsReady() bool {
tempDir := setting.GetStr(conf.Pan123OpenTempDir)
if tempDir == "" {
return false
}
storage, _, err := op.GetStorageAndActualPath(tempDir)
if err != nil {
return false
}
if _, ok := storage.(*_123_open.Open123); !ok {
return false
}
return true
}

func (*Open123) AddURL(args *tool.AddUrlArgs) (string, error) {
storage, actualPath, err := op.GetStorageAndActualPath(args.TempDir)
if err != nil {
return "", err
}
driver123Open, ok := storage.(*_123_open.Open123)
if !ok {
return "", fmt.Errorf("unsupported storage driver for offline download, only 123 Open 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
}
cb := setting.GetStr(conf.Pan123OpenOfflineDownloadCallbackUrl)
taskID, err := driver123Open.OfflineDownload(ctx, args.Url, parentDir, cb)
if err != nil {
return "", fmt.Errorf("failed to add offline download task: %w", err)
}
return strconv.Itoa(taskID), nil
}

func (*Open123) Remove(_ *tool.DownloadTask) error {
return errs.NotSupport
}

func (*Open123) Status(task *tool.DownloadTask) (*tool.Status, error) {
taskID, err := strconv.Atoi(task.GID)
if err != nil {
return nil, fmt.Errorf("failed to parse task ID: %s", task.GID)
}
storage, _, err := op.GetStorageAndActualPath(task.TempDir)
if err != nil {
return nil, err
}
driver123Open, ok := storage.(*_123_open.Open123)
if !ok {
return nil, fmt.Errorf("unsupported storage driver for offline download, only 123 Open is supported")
}
process, status, err := driver123Open.OfflineDownloadProcess(context.Background(), taskID)
if err != nil {
return nil, err
}
var statusStr string
switch status {
case 0:
statusStr = "downloading"
case 1:
err = fmt.Errorf("offline download failed")
case 2:
statusStr = "succeed"
case 3:
statusStr = "retrying"
}
return &tool.Status{
Progress: process,
Completed: status == 2,
Status: statusStr,
Err: err,
}, nil
}

var _ tool.Tool = (*Open123)(nil)

func init() {
tool.Tools.Add(&Open123{})
}
1 change: 1 addition & 0 deletions internal/offline_download/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,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/123_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"
Expand Down
16 changes: 11 additions & 5 deletions internal/offline_download/tool/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ package tool

import (
"context"
"github.com/OpenListTeam/OpenList/v4/drivers/thunder_browser"

_115_open "github.com/OpenListTeam/OpenList/v4/drivers/115_open"
"github.com/OpenListTeam/OpenList/v4/server/common"

"net/url"
stdpath "path"
"path/filepath"

_115 "github.com/OpenListTeam/OpenList/v4/drivers/115"
_115_open "github.com/OpenListTeam/OpenList/v4/drivers/115_open"
_123_open "github.com/OpenListTeam/OpenList/v4/drivers/123_open"
"github.com/OpenListTeam/OpenList/v4/drivers/pikpak"
"github.com/OpenListTeam/OpenList/v4/drivers/thunder"
"github.com/OpenListTeam/OpenList/v4/drivers/thunder_browser"
"github.com/OpenListTeam/OpenList/v4/drivers/thunderx"
"github.com/OpenListTeam/OpenList/v4/internal/conf"
"github.com/OpenListTeam/OpenList/v4/internal/errs"
Expand All @@ -22,6 +20,7 @@ import (
"github.com/OpenListTeam/OpenList/v4/internal/op"
"github.com/OpenListTeam/OpenList/v4/internal/setting"
"github.com/OpenListTeam/OpenList/v4/internal/task"
"github.com/OpenListTeam/OpenList/v4/server/common"
"github.com/google/uuid"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -104,6 +103,13 @@ func AddURL(ctx context.Context, args *AddURLArgs) (task.TaskExtensionInfo, erro
} else {
tempDir = filepath.Join(setting.GetStr(conf.Pan115OpenTempDir), uid)
}
case "123 Open":
if _, ok := storage.(*_123_open.Open123); ok && dstDirActualPath != "/" {
// directly offline downloading to the root path is not allowed via 123 open platform
tempDir = args.DstDirPath
} else {
tempDir = filepath.Join(setting.GetStr(conf.Pan123OpenTempDir), uid)
}
case "PikPak":
if _, ok := storage.(*pikpak.PikPak); ok {
tempDir = args.DstDirPath
Expand Down
5 changes: 4 additions & 1 deletion internal/offline_download/tool/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ outer:
if t.tool.Name() == "115 Open" {
return nil
}
if t.tool.Name() == "123 Open" {
return nil
}
t.Status = "offline download completed, maybe transferring"
// hack for qBittorrent
if t.tool.Name() == "qBittorrent" {
Expand Down Expand Up @@ -174,7 +177,7 @@ func (t *DownloadTask) Update() (bool, error) {

func (t *DownloadTask) Transfer() error {
toolName := t.tool.Name()
if toolName == "115 Cloud" || toolName == "115 Open" || toolName == "PikPak" || toolName == "Thunder" || toolName == "ThunderX" || toolName == "ThunderBrowser" {
if toolName == "115 Cloud" || toolName == "115 Open" || toolName == "123 Open" || toolName == "PikPak" || toolName == "Thunder" || toolName == "ThunderX" || toolName == "ThunderBrowser" {
// 如果不是直接下载到目标路径,则进行转存
if t.TempDir != t.DstDirPath {
return transferObj(t.Ctx(), t.TempDir, t.DstDirPath, t.DeletePolicy)
Expand Down
51 changes: 49 additions & 2 deletions server/handles/offline_download.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package handles

import (
"strings"

_115 "github.com/OpenListTeam/OpenList/v4/drivers/115"
_115_open "github.com/OpenListTeam/OpenList/v4/drivers/115_open"
_123_open "github.com/OpenListTeam/OpenList/v4/drivers/123_open"
"github.com/OpenListTeam/OpenList/v4/drivers/pikpak"
"github.com/OpenListTeam/OpenList/v4/drivers/thunder"
"github.com/OpenListTeam/OpenList/v4/drivers/thunder_browser"
Expand Down Expand Up @@ -200,6 +201,52 @@ func Set115Open(c *gin.Context) {
common.SuccessResp(c, "ok")
}

type Set123OpenReq struct {
TempDir string `json:"temp_dir" form:"temp_dir"`
CallbackUrl string `json:"callback_url" form:"callback_url"`
}

func Set123Open(c *gin.Context) {
var req Set123OpenReq
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.(*_123_open.Open123); !ok {
common.ErrorStrResp(c, "unsupported storage driver for offline download, only 123 Open is supported", 400)
return
}
}
items := []model.SettingItem{
{Key: conf.Pan123OpenTempDir, Value: req.TempDir, Type: conf.TypeString, Group: model.OFFLINE_DOWNLOAD, Flag: model.PRIVATE},
{Key: conf.Pan123OpenOfflineDownloadCallbackUrl, Value: req.CallbackUrl, 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("123 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"`
}
Expand Down Expand Up @@ -413,7 +460,7 @@ func AddOfflineDownload(c *gin.Context) {
if trimmedUrl == "" {
continue
}

t, err := tool.AddURL(c, &tool.AddURLArgs{
URL: trimmedUrl,
DstDirPath: reqPath,
Expand Down
1 change: 1 addition & 0 deletions server/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ func admin(g *gin.RouterGroup) {
setting.POST("/set_transmission", handles.SetTransmission)
setting.POST("/set_115", handles.Set115)
setting.POST("/set_115_open", handles.Set115Open)
setting.POST("/set_123_open", handles.Set123Open)
setting.POST("/set_pikpak", handles.SetPikPak)
setting.POST("/set_thunder", handles.SetThunder)
setting.POST("/set_thunderx", handles.SetThunderX)
Expand Down