diff --git a/drivers/cloudreve_v4/driver.go b/drivers/cloudreve_v4/driver.go index e486874c..b985018b 100644 --- a/drivers/cloudreve_v4/driver.go +++ b/drivers/cloudreve_v4/driver.go @@ -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 { diff --git a/drivers/cloudreve_v4/meta.go b/drivers/cloudreve_v4/meta.go index f1ea1098..f0f8edd1 100644 --- a/drivers/cloudreve_v4/meta.go +++ b/drivers/cloudreve_v4/meta.go @@ -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"` } diff --git a/drivers/cloudreve_v4/types.go b/drivers/cloudreve_v4/types.go index b01bc4e9..a28f3d8f 100644 --- a/drivers/cloudreve_v4/types.go +++ b/drivers/cloudreve_v4/types.go @@ -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"`