forked from TrueCloudLab/rclone
storj: implement purge
This commit is contained in:
parent
e2886aaddf
commit
f08bb5bf66
2 changed files with 58 additions and 6 deletions
|
@ -162,6 +162,7 @@ var (
|
||||||
_ fs.PutStreamer = &Fs{}
|
_ fs.PutStreamer = &Fs{}
|
||||||
_ fs.Mover = &Fs{}
|
_ fs.Mover = &Fs{}
|
||||||
_ fs.Copier = &Fs{}
|
_ fs.Copier = &Fs{}
|
||||||
|
_ fs.Purger = &Fs{}
|
||||||
_ fs.PublicLinker = &Fs{}
|
_ fs.PublicLinker = &Fs{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -774,15 +775,63 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object,
|
||||||
return newObjectFromUplink(f, remote, newObject), nil
|
return newObjectFromUplink(f, remote, newObject), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Purge all files in the directory specified
|
||||||
|
//
|
||||||
|
// Implement this if you have a way of deleting all the files
|
||||||
|
// quicker than just running Remove() on the result of List()
|
||||||
|
//
|
||||||
|
// Return an error if it doesn't exist
|
||||||
|
func (f *Fs) Purge(ctx context.Context, dir string) error {
|
||||||
|
bucket, directory := f.absolute(dir)
|
||||||
|
if bucket == "" {
|
||||||
|
return errors.New("can't purge from root")
|
||||||
|
}
|
||||||
|
|
||||||
|
if directory == "" {
|
||||||
|
_, err := f.project.DeleteBucketWithObjects(ctx, bucket)
|
||||||
|
if errors.Is(err, uplink.ErrBucketNotFound) {
|
||||||
|
return fs.ErrorDirNotFound
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.Infof(directory, "Quick delete is available only for entire bucket. Falling back to list and delete.")
|
||||||
|
objects := f.project.ListObjects(ctx, bucket,
|
||||||
|
&uplink.ListObjectsOptions{
|
||||||
|
Prefix: directory + "/",
|
||||||
|
Recursive: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err := objects.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
empty := true
|
||||||
|
for objects.Next() {
|
||||||
|
empty = false
|
||||||
|
_, err := f.project.DeleteObject(ctx, bucket, objects.Item().Key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fs.Infof(objects.Item().Key, "Deleted")
|
||||||
|
}
|
||||||
|
|
||||||
|
if empty {
|
||||||
|
return fs.ErrorDirNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// PublicLink generates a public link to the remote path (usually readable by anyone)
|
// PublicLink generates a public link to the remote path (usually readable by anyone)
|
||||||
func (f *Fs) PublicLink(ctx context.Context, remote string, expire fs.Duration, unlink bool) (string, error) {
|
func (f *Fs) PublicLink(ctx context.Context, remote string, expire fs.Duration, unlink bool) (string, error) {
|
||||||
bucket, key := f.absolute(remote)
|
bucket, key := f.absolute(remote)
|
||||||
if len(bucket) == 0 {
|
if bucket == "" {
|
||||||
return "", errors.New("path must be specified")
|
return "", errors.New("path must be specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rclone requires that a link is only generated if the remote path exists
|
// Rclone requires that a link is only generated if the remote path exists
|
||||||
if len(key) == 0 {
|
if key == "" {
|
||||||
_, err := f.project.StatBucket(ctx, bucket)
|
_, err := f.project.StatBucket(ctx, bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
|
@ -504,7 +504,7 @@ upon backend-specific capabilities.
|
||||||
| Sia | No | No | No | No | No | No | Yes | No | No | Yes |
|
| Sia | No | No | No | No | No | No | Yes | No | No | Yes |
|
||||||
| SMB | No | No | Yes | Yes | No | No | Yes | No | No | Yes |
|
| SMB | No | No | Yes | Yes | No | No | Yes | No | No | Yes |
|
||||||
| SugarSync | Yes | Yes | Yes | Yes | No | No | Yes | Yes | No | Yes |
|
| SugarSync | Yes | Yes | Yes | Yes | No | No | Yes | Yes | No | Yes |
|
||||||
| Storj | Yes † | Yes | Yes | No | No | Yes | Yes | Yes | No | No |
|
| Storj | Yes ☨ | Yes | Yes | No | No | Yes | Yes | Yes | No | No |
|
||||||
| Uptobox | No | Yes | Yes | Yes | No | No | No | No | No | No |
|
| Uptobox | No | Yes | Yes | Yes | No | No | No | No | No | No |
|
||||||
| WebDAV | Yes | Yes | Yes | Yes | No | No | Yes ‡ | No | Yes | Yes |
|
| WebDAV | Yes | Yes | Yes | Yes | No | No | Yes ‡ | No | Yes | Yes |
|
||||||
| Yandex Disk | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes | Yes | Yes |
|
| Yandex Disk | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes | Yes | Yes |
|
||||||
|
@ -516,9 +516,12 @@ upon backend-specific capabilities.
|
||||||
This deletes a directory quicker than just deleting all the files in
|
This deletes a directory quicker than just deleting all the files in
|
||||||
the directory.
|
the directory.
|
||||||
|
|
||||||
† Note Swift and Storj implement this in order to delete
|
† Note Swift implements this in order to delete directory markers but
|
||||||
directory markers but they don't actually have a quicker way of deleting
|
they don't actually have a quicker way of deleting files other than
|
||||||
files other than deleting them individually.
|
deleting them individually.
|
||||||
|
|
||||||
|
☨ Storj implements this efficiently only for entire buckets. If
|
||||||
|
purging a directory inside a bucket, files are deleted individually.
|
||||||
|
|
||||||
‡ StreamUpload is not supported with Nextcloud
|
‡ StreamUpload is not supported with Nextcloud
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue