Skip to content

Commit d31e1a3

Browse files
authored
feat(model): add object mask support and enhance cache/task handling (#1743)
1 parent e1bba70 commit d31e1a3

File tree

26 files changed

+623
-471
lines changed

26 files changed

+623
-471
lines changed

drivers/alias/driver.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ func (d *Alias) Get(ctx context.Context, path string) (model.Obj, error) {
8585
}
8686
var ret *model.Object
8787
provider := ""
88+
var mask model.ObjMask
8889
for _, dst := range dsts {
8990
rawPath := stdpath.Join(dst, sub)
9091
obj, err := fs.Get(ctx, rawPath, &fs.GetArgs{NoLog: true})
@@ -93,6 +94,8 @@ func (d *Alias) Get(ctx context.Context, path string) (model.Obj, error) {
9394
}
9495
storage, err := fs.GetStorage(rawPath, &fs.GetStoragesArgs{})
9596
if ret == nil {
97+
mask = model.GetObjMask(obj)
98+
mask &^= model.Temp
9699
ret = &model.Object{
97100
Path: path,
98101
Name: obj.GetName(),
@@ -114,14 +117,14 @@ func (d *Alias) Get(ctx context.Context, path string) (model.Obj, error) {
114117
return nil, errs.ObjectNotFound
115118
}
116119
if provider != "" {
117-
return &model.ObjectProvider{
120+
return model.ObjAddMask(&model.ObjectProvider{
118121
Object: *ret,
119122
Provider: model.Provider{
120123
Provider: provider,
121124
},
122-
}, nil
125+
}, mask), nil
123126
}
124-
return ret, nil
127+
return model.ObjAddMask(ret, mask), nil
125128
}
126129

127130
func (d *Alias) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
@@ -150,21 +153,23 @@ func (d *Alias) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([
150153
Modified: obj.ModTime(),
151154
IsFolder: obj.IsDir(),
152155
}
156+
mask := model.GetObjMask(obj)
157+
mask &^= model.Temp
153158
if thumb, ok := model.GetThumb(obj); ok {
154-
return &model.ObjThumb{
159+
return model.ObjAddMask(&model.ObjThumb{
155160
Object: objRes,
156161
Thumbnail: model.Thumbnail{
157162
Thumbnail: thumb,
158163
},
159-
}, nil
164+
}, mask), nil
160165
}
161166
if details, ok := model.GetStorageDetails(obj); ok {
162-
return &model.ObjStorageDetails{
167+
return model.ObjAddMask(&model.ObjStorageDetails{
163168
Obj: &objRes,
164169
StorageDetailsWithName: *details,
165-
}, nil
170+
}, mask), nil
166171
}
167-
return &objRes, nil
172+
return model.ObjAddMask(&objRes, mask), nil
168173
})
169174
}
170175
if err == nil {

drivers/alias/util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func (d *Alias) listRoot(ctx context.Context, withDetails, refresh bool) []model
3333
Modified: d.Modified,
3434
}
3535
idx := len(objs)
36-
objs = append(objs, &obj)
36+
objs = append(objs, model.ObjAddMask(&obj, model.Virtual))
3737
v := d.pathMap[k]
3838
if !withDetails || len(v) != 1 {
3939
continue

drivers/chunk/driver.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strconv"
1111
"strings"
1212

13+
"github.com/OpenListTeam/OpenList/v4/internal/conf"
1314
"github.com/OpenListTeam/OpenList/v4/internal/driver"
1415
"github.com/OpenListTeam/OpenList/v4/internal/errs"
1516
"github.com/OpenListTeam/OpenList/v4/internal/fs"
@@ -426,17 +427,18 @@ func (d *Chunk) Put(ctx context.Context, dstDir model.Obj, file model.FileStream
426427
UpdateProgress: up,
427428
}
428429
dst := stdpath.Join(remoteActualPath, dstDir.GetPath(), d.ChunkPrefix+file.GetName())
430+
skipHookCtx := context.WithValue(ctx, conf.SkipHookKey, struct{}{})
429431
if d.StoreHash {
430432
for ht, value := range file.GetHash().All() {
431-
_ = op.Put(ctx, remoteStorage, dst, &stream.FileStream{
433+
_ = op.Put(skipHookCtx, remoteStorage, dst, &stream.FileStream{
432434
Obj: &model.Object{
433435
Name: fmt.Sprintf("hash_%s_%s%s", ht.Name, value, d.CustomExt),
434436
Size: 1,
435437
Modified: file.ModTime(),
436438
},
437439
Mimetype: "application/octet-stream",
438440
Reader: bytes.NewReader([]byte{0}), // 兼容不支持空文件的驱动
439-
}, nil, true)
441+
}, nil)
440442
}
441443
}
442444
fullPartCount := int(file.GetSize() / d.PartSize)
@@ -447,15 +449,15 @@ func (d *Chunk) Put(ctx context.Context, dstDir model.Obj, file model.FileStream
447449
}
448450
partIndex := 0
449451
for partIndex < fullPartCount {
450-
err = op.Put(ctx, remoteStorage, dst, &stream.FileStream{
452+
err = op.Put(skipHookCtx, remoteStorage, dst, &stream.FileStream{
451453
Obj: &model.Object{
452454
Name: d.getPartName(partIndex),
453455
Size: d.PartSize,
454456
Modified: file.ModTime(),
455457
},
456458
Mimetype: file.GetMimetype(),
457459
Reader: io.LimitReader(upReader, d.PartSize),
458-
}, nil, true)
460+
}, nil)
459461
if err != nil {
460462
_ = op.Remove(ctx, remoteStorage, dst)
461463
return err

drivers/crypt/driver.go

Lines changed: 61 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package crypt
33
import (
44
"bytes"
55
"context"
6+
"errors"
67
"fmt"
78
"io"
89
stdpath "path"
@@ -109,43 +110,35 @@ func (d *Crypt) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([
109110

110111
result := make([]model.Obj, 0, len(objs))
111112
for _, obj := range objs {
112-
rawName := model.UnwrapObj(obj).GetName()
113-
if obj.IsDir() {
114-
name, err := d.cipher.DecryptDirName(rawName)
115-
if err != nil {
116-
// filter illegal files
117-
continue
118-
}
119-
if !d.ShowHidden && strings.HasPrefix(name, ".") {
120-
continue
113+
size := obj.GetSize()
114+
mask := model.GetObjMask(obj)
115+
name := obj.GetName()
116+
if mask&model.Virtual == 0 {
117+
if obj.IsDir() {
118+
name, err = d.cipher.DecryptDirName(model.UnwrapObjName(obj).GetName())
119+
if err != nil {
120+
// filter illegal files
121+
continue
122+
}
123+
} else {
124+
size, err = d.cipher.DecryptedSize(size)
125+
if err != nil {
126+
// filter illegal files
127+
continue
128+
}
129+
name, err = d.cipher.DecryptFileName(model.UnwrapObjName(obj).GetName())
130+
if err != nil {
131+
// filter illegal files
132+
continue
133+
}
121134
}
122-
result = append(result, &model.Object{
123-
Path: stdpath.Join(remoteFullPath, rawName),
124-
Name: name,
125-
Size: 0,
126-
Modified: obj.ModTime(),
127-
IsFolder: obj.IsDir(),
128-
Ctime: obj.CreateTime(),
129-
// discarding hash as it's encrypted
130-
})
131-
continue
132-
}
133-
134-
size, err := d.cipher.DecryptedSize(obj.GetSize())
135-
if err != nil {
136-
// filter illegal files
137-
continue
138-
}
139-
name, err := d.cipher.DecryptFileName(rawName)
140-
if err != nil {
141-
// filter illegal files
142-
continue
143135
}
144136
if !d.ShowHidden && strings.HasPrefix(name, ".") {
145137
continue
146138
}
139+
mask &^= model.Temp
147140
objRes := &model.Object{
148-
Path: stdpath.Join(remoteFullPath, rawName),
141+
Path: stdpath.Join(remoteFullPath, obj.GetName()),
149142
Name: name,
150143
Size: size,
151144
Modified: obj.ModTime(),
@@ -154,20 +147,20 @@ func (d *Crypt) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([
154147
// discarding hash as it's encrypted
155148
}
156149
if !d.Thumbnail || !strings.HasPrefix(args.ReqPath, "/") {
157-
result = append(result, objRes)
150+
result = append(result, model.ObjAddMask(objRes, mask))
158151
continue
159152
}
160153
thumbPath := stdpath.Join(args.ReqPath, ".thumbnails", name+".webp")
161154
thumb := fmt.Sprintf("%s/d%s?sign=%s",
162155
common.GetApiUrl(ctx),
163156
utils.EncodePath(thumbPath, true),
164157
sign.Sign(thumbPath))
165-
result = append(result, &model.ObjThumb{
158+
result = append(result, model.ObjAddMask(&model.ObjThumb{
166159
Object: *objRes,
167160
Thumbnail: model.Thumbnail{
168161
Thumbnail: thumb,
169162
},
170-
})
163+
}, mask))
171164
}
172165

173166
return result, nil
@@ -182,7 +175,14 @@ func (d *Crypt) Get(ctx context.Context, path string) (model.Obj, error) {
182175
remoteFullPath := stdpath.Join(d.RemotePath, d.encryptPath(path, firstTryIsFolder))
183176
remoteObj, err := fs.Get(ctx, remoteFullPath, &fs.GetArgs{NoLog: true})
184177
if err != nil {
185-
if secondTry && errs.IsObjectNotFound(err) {
178+
if errors.Is(err, errs.StorageNotFound) {
179+
remoteFullPath = stdpath.Join(d.RemotePath, path)
180+
remoteObj, err = fs.Get(ctx, remoteFullPath, &fs.GetArgs{NoLog: true})
181+
if err != nil {
182+
// 可能是 虚拟路径+开启文件夹加密:返回NotSupport让op.Get去尝试op.List查找
183+
return nil, errs.NotSupport
184+
}
185+
} else if secondTry && errs.IsObjectNotFound(err) {
186186
// try the opposite
187187
remoteFullPath = stdpath.Join(d.RemotePath, d.encryptPath(path, !firstTryIsFolder))
188188
remoteObj, err = fs.Get(ctx, remoteFullPath, &fs.GetArgs{NoLog: true})
@@ -195,20 +195,30 @@ func (d *Crypt) Get(ctx context.Context, path string) (model.Obj, error) {
195195
}
196196

197197
size := remoteObj.GetSize()
198-
name := model.UnwrapObj(remoteObj).GetName()
199-
if !remoteObj.IsDir() {
200-
size, err = d.cipher.DecryptedSize(size)
201-
if err != nil {
202-
log.Warnf("DecryptedSize failed for %s ,will use original size, err:%s", path, err)
203-
}
204-
name, err = d.cipher.DecryptFileName(name)
205-
if err != nil {
206-
log.Warnf("DecryptFileName failed for %s ,will use original name, err:%s", path, err)
207-
}
208-
} else {
209-
name, err = d.cipher.DecryptDirName(name)
210-
if err != nil {
211-
log.Warnf("DecryptDirName failed for %s ,will use original name, err:%s", path, err)
198+
name := remoteObj.GetName()
199+
mask := model.GetObjMask(remoteObj)
200+
mask &^= model.Temp
201+
if mask&model.Virtual == 0 {
202+
if !remoteObj.IsDir() {
203+
decryptedSize, err := d.cipher.DecryptedSize(size)
204+
if err != nil {
205+
log.Warnf("DecryptedSize failed for %s ,will use original size, err:%s", path, err)
206+
} else {
207+
size = decryptedSize
208+
}
209+
decryptedName, err := d.cipher.DecryptFileName(model.UnwrapObjName(remoteObj).GetName())
210+
if err != nil {
211+
log.Warnf("DecryptFileName failed for %s ,will use original name, err:%s", path, err)
212+
} else {
213+
name = decryptedName
214+
}
215+
} else {
216+
decryptedName, err := d.cipher.DecryptDirName(model.UnwrapObjName(remoteObj).GetName())
217+
if err != nil {
218+
log.Warnf("DecryptDirName failed for %s ,will use original name, err:%s", path, err)
219+
} else {
220+
name = decryptedName
221+
}
212222
}
213223
}
214224
obj := &model.Object{
@@ -217,8 +227,9 @@ func (d *Crypt) Get(ctx context.Context, path string) (model.Obj, error) {
217227
Size: size,
218228
Modified: remoteObj.ModTime(),
219229
IsFolder: remoteObj.IsDir(),
230+
Ctime: remoteObj.CreateTime(),
220231
}
221-
return obj, nil
232+
return model.ObjAddMask(obj, mask), nil
222233
}
223234

224235
// https://github.com/rclone/rclone/blob/v1.67.0/backend/crypt/cipher.go#L37

internal/cache/keyed_cache.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (c *KeyedCache[T]) Delete(key string) {
7070
delete(c.entries, key)
7171
}
7272

73-
func (c *KeyedCache[T]) Take(key string) (T, bool) {
73+
func (c *KeyedCache[T]) Pop(key string) (T, bool) {
7474
c.mu.Lock()
7575
defer c.mu.Unlock()
7676
if entry, exists := c.entries[key]; exists {

internal/conf/const.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ const (
170170
)
171171

172172
// ContextKey is the type of context keys.
173-
type ContextKey int
173+
type ContextKey int8
174174

175175
const (
176176
_ ContextKey = iota
@@ -186,4 +186,5 @@ const (
186186
UserAgentKey
187187
PathKey
188188
SharingIDKey
189+
SkipHookKey
189190
)

internal/driver/driver.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,6 @@ type PutURL interface {
110110
PutURL(ctx context.Context, dstDir model.Obj, name, url string) error
111111
}
112112

113-
//type WriteResult interface {
114-
// MkdirResult
115-
// MoveResult
116-
// RenameResult
117-
// CopyResult
118-
// PutResult
119-
// Remove
120-
//}
121-
122113
type MkdirResult interface {
123114
MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error)
124115
}

0 commit comments

Comments
 (0)