mirror of https://github.com/Xhofe/alist
189 lines
4.2 KiB
Go
189 lines
4.2 KiB
Go
package pcloud
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/alist-org/alist/v3/internal/driver"
|
|
"github.com/alist-org/alist/v3/internal/model"
|
|
"github.com/alist-org/alist/v3/pkg/utils"
|
|
"github.com/go-resty/resty/v2"
|
|
)
|
|
|
|
type PCloud struct {
|
|
model.Storage
|
|
Addition
|
|
AccessToken string // Actual access token obtained from refresh token
|
|
}
|
|
|
|
func (d *PCloud) Config() driver.Config {
|
|
return config
|
|
}
|
|
|
|
func (d *PCloud) GetAddition() driver.Additional {
|
|
return &d.Addition
|
|
}
|
|
|
|
func (d *PCloud) Init(ctx context.Context) error {
|
|
// Map hostname selection to actual API endpoints
|
|
if d.Hostname == "us" {
|
|
d.Hostname = "api.pcloud.com"
|
|
} else if d.Hostname == "eu" {
|
|
d.Hostname = "eapi.pcloud.com"
|
|
}
|
|
|
|
// Set default root folder ID if not provided
|
|
if d.RootFolderID == "" {
|
|
d.RootFolderID = "d0"
|
|
}
|
|
|
|
// Use the access token directly (like rclone)
|
|
d.AccessToken = d.RefreshToken // RefreshToken field actually contains the access_token
|
|
return nil
|
|
}
|
|
|
|
func (d *PCloud) Drop(ctx context.Context) error {
|
|
return nil
|
|
}
|
|
|
|
func (d *PCloud) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
|
|
folderID := d.RootFolderID
|
|
if dir.GetID() != "" {
|
|
folderID = dir.GetID()
|
|
}
|
|
|
|
files, err := d.getFiles(folderID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return utils.SliceConvert(files, func(src FileObject) (model.Obj, error) {
|
|
return fileToObj(src), nil
|
|
})
|
|
}
|
|
|
|
func (d *PCloud) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
|
downloadURL, err := d.getDownloadLink(file.GetID())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &model.Link{
|
|
URL: downloadURL,
|
|
}, nil
|
|
}
|
|
|
|
// Mkdir implements driver.Mkdir
|
|
func (d *PCloud) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
|
parentID := d.RootFolderID
|
|
if parentDir.GetID() != "" {
|
|
parentID = parentDir.GetID()
|
|
}
|
|
|
|
return d.createFolder(parentID, dirName)
|
|
}
|
|
|
|
// Move implements driver.Move
|
|
func (d *PCloud) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
|
|
// pCloud uses renamefile/renamefolder for both rename and move
|
|
endpoint := "/renamefile"
|
|
paramName := "fileid"
|
|
|
|
if srcObj.IsDir() {
|
|
endpoint = "/renamefolder"
|
|
paramName = "folderid"
|
|
}
|
|
|
|
var resp ItemResult
|
|
_, err := d.requestWithRetry(endpoint, "POST", func(req *resty.Request) {
|
|
req.SetFormData(map[string]string{
|
|
paramName: extractID(srcObj.GetID()),
|
|
"tofolderid": extractID(dstDir.GetID()),
|
|
"toname": srcObj.GetName(),
|
|
})
|
|
}, &resp)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if resp.Result != 0 {
|
|
return fmt.Errorf("pCloud error: result code %d", resp.Result)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Rename implements driver.Rename
|
|
func (d *PCloud) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
|
endpoint := "/renamefile"
|
|
paramName := "fileid"
|
|
|
|
if srcObj.IsDir() {
|
|
endpoint = "/renamefolder"
|
|
paramName = "folderid"
|
|
}
|
|
|
|
var resp ItemResult
|
|
_, err := d.requestWithRetry(endpoint, "POST", func(req *resty.Request) {
|
|
req.SetFormData(map[string]string{
|
|
paramName: extractID(srcObj.GetID()),
|
|
"toname": newName,
|
|
})
|
|
}, &resp)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if resp.Result != 0 {
|
|
return fmt.Errorf("pCloud error: result code %d", resp.Result)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Copy implements driver.Copy
|
|
func (d *PCloud) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
|
endpoint := "/copyfile"
|
|
paramName := "fileid"
|
|
|
|
if srcObj.IsDir() {
|
|
endpoint = "/copyfolder"
|
|
paramName = "folderid"
|
|
}
|
|
|
|
var resp ItemResult
|
|
_, err := d.requestWithRetry(endpoint, "POST", func(req *resty.Request) {
|
|
req.SetFormData(map[string]string{
|
|
paramName: extractID(srcObj.GetID()),
|
|
"tofolderid": extractID(dstDir.GetID()),
|
|
"toname": srcObj.GetName(),
|
|
})
|
|
}, &resp)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if resp.Result != 0 {
|
|
return fmt.Errorf("pCloud error: result code %d", resp.Result)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Remove implements driver.Remove
|
|
func (d *PCloud) Remove(ctx context.Context, obj model.Obj) error {
|
|
return d.delete(obj.GetID(), obj.IsDir())
|
|
}
|
|
|
|
// Put implements driver.Put
|
|
func (d *PCloud) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
|
parentID := d.RootFolderID
|
|
if dstDir.GetID() != "" {
|
|
parentID = dstDir.GetID()
|
|
}
|
|
|
|
return d.uploadFile(ctx, stream, parentID, stream.GetName(), stream.GetSize())
|
|
} |