alist/drivers/uss/driver.go

134 lines
3.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 {
return &d.Addition
}
func (d *USS) Init(ctx context.Context) error {
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)
var err error
go func() {
err = d.client.List(&upyun.GetObjectsConfig{
Path: prefix,
ObjectsChan: objsChan,
MaxListObjects: 0,
MaxListLevel: 1,
})
}()
if err != nil {
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)
}
return res, err
}
func (d *USS) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
key := getKey(file.GetPath(), false)
host := d.Endpoint
if !strings.Contains(host, "://") { //判断是否包含协议头否则https
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()))
tokenOrPassword := d.AntiTheftChainToken
if tokenOrPassword == "" {
tokenOrPassword = d.OperatorPassword
}
signStr := strings.Join([]string{tokenOrPassword, fmt.Sprint(expireAt), fmt.Sprintf("/%s", key)}, "&")
upt := utils.GetMD5EncodeStr(signStr)[12:20] + fmt.Sprint(expireAt)
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 {
// TODO not support cancel??
return d.client.Put(&upyun.PutObjectConfig{
Path: getKey(path.Join(dstDir.GetPath(), stream.GetName()), false),
Reader: stream,
})
}
var _ driver.Driver = (*USS)(nil)