Skip to content

Commit

Permalink
Merge branch 'release/v1.0.26'
Browse files Browse the repository at this point in the history
  • Loading branch information
SheltonZhu committed Aug 7, 2024
2 parents 7c2b7d9 + f639ed6 commit 618c33a
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* [X] Get Information by ID
* [X] Stat File
* [x] Download by share code
* [x] Offline Download

## Example

Expand Down
6 changes: 6 additions & 0 deletions pkg/driver/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const (
ApiDownloadGetUrl = "https://proapi.115.com/app/chrome/downurl"
ApiDownloadGetShareUrl = "https://proapi.115.com/app/share/downurl"

// offline download
ApiAddOfflineUrl = "https://lixian.115.com/lixianssp/?ac=add_task_urls"
ApiDelOfflineUrl = "https://lixian.115.com/lixian/?ct=lixian&ac=task_del"
ApiListOfflineUrl = "https://lixian.115.com/lixian/?ct=lixian&ac=task_lists"
ApiClearOfflineUrl = "https://lixian.115.com/lixian/?ct=lixian&ac=task_clear"

// upload
ApiUploadInfo = "https://proapi.115.com/app/uploadinfo"
ApiGetUploadEndpoint = "https://uplb.115.com/3.0/getuploadinfo.php"
Expand Down
33 changes: 33 additions & 0 deletions pkg/driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,39 @@ func teardown(t *testing.T) func(t *testing.T) {
return func(t *testing.T) {}
}

func TestListOfflineTasks(t *testing.T) {
down := teardown(t)
defer down(t)
_, err := client.ListOfflineTask(1)
assert.Nil(t, err)
}

func TestOfflineAddUri(t *testing.T) {
down := teardown(t)
defer down(t)

uri := "https://x.com/Olympics/status/1820550228640203065/photo/1"
hashs, err := client.AddOfflineTaskURIs([]string{uri}, "0")
assert.Nil(t, err)
assert.NotEmpty(t, hashs)
}

func TestOfflineDelUri(t *testing.T) {
down := teardown(t)
defer down(t)

err := client.DeleteOfflineTasks([]string{"1123", "1231"}, true)
assert.Nil(t, err)
}

func TestOfflineClearUri(t *testing.T) {
down := teardown(t)
defer down(t)

err := client.ClearOfflineTasks(1)
assert.Nil(t, err)
}

func TestMkdir(t *testing.T) {
down := teardown(t)
defer down(t)
Expand Down
2 changes: 2 additions & 0 deletions pkg/driver/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var (
var (
ErrNotLogin = errors.New("user not login")

ErrOfflineNoTimes = errors.New("offline download quota has been used up, you can purchase a VIP experience or upgrade to VIP service to get more quota")
ErrOfflineInvalidLink = errors.New("invalid download link")
ErrOfflineTaskExisted = errors.New("offline task existed")

Expand Down Expand Up @@ -84,6 +85,7 @@ var (
99: ErrNotLogin,
990001: ErrNotLogin,
// Offline errors
10010: ErrOfflineNoTimes,
10004: ErrOfflineInvalidLink,
10008: ErrOfflineTaskExisted,
// Dir errors
Expand Down
3 changes: 2 additions & 1 deletion pkg/driver/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ func (f *File) from(fileInfo *FileInfo) *File {
f.FileID = fileInfo.FileID
f.ParentID = string(fileInfo.CategoryID)
f.IsDirectory = false
localTime, err := time.ParseInLocation("2006-01-02 15:04", fileInfo.UpdateTime, time.Local)
loc, _ := time.LoadLocation("Asia/Shanghai") // updatetime is a string without timezone
localTime, err := time.ParseInLocation("2006-01-02 15:04", fileInfo.UpdateTime, loc)
if err == nil {
f.UpdateTime = time.Unix(localTime.Unix(), 0)
}
Expand Down
197 changes: 197 additions & 0 deletions pkg/driver/offline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
package driver

import (
"encoding/json"
"fmt"
"net/url"
"strconv"

crypto "github.com/gaoyb7/115drive-webdav/115"
)

// OfflineTask describe an offline downloading task.
type OfflineTask struct {
InfoHash string `json:"info_hash"`
Name string `json:"name"`
Size int64 `json:"size"`
Url string `json:"url"`
AddTime int64 `json:"add_time"`
Peers int64 `json:"peers"`
RateDownload float64 `json:"rateDownload"`
Status int `json:"status"`
Percent float64 `json:"percentDone"`
UpdateTime int64 `json:"last_update"`
LeftTime int64 `json:"left_time"`
FileId string `json:"file_id"`
DelFileId string `json:"delete_file_id"`
DirId string `json:"wp_path_id"`
Move int `json:"move"`
}

func (t *OfflineTask) IsTodo() bool {
return t.Status == 0
}

func (t *OfflineTask) IsRunning() bool {
return t.Status == 1
}

func (t *OfflineTask) IsDone() bool {
return t.Status == 2
}

func (t *OfflineTask) IsFailed() bool {
return t.Status == -1
}

func (t *OfflineTask) GetStatus() string {
if t.IsTodo() {
return "准备开始离线下载"
}
if t.IsDone() {
return "离线下载完成"
}
if t.IsFailed() {
return "离线下载失败"
}
if t.IsRunning() {
return "离线任务下载中"
}
return fmt.Sprintf("未知状态: %d", t.Status)
}

// ListOfflineTask list tasks
func (c *Pan115Client) ListOfflineTask(page int64) (OfflineTaskResp, error) {
result := OfflineTaskResp{}
req := c.NewRequest().
SetQueryParam("page", strconv.FormatInt(page, 10)).
SetResult(&result).
ForceContentType("application/json;charset=UTF-8")

resp, err := req.Post(ApiListOfflineUrl)

if err := CheckErr(err, &result, resp); err != nil {
return OfflineTaskResp{}, err
}
return result, nil
}

// AddOfflineTaskURIs adds offline tasks by download URIs.
// supports http, ed2k, magent
func (c *Pan115Client) AddOfflineTaskURIs(uris []string, saveDirID string) (hashes []string, err error) {
count := len(uris)
if count == 0 {
return
}

if c.UserID < 0 {
if err := c.LoginCheck(); err != nil {
return nil, err
}
}

key := crypto.GenerateKey()

result := DownloadResp{}

params := map[string]string{
"ac": "add_task_urls",
"wp_path_id": saveDirID,
"app_ver": appVer,
"uid": strconv.FormatInt(c.UserID, 10),
}
for i, uri := range uris {
key := fmt.Sprintf("url[%d]", i)
params[key] = uri
}
paramsBytes, err := json.Marshal(params)
if err != nil {
return nil, err
}

data := crypto.Encode(paramsBytes, key)
req := c.NewRequest().
SetQueryParam("t", Now().String()).
SetFormData(map[string]string{"data": data}).
ForceContentType("application/json").
SetResult(&result)

resp, err := req.Post(ApiAddOfflineUrl)

if err := CheckErr(err, &result, resp); err != nil {
return nil, err
}

bytes, err := crypto.Decode(string(result.EncodedData), key)
if err != nil {
return nil, err
}

taskInfos := OfflineAddUrlResponse{}
if err := json.Unmarshal(bytes, &taskInfos); err != nil {
return nil, err
}

hashes = make([]string, count)
for i, task := range taskInfos.Result {
hashes[i] = task.InfoHash
}
return hashes, nil
}

// DeleteOfflineTasks deletes tasks.
func (c *Pan115Client) DeleteOfflineTasks(hashes []string, deleteFiles bool) error {
form := url.Values{}
for _, hash := range hashes {
form.Add("hash", hash)
}

form.Set("flag", "0")
if deleteFiles {
form.Set("flag", "1")
}

result := MkdirResp{}
req := c.NewRequest().
SetFormDataFromValues(form).
SetResult(&result).
ForceContentType("application/json;charset=UTF-8")

resp, err := req.Post(ApiDelOfflineUrl)
return CheckErr(err, &result, resp)
}

// ClearOfflineTasks deletes tasks.
func (c *Pan115Client) ClearOfflineTasks(clearFlag int64) error {
form := url.Values{}
form.Set("flag", strconv.FormatInt(int64(clearFlag), 10))

result := MkdirResp{}
req := c.NewRequest().
SetFormDataFromValues(form).
SetResult(&result).
ForceContentType("application/json;charset=UTF-8")

resp, err := req.Post(ApiClearOfflineUrl)
return CheckErr(err, &result, resp)
}

type OfflineAddUrlResponse struct {
BasicResp
Result []OfflineTaskResponse `json:"result"`
}
type OfflineTaskResponse struct {
InfoHash string `json:"info_hash"`
Url string `json:"url"`
}

type OfflineTaskResp struct {
BasicResp
Total int64 `json:"total"`
Count int64 `json:"count"`
PageRow int64 `json:"page_row"`
PageCount int64 `json:"page_count"`
Page int64 `json:"page"`
Quota int64 `json:"quota"`
Tasks []*OfflineTask `json:"tasks"`
}

0 comments on commit 618c33a

Please sign in to comment.