fix: enhance file deletion handling and add option to hide uploading files and fix cloudreve refresh_token get error

cloudreve_v4_token
AlistDev 2025-07-05 09:48:41 +08:00
parent 9da56bab4d
commit ba8edd25a7
4 changed files with 73 additions and 12 deletions

View File

@ -91,6 +91,13 @@ func (d *CloudreveV4) List(ctx context.Context, dir model.Obj, args model.ListAr
break
}
params["next_page_token"] = r.Pagination.NextToken
if d.HideUploading {
f = utils.SliceFilter(f, func(src File) bool {
// Filter out files that are currently being uploaded
return src.Metadata == nil || src.Metadata[MetadataUploadSessionID] == nil
})
}
}
return utils.SliceConvert(f, func(src File) (model.Obj, error) {
@ -105,7 +112,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] != nil {
var t FileThumbResp
err := d.request(http.MethodGet, "/file/thumb", func(req *resty.Request) {
req.SetQueryParam("uri", src.Path)
@ -173,7 +180,7 @@ func (d *CloudreveV4) Move(ctx context.Context, srcObj, dstDir model.Obj) error
}
func (d *CloudreveV4) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
return d.request(http.MethodPost, "/file/create", func(req *resty.Request) {
return d.request(http.MethodPost, "/file/rename", func(req *resty.Request) {
req.SetBody(base.Json{
"new_name": newName,
"uri": srcObj.GetPath(),
@ -192,14 +199,52 @@ func (d *CloudreveV4) Copy(ctx context.Context, srcObj, dstDir model.Obj) error
}, nil)
}
func (d *CloudreveV4) Remove(ctx context.Context, obj model.Obj) error {
return d.request(http.MethodDelete, "/file", func(req *resty.Request) {
req.SetBody(base.Json{
"uris": []string{obj.GetPath()},
func (c *CloudreveV4) Remove(ctx context.Context, target model.Obj) error {
path := target.GetPath()
deletePayload := func() base.Json {
return base.Json{
"uris": []string{path},
"unlink": false,
"skip_soft_delete": true,
})
}, nil)
}
}
var resp FileDeleteResp
del := func() error {
return c.request(http.MethodDelete, "/file", func(req *resty.Request) {
req.SetBody(deletePayload())
req.SetResult(&resp)
}, nil)
}
// 尝试第一次删除
if err := del(); err != nil {
return err
}
if resp.Code == 0 {
return nil
}
// 若存在锁冲突,则先清除锁再重试
if resp.Code == 40073 && resp.Msg == "Lock conflict" && len(resp.Data) > 0 {
var lockTokens []string
for _, entry := range resp.Data {
lockTokens = append(lockTokens, entry.Token)
}
// 先解锁
if err := c.request(http.MethodDelete, "/file/lock", func(req *resty.Request) {
req.SetBody(base.Json{"tokens": lockTokens})
}, nil); err != nil {
return err
}
// 再次尝试删除
return del()
}
return errors.New(resp.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/alist-org/alist/v3/internal/model"
)
const (
MetadataUploadSessionID = "sys:upload_session_id"
MetadataThumbDisabled = "thumb:disabled"
)
type Object struct {
model.Object
StoragePolicy StoragePolicy
@ -88,7 +93,7 @@ type File struct {
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Size int64 `json:"size"`
Metadata interface{} `json:"metadata"`
Metadata map[any]any `json:"metadata"`
Path string `json:"path"`
Capability string `json:"capability"`
Owned bool `json:"owned"`
@ -147,6 +152,15 @@ type FileUploadResp struct {
Credential string `json:"credential,omitempty"` // for local
}
type FileDeleteResp struct {
Resp
Data []struct {
Path string `json:"path"`
Token string `json:"token"`
Type int `json:"type"`
} `json:"data,omitempty"`
}
type FileThumbResp struct {
URL string `json:"url"`
Expires time.Time `json:"expires"`

View File

@ -175,8 +175,8 @@ func (d *CloudreveV4) doLogin(needCaptcha bool) error {
}
func (d *CloudreveV4) refreshToken() error {
var token Token
if token.RefreshToken == "" {
//var token Token
if d.RefreshToken == "" {
if d.Username != "" {
err := d.login()
if err != nil {
@ -185,6 +185,7 @@ func (d *CloudreveV4) refreshToken() error {
}
return nil
}
var token Token
err := d.request(http.MethodPost, "/session/token/refresh", func(req *resty.Request) {
req.SetBody(base.Json{
"refresh_token": d.RefreshToken,
@ -470,7 +471,7 @@ func (d *CloudreveV4) upS3(ctx context.Context, file model.FileStreamer, u FileU
}
// 上传成功发送回调请求
return d.request(http.MethodPost, "/callback/s3/"+u.SessionID+"/"+u.CallbackSecret, func(req *resty.Request) {
return d.request(http.MethodGet, "/callback/s3/"+u.SessionID+"/"+u.CallbackSecret, func(req *resty.Request) {
req.SetBody("{}")
}, nil)
}