2022-09-04 05:03:10 +00:00
|
|
|
|
package uss
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"net/url"
|
|
|
|
|
"path"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"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/upyun/go-sdk/v3/upyun"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type USS struct {
|
|
|
|
|
model.Storage
|
|
|
|
|
Addition
|
|
|
|
|
client *upyun.UpYun
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) Config() driver.Config {
|
|
|
|
|
return config
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) GetAddition() driver.Additional {
|
2022-12-13 10:03:30 +00:00
|
|
|
|
return &d.Addition
|
2022-09-04 05:03:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-13 10:03:30 +00:00
|
|
|
|
func (d *USS) Init(ctx context.Context) error {
|
2022-09-04 05:03:10 +00:00
|
|
|
|
d.client = upyun.NewUpYun(&upyun.UpYunConfig{
|
|
|
|
|
Bucket: d.Bucket,
|
|
|
|
|
Operator: d.OperatorName,
|
|
|
|
|
Password: d.OperatorPassword,
|
|
|
|
|
})
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) Drop(ctx context.Context) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
|
|
|
|
|
prefix := getKey(dir.GetPath(), true)
|
|
|
|
|
objsChan := make(chan *upyun.FileInfo, 10)
|
2023-01-08 08:30:05 +00:00
|
|
|
|
var err error
|
|
|
|
|
go func() {
|
|
|
|
|
err = d.client.List(&upyun.GetObjectsConfig{
|
|
|
|
|
Path: prefix,
|
|
|
|
|
ObjectsChan: objsChan,
|
|
|
|
|
MaxListObjects: 0,
|
|
|
|
|
MaxListLevel: 1,
|
|
|
|
|
})
|
|
|
|
|
}()
|
|
|
|
|
if err != nil {
|
2022-09-04 05:03:10 +00:00
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
res := make([]model.Obj, 0)
|
|
|
|
|
for obj := range objsChan {
|
|
|
|
|
t := obj.Time
|
|
|
|
|
f := model.Object{
|
|
|
|
|
Name: obj.Name,
|
|
|
|
|
Size: obj.Size,
|
|
|
|
|
Modified: t,
|
|
|
|
|
IsFolder: obj.IsDir,
|
|
|
|
|
}
|
|
|
|
|
res = append(res, &f)
|
|
|
|
|
}
|
2023-01-08 08:30:05 +00:00
|
|
|
|
return res, err
|
2022-09-04 05:03:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
|
|
|
|
key := getKey(file.GetPath(), false)
|
2023-01-08 08:30:05 +00:00
|
|
|
|
host := d.Endpoint
|
|
|
|
|
if !strings.Contains(host, "://") { //判断是否包含协议头,否则https
|
2022-09-04 05:03:10 +00:00
|
|
|
|
host = "https://" + host
|
|
|
|
|
}
|
|
|
|
|
u := fmt.Sprintf("%s/%s", host, key)
|
|
|
|
|
downExp := time.Hour * time.Duration(d.SignURLExpire)
|
|
|
|
|
expireAt := time.Now().Add(downExp).Unix()
|
|
|
|
|
upd := url.QueryEscape(path.Base(file.GetPath()))
|
2023-08-30 07:16:26 +00:00
|
|
|
|
tokenOrPassword := d.AntiTheftChainToken
|
|
|
|
|
if tokenOrPassword == "" {
|
|
|
|
|
tokenOrPassword = d.OperatorPassword
|
|
|
|
|
}
|
|
|
|
|
signStr := strings.Join([]string{tokenOrPassword, fmt.Sprint(expireAt), fmt.Sprintf("/%s", key)}, "&")
|
2023-07-15 08:28:55 +00:00
|
|
|
|
upt := utils.GetMD5EncodeStr(signStr)[12:20] + fmt.Sprint(expireAt)
|
2022-09-04 05:03:10 +00:00
|
|
|
|
link := fmt.Sprintf("%s?_upd=%s&_upt=%s", u, upd, upt)
|
|
|
|
|
return &model.Link{URL: link}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
|
|
|
|
return d.client.Mkdir(getKey(path.Join(parentDir.GetPath(), dirName), true))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
|
|
|
|
|
return d.client.Move(&upyun.MoveObjectConfig{
|
|
|
|
|
SrcPath: getKey(srcObj.GetPath(), srcObj.IsDir()),
|
|
|
|
|
DestPath: getKey(path.Join(dstDir.GetPath(), srcObj.GetName()), srcObj.IsDir()),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
|
|
|
|
return d.client.Move(&upyun.MoveObjectConfig{
|
|
|
|
|
SrcPath: getKey(srcObj.GetPath(), srcObj.IsDir()),
|
|
|
|
|
DestPath: getKey(path.Join(path.Dir(srcObj.GetPath()), newName), srcObj.IsDir()),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
|
|
|
|
return d.client.Copy(&upyun.CopyObjectConfig{
|
|
|
|
|
SrcPath: getKey(srcObj.GetPath(), srcObj.IsDir()),
|
|
|
|
|
DestPath: getKey(path.Join(dstDir.GetPath(), srcObj.GetName()), srcObj.IsDir()),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) Remove(ctx context.Context, obj model.Obj) error {
|
|
|
|
|
return d.client.Delete(&upyun.DeleteObjectConfig{
|
|
|
|
|
Path: getKey(obj.GetPath(), obj.IsDir()),
|
|
|
|
|
Async: false,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *USS) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
2022-12-21 07:03:09 +00:00
|
|
|
|
// TODO not support cancel??
|
2022-09-04 05:03:10 +00:00
|
|
|
|
return d.client.Put(&upyun.PutObjectConfig{
|
|
|
|
|
Path: getKey(path.Join(dstDir.GetPath(), stream.GetName()), false),
|
|
|
|
|
Reader: stream,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var _ driver.Driver = (*USS)(nil)
|