|
package alias |
|
|
|
import ( |
|
"context" |
|
"errors" |
|
"strings" |
|
|
|
"github.com/alist-org/alist/v3/internal/driver" |
|
"github.com/alist-org/alist/v3/internal/errs" |
|
"github.com/alist-org/alist/v3/internal/fs" |
|
"github.com/alist-org/alist/v3/internal/model" |
|
"github.com/alist-org/alist/v3/pkg/utils" |
|
) |
|
|
|
type Alias struct { |
|
model.Storage |
|
Addition |
|
pathMap map[string][]string |
|
autoFlatten bool |
|
oneKey string |
|
} |
|
|
|
func (d *Alias) Config() driver.Config { |
|
return config |
|
} |
|
|
|
func (d *Alias) GetAddition() driver.Additional { |
|
return &d.Addition |
|
} |
|
|
|
func (d *Alias) Init(ctx context.Context) error { |
|
if d.Paths == "" { |
|
return errors.New("paths is required") |
|
} |
|
d.pathMap = make(map[string][]string) |
|
for _, path := range strings.Split(d.Paths, "\n") { |
|
path = strings.TrimSpace(path) |
|
if path == "" { |
|
continue |
|
} |
|
k, v := getPair(path) |
|
d.pathMap[k] = append(d.pathMap[k], v) |
|
} |
|
if len(d.pathMap) == 1 { |
|
for k := range d.pathMap { |
|
d.oneKey = k |
|
} |
|
d.autoFlatten = true |
|
} else { |
|
d.oneKey = "" |
|
d.autoFlatten = false |
|
} |
|
return nil |
|
} |
|
|
|
func (d *Alias) Drop(ctx context.Context) error { |
|
d.pathMap = nil |
|
return nil |
|
} |
|
|
|
func (d *Alias) Get(ctx context.Context, path string) (model.Obj, error) { |
|
if utils.PathEqual(path, "/") { |
|
return &model.Object{ |
|
Name: "Root", |
|
IsFolder: true, |
|
Path: "/", |
|
}, nil |
|
} |
|
root, sub := d.getRootAndPath(path) |
|
dsts, ok := d.pathMap[root] |
|
if !ok { |
|
return nil, errs.ObjectNotFound |
|
} |
|
for _, dst := range dsts { |
|
obj, err := d.get(ctx, path, dst, sub) |
|
if err == nil { |
|
return obj, nil |
|
} |
|
} |
|
return nil, errs.ObjectNotFound |
|
} |
|
|
|
func (d *Alias) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { |
|
path := dir.GetPath() |
|
if utils.PathEqual(path, "/") && !d.autoFlatten { |
|
return d.listRoot(), nil |
|
} |
|
root, sub := d.getRootAndPath(path) |
|
dsts, ok := d.pathMap[root] |
|
if !ok { |
|
return nil, errs.ObjectNotFound |
|
} |
|
var objs []model.Obj |
|
fsArgs := &fs.ListArgs{NoLog: true, Refresh: args.Refresh} |
|
for _, dst := range dsts { |
|
tmp, err := d.list(ctx, dst, sub, fsArgs) |
|
if err == nil { |
|
objs = append(objs, tmp...) |
|
} |
|
} |
|
return objs, nil |
|
} |
|
|
|
func (d *Alias) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { |
|
root, sub := d.getRootAndPath(file.GetPath()) |
|
dsts, ok := d.pathMap[root] |
|
if !ok { |
|
return nil, errs.ObjectNotFound |
|
} |
|
for _, dst := range dsts { |
|
link, err := d.link(ctx, dst, sub, args) |
|
if err == nil { |
|
return link, nil |
|
} |
|
} |
|
return nil, errs.ObjectNotFound |
|
} |
|
|
|
func (d *Alias) Rename(ctx context.Context, srcObj model.Obj, newName string) error { |
|
reqPath, err := d.getReqPath(ctx, srcObj) |
|
if err == nil { |
|
return fs.Rename(ctx, *reqPath, newName) |
|
} |
|
if errs.IsNotImplement(err) { |
|
return errors.New("same-name files cannot be Rename") |
|
} |
|
return err |
|
} |
|
|
|
func (d *Alias) Remove(ctx context.Context, obj model.Obj) error { |
|
reqPath, err := d.getReqPath(ctx, obj) |
|
if err == nil { |
|
return fs.Remove(ctx, *reqPath) |
|
} |
|
if errs.IsNotImplement(err) { |
|
return errors.New("same-name files cannot be Delete") |
|
} |
|
return err |
|
} |
|
|
|
var _ driver.Driver = (*Alias)(nil) |
|
|