feat(cloudreve_v4): enhance metadata and lock conflict handling (#485)

* feat(cloudreve_v4): add metadata constants

* fix(cloudreve_v4): enhance thumbnail handling

* feat(cloudreve_v4): add HideUploading option

* fix(cloudreve_v4): handle lock conflict during file deletion
This commit is contained in:
MadDogOwner
2025-07-01 01:06:28 +08:00
committed by GitHub
parent 862b1c3c53
commit 9442013b37
3 changed files with 70 additions and 13 deletions

View File

@ -93,6 +93,12 @@ func (d *CloudreveV4) List(ctx context.Context, dir model.Obj, args model.ListAr
params["next_page_token"] = r.Pagination.NextToken
}
if d.HideUploading {
f = utils.SliceFilter(f, func(src File) bool {
return src.Metadata == nil || src.Metadata[MetadataUploadSessionID] == nil
})
}
return utils.SliceConvert(f, func(src File) (model.Obj, error) {
if d.EnableFolderSize && src.Type == 1 {
var ds FolderSummaryResp
@ -105,7 +111,7 @@ func (d *CloudreveV4) List(ctx context.Context, dir model.Obj, args model.ListAr
}
}
var thumb model.Thumbnail
if d.EnableThumb && src.Type == 0 {
if d.EnableThumb && src.Type == 0 && (src.Metadata == nil || src.Metadata[MetadataThumbDisabled] == "") {
var t FileThumbResp
err := d.request(http.MethodGet, "/file/thumb", func(req *resty.Request) {
req.SetQueryParam("uri", src.Path)
@ -192,13 +198,43 @@ func (d *CloudreveV4) Copy(ctx context.Context, srcObj, dstDir model.Obj) error
}
func (d *CloudreveV4) Remove(ctx context.Context, obj model.Obj) error {
return d.request(http.MethodDelete, "/file", func(req *resty.Request) {
var r FileDeleteResp
err := d.request(http.MethodDelete, "/file", func(req *resty.Request) {
req.SetBody(base.Json{
"uris": []string{obj.GetPath()},
"unlink": false,
"skip_soft_delete": true,
})
req.SetResult(&r)
}, nil)
if err != nil {
return err
}
if r.Code == 0 {
return nil
}
if r.Code == 40073 && r.Msg == "Lock conflict" && len(r.Data) > 0 {
tokens := make([]string, 0, len(r.Data))
for _, item := range r.Data {
tokens = append(tokens, item.Token)
}
err = d.request(http.MethodDelete, "/file/lock", func(req *resty.Request) {
req.SetBody(base.Json{
"tokens": tokens,
})
}, nil)
if err != nil {
return err
}
return d.request(http.MethodDelete, "/file", func(req *resty.Request) {
req.SetBody(base.Json{
"uris": []string{obj.GetPath()},
"unlink": false,
"skip_soft_delete": true,
})
}, nil)
}
return errors.New(r.Msg)
}
func (d *CloudreveV4) Put(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) error {

View File

@ -19,6 +19,7 @@ type Addition struct {
EnableFolderSize bool `json:"enable_folder_size"`
EnableThumb bool `json:"enable_thumb"`
EnableVersionUpload bool `json:"enable_version_upload"`
HideUploading bool `json:"hide_uploading"`
OrderBy string `json:"order_by" type:"select" options:"name,size,updated_at,created_at" default:"name" required:"true"`
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc" required:"true"`
}

View File

@ -6,6 +6,11 @@ import (
"github.com/OpenListTeam/OpenList/internal/model"
)
const (
MetadataUploadSessionID = "sys:upload_session_id"
MetadataThumbDisabled = "thumb:disabled"
)
type Object struct {
model.Object
StoragePolicy StoragePolicy
@ -82,17 +87,17 @@ type TokenResponse struct {
}
type File struct {
Type int `json:"type"` // 0: file, 1: folder
ID string `json:"id"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Size int64 `json:"size"`
Metadata interface{} `json:"metadata"`
Path string `json:"path"`
Capability string `json:"capability"`
Owned bool `json:"owned"`
PrimaryEntity string `json:"primary_entity"`
Type int `json:"type"` // 0: file, 1: folder
ID string `json:"id"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Size int64 `json:"size"`
Metadata map[string]any `json:"metadata,omitempty"`
Path string `json:"path"`
Capability string `json:"capability"`
Owned bool `json:"owned"`
PrimaryEntity string `json:"primary_entity"`
}
type StoragePolicy struct {
@ -147,6 +152,21 @@ type FileUploadResp struct {
Credential string `json:"credential,omitempty"` // for local
}
type FileDeleteResp struct {
Resp
Data []struct {
Path string `json:"path"`
Token string `json:"token"`
// Owner struct {
// Owner string `json:"owner"`
// Application struct {
// Type string `json:"type"`
// } `json:"application"`
// } `json:"owner"`
Type int `json:"type"`
} `json:"data,omitempty"`
}
type FileThumbResp struct {
URL string `json:"url"`
Expires time.Time `json:"expires"`