mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2025-09-19 12:16:24 +08:00

* perf(stream): improve file stream range reading and caching mechanism * 。 * add bytes_test.go * fix(stream): handle EOF and buffer reading more gracefully * 注释 * refactor: update CacheFullAndWriter to accept pointer for UpdateProgress * update tests * Update drivers/google_drive/util.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com> * 更优雅的克隆Link * 修复stream已缓存但无法重复读取 * 将Bytes类型重命名为Reader * 修复栈溢出 * update tests --------- Signed-off-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
157 lines
4.2 KiB
Go
157 lines
4.2 KiB
Go
package alias
|
|
|
|
import (
|
|
"context"
|
|
stdpath "path"
|
|
"strings"
|
|
|
|
"github.com/OpenListTeam/OpenList/v4/internal/driver"
|
|
"github.com/OpenListTeam/OpenList/v4/internal/errs"
|
|
"github.com/OpenListTeam/OpenList/v4/internal/fs"
|
|
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
|
"github.com/OpenListTeam/OpenList/v4/internal/op"
|
|
"github.com/OpenListTeam/OpenList/v4/server/common"
|
|
)
|
|
|
|
func (d *Alias) listRoot() []model.Obj {
|
|
var objs []model.Obj
|
|
for k := range d.pathMap {
|
|
obj := model.Object{
|
|
Name: k,
|
|
IsFolder: true,
|
|
Modified: d.Modified,
|
|
}
|
|
objs = append(objs, &obj)
|
|
}
|
|
return objs
|
|
}
|
|
|
|
// do others that not defined in Driver interface
|
|
func getPair(path string) (string, string) {
|
|
//path = strings.TrimSpace(path)
|
|
if strings.Contains(path, ":") {
|
|
pair := strings.SplitN(path, ":", 2)
|
|
if !strings.Contains(pair[0], "/") {
|
|
return pair[0], pair[1]
|
|
}
|
|
}
|
|
return stdpath.Base(path), path
|
|
}
|
|
|
|
func (d *Alias) getRootAndPath(path string) (string, string) {
|
|
if d.autoFlatten {
|
|
return d.oneKey, path
|
|
}
|
|
path = strings.TrimPrefix(path, "/")
|
|
parts := strings.SplitN(path, "/", 2)
|
|
if len(parts) == 1 {
|
|
return parts[0], ""
|
|
}
|
|
return parts[0], parts[1]
|
|
}
|
|
|
|
func (d *Alias) link(ctx context.Context, reqPath string, args model.LinkArgs) (*model.Link, model.Obj, error) {
|
|
storage, reqActualPath, err := op.GetStorageAndActualPath(reqPath)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
if !args.Redirect {
|
|
return op.Link(ctx, storage, reqActualPath, args)
|
|
}
|
|
obj, err := fs.Get(ctx, reqPath, &fs.GetArgs{NoLog: true})
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
if common.ShouldProxy(storage, stdpath.Base(reqPath)) {
|
|
return nil, obj, nil
|
|
}
|
|
return op.Link(ctx, storage, reqActualPath, args)
|
|
}
|
|
|
|
func (d *Alias) getReqPath(ctx context.Context, obj model.Obj, isParent bool) ([]*string, error) {
|
|
root, sub := d.getRootAndPath(obj.GetPath())
|
|
if sub == "" && !isParent {
|
|
return nil, errs.NotSupport
|
|
}
|
|
dsts, ok := d.pathMap[root]
|
|
all := true
|
|
if !ok {
|
|
return nil, errs.ObjectNotFound
|
|
}
|
|
var reqPath []*string
|
|
for _, dst := range dsts {
|
|
path := stdpath.Join(dst, sub)
|
|
_, err := fs.Get(ctx, path, &fs.GetArgs{NoLog: true})
|
|
if err != nil {
|
|
all = false
|
|
if d.ProtectSameName && d.ParallelWrite && len(reqPath) >= 2 {
|
|
return nil, errs.NotImplement
|
|
}
|
|
continue
|
|
}
|
|
if !d.ProtectSameName && !d.ParallelWrite {
|
|
return []*string{&path}, nil
|
|
}
|
|
reqPath = append(reqPath, &path)
|
|
if d.ProtectSameName && !d.ParallelWrite && len(reqPath) >= 2 {
|
|
return nil, errs.NotImplement
|
|
}
|
|
if d.ProtectSameName && d.ParallelWrite && len(reqPath) >= 2 && !all {
|
|
return nil, errs.NotImplement
|
|
}
|
|
}
|
|
if len(reqPath) == 0 {
|
|
return nil, errs.ObjectNotFound
|
|
}
|
|
return reqPath, nil
|
|
}
|
|
|
|
func (d *Alias) getArchiveMeta(ctx context.Context, dst, sub string, args model.ArchiveArgs) (model.ArchiveMeta, error) {
|
|
reqPath := stdpath.Join(dst, sub)
|
|
storage, reqActualPath, err := op.GetStorageAndActualPath(reqPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if _, ok := storage.(driver.ArchiveReader); ok {
|
|
return op.GetArchiveMeta(ctx, storage, reqActualPath, model.ArchiveMetaArgs{
|
|
ArchiveArgs: args,
|
|
Refresh: true,
|
|
})
|
|
}
|
|
return nil, errs.NotImplement
|
|
}
|
|
|
|
func (d *Alias) listArchive(ctx context.Context, dst, sub string, args model.ArchiveInnerArgs) ([]model.Obj, error) {
|
|
reqPath := stdpath.Join(dst, sub)
|
|
storage, reqActualPath, err := op.GetStorageAndActualPath(reqPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if _, ok := storage.(driver.ArchiveReader); ok {
|
|
return op.ListArchive(ctx, storage, reqActualPath, model.ArchiveListArgs{
|
|
ArchiveInnerArgs: args,
|
|
Refresh: true,
|
|
})
|
|
}
|
|
return nil, errs.NotImplement
|
|
}
|
|
|
|
func (d *Alias) extract(ctx context.Context, reqPath string, args model.ArchiveInnerArgs) (*model.Link, error) {
|
|
storage, reqActualPath, err := op.GetStorageAndActualPath(reqPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if _, ok := storage.(driver.ArchiveReader); !ok {
|
|
return nil, errs.NotImplement
|
|
}
|
|
if args.Redirect && common.ShouldProxy(storage, stdpath.Base(reqPath)) {
|
|
_, err := fs.Get(ctx, reqPath, &fs.GetArgs{NoLog: true})
|
|
if err == nil {
|
|
return nil, err
|
|
}
|
|
return nil, nil
|
|
}
|
|
link, _, err := op.DriverExtract(ctx, storage, reqActualPath, args)
|
|
return link, err
|
|
}
|