forked from TrueCloudLab/rclone
about: add new command 'about' to get quota info from a remote
Implemented for drive only. Relates to #1138 and #1564.
This commit is contained in:
parent
b83814082b
commit
94e277d759
9 changed files with 130 additions and 21 deletions
13
backend/cache/cache.go
vendored
13
backend/cache/cache.go
vendored
|
@ -1413,6 +1413,18 @@ func (f *Fs) CleanUp() error {
|
|||
return do()
|
||||
}
|
||||
|
||||
// About gets quota information from the Fs
|
||||
func (f *Fs) About() error {
|
||||
f.CleanUpCache(false)
|
||||
|
||||
do := f.Fs.Features().About
|
||||
if do == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return do()
|
||||
}
|
||||
|
||||
// Stats returns stats about the cache storage
|
||||
func (f *Fs) Stats() (map[string]map[string]interface{}, error) {
|
||||
return f.cache.Stats()
|
||||
|
@ -1551,4 +1563,5 @@ var (
|
|||
_ fs.Wrapper = (*Fs)(nil)
|
||||
_ fs.ListRer = (*Fs)(nil)
|
||||
_ fs.ChangeNotifier = (*Fs)(nil)
|
||||
_ fs.Abouter = (*Fs)(nil)
|
||||
)
|
||||
|
|
|
@ -1050,6 +1050,29 @@ func (f *Fs) CleanUp() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// About gets quota information
|
||||
func (f *Fs) About() error {
|
||||
var about *drive.About
|
||||
var err error
|
||||
err = f.pacer.Call(func() (bool, error) {
|
||||
about, err = f.svc.About.Get().Fields("storageQuota").Do()
|
||||
return shouldRetry(err)
|
||||
})
|
||||
if err != nil {
|
||||
fs.Errorf(f, "Failed to get Drive storageQuota: %v", err)
|
||||
return nil
|
||||
}
|
||||
quota := float64(about.StorageQuota.Limit) / (1 << 30)
|
||||
usagetotal := float64(about.StorageQuota.Usage) / (1 << 30)
|
||||
usagedrive := float64(about.StorageQuota.UsageInDrive) / (1 << 30)
|
||||
usagetrash := float64(about.StorageQuota.UsageInDriveTrash) / (1 << 30)
|
||||
fmt.Printf("Quota: %.0f GiB | Used: %.1f GiB (Trash: %.1f GiB) | Available: %.1f GiB | Usage: %d%%\n",
|
||||
quota, usagedrive, usagetrash, quota-usagedrive, int((usagedrive/quota)*100))
|
||||
fmt.Printf("Space used in other Google services (such as Gmail): %.2f GiB\n",
|
||||
usagetotal-usagedrive)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Move src to this remote using server side move operations.
|
||||
//
|
||||
// This is stored with the remote path given
|
||||
|
|
27
cmd/about/about.go
Normal file
27
cmd/about/about.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package about
|
||||
|
||||
import (
|
||||
"github.com/ncw/rclone/cmd"
|
||||
"github.com/ncw/rclone/fs/operations"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmd.Root.AddCommand(commandDefintion)
|
||||
}
|
||||
|
||||
var commandDefintion = &cobra.Command{
|
||||
Use: "about remote:",
|
||||
Short: `Get quota information from the remote.`,
|
||||
Long: `
|
||||
Get quota information from the remote, like bytes used/free/quota and bytes
|
||||
used in the trash. Not supported by all remotes.
|
||||
`,
|
||||
Run: func(command *cobra.Command, args []string) {
|
||||
cmd.CheckArgs(1, 1, command, args)
|
||||
fsrc := cmd.NewFsSrc(args)
|
||||
cmd.Run(true, false, command, func() error {
|
||||
return operations.About(fsrc)
|
||||
})
|
||||
},
|
||||
}
|
|
@ -4,6 +4,7 @@ package all
|
|||
import (
|
||||
// Active commands
|
||||
_ "github.com/ncw/rclone/cmd"
|
||||
_ "github.com/ncw/rclone/cmd/about"
|
||||
_ "github.com/ncw/rclone/cmd/authorize"
|
||||
_ "github.com/ncw/rclone/cmd/cachestats"
|
||||
_ "github.com/ncw/rclone/cmd/cat"
|
||||
|
|
|
@ -98,6 +98,7 @@ The main rclone commands with most used first
|
|||
* [rclone moveto](/commands/rclone_moveto/) - Move file or directory from source to dest.
|
||||
* [rclone obscure](/commands/rclone_obscure/) - Obscure password for use in the rclone.conf
|
||||
* [rclone cryptcheck](/commands/rclone_cryptcheck/) - Check the integrity of a crypted remote.
|
||||
* [rclone about](/commands/rclone_about/) - Get quota information from the remote.
|
||||
|
||||
See the [commands index](/commands/) for the full list.
|
||||
|
||||
|
|
|
@ -338,6 +338,14 @@ If you wish to empty your trash you can use the `rclone cleanup remote:`
|
|||
command which will permanently delete all your trashed files. This command
|
||||
does not take any path arguments.
|
||||
|
||||
### Quota information ###
|
||||
|
||||
To view your current quota you can use the `rclone about remote:`
|
||||
command which will display your usage limit (quota), the usage in Google
|
||||
Drive, the size of all files in the Trash and the space used by other
|
||||
Google services such as Gmail. This command does not take any path
|
||||
arguments.
|
||||
|
||||
### Specific options ###
|
||||
|
||||
Here are the command line options specific to this cloud storage
|
||||
|
|
|
@ -119,27 +119,27 @@ All the remotes support a basic set of features, but there are some
|
|||
optional features supported by some remotes used to make some
|
||||
operations more efficient.
|
||||
|
||||
| Name | Purge | Copy | Move | DirMove | CleanUp | ListR | StreamUpload | LinkSharing |
|
||||
| ---------------------------- |:-----:|:----:|:----:|:-------:|:-------:|:-----:|:------------:|:------------:|
|
||||
| Amazon Drive | Yes | No | Yes | Yes | No [#575](https://github.com/ncw/rclone/issues/575) | No | No | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Amazon S3 | No | Yes | No | No | No | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Backblaze B2 | No | No | No | No | Yes | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Box | Yes | Yes | Yes | Yes | No [#575](https://github.com/ncw/rclone/issues/575) | No | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Dropbox | Yes | Yes | Yes | Yes | No [#575](https://github.com/ncw/rclone/issues/575) | No | Yes | Yes |
|
||||
| FTP | No | No | Yes | Yes | No | No | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Google Cloud Storage | Yes | Yes | No | No | No | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Google Drive | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes |
|
||||
| HTTP | No | No | No | No | No | No | No | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Hubic | Yes † | Yes | No | No | No | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Microsoft Azure Blob Storage | Yes | Yes | No | No | No | Yes | No | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Microsoft OneDrive | Yes | Yes | Yes | No [#197](https://github.com/ncw/rclone/issues/197) | No [#575](https://github.com/ncw/rclone/issues/575) | No | No | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Openstack Swift | Yes † | Yes | No | No | No | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| pCloud | Yes | Yes | Yes | Yes | Yes | No | No | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| QingStor | No | Yes | No | No | No | Yes | No | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| SFTP | No | No | Yes | Yes | No | No | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| WebDAV | Yes | Yes | Yes | Yes | No | No | Yes ‡ | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| Yandex Disk | Yes | No | No | No | Yes | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) |
|
||||
| The local filesystem | Yes | No | Yes | Yes | No | No | Yes | No |
|
||||
| Name | Purge | Copy | Move | DirMove | CleanUp | ListR | StreamUpload | LinkSharing | About |
|
||||
| ---------------------------- |:-----:|:----:|:----:|:-------:|:-------:|:-----:|:------------:|:------------:|:-----:|
|
||||
| Amazon Drive | Yes | No | Yes | Yes | No [#575](https://github.com/ncw/rclone/issues/575) | No | No | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Amazon S3 | No | Yes | No | No | No | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Backblaze B2 | No | No | No | No | Yes | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Box | Yes | Yes | Yes | Yes | No [#575](https://github.com/ncw/rclone/issues/575) | No | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Dropbox | Yes | Yes | Yes | Yes | No [#575](https://github.com/ncw/rclone/issues/575) | No | Yes | Yes | No |
|
||||
| FTP | No | No | Yes | Yes | No | No | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Google Cloud Storage | Yes | Yes | No | No | No | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Google Drive | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes | Yes |
|
||||
| HTTP | No | No | No | No | No | No | No | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Hubic | Yes † | Yes | No | No | No | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Microsoft Azure Blob Storage | Yes | Yes | No | No | No | Yes | No | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Microsoft OneDrive | Yes | Yes | Yes | No [#197](https://github.com/ncw/rclone/issues/197) | No [#575](https://github.com/ncw/rclone/issues/575) | No | No | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Openstack Swift | Yes † | Yes | No | No | No | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| pCloud | Yes | Yes | Yes | Yes | Yes | No | No | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| QingStor | No | Yes | No | No | No | Yes | No | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| SFTP | No | No | Yes | Yes | No | No | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| WebDAV | Yes | Yes | Yes | Yes | No | No | Yes ‡ | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| Yandex Disk | Yes | No | No | No | Yes | Yes | Yes | No [#2178](https://github.com/ncw/rclone/issues/2178) | No |
|
||||
| The local filesystem | Yes | No | Yes | Yes | No | No | Yes | No | No |
|
||||
|
||||
### Purge ###
|
||||
|
||||
|
@ -202,3 +202,11 @@ file to local disk first, e.g. `rclone rcat`.
|
|||
Sets the necessary permissions on a file or folder and prints a link
|
||||
that allows others to access them, even if they don't have an account
|
||||
on the particular cloud provider.
|
||||
|
||||
### About ###
|
||||
|
||||
This is used to fetch quota information from the remote, like bytes
|
||||
used/free/quota and bytes used in the trash.
|
||||
|
||||
If the server can't do `About` then `rclone about` will return an
|
||||
error.
|
||||
|
|
15
fs/fs.go
15
fs/fs.go
|
@ -377,6 +377,9 @@ type Features struct {
|
|||
// Don't implement this unless you have a more efficient way
|
||||
// of listing recursively that doing a directory traversal.
|
||||
ListR ListRFn
|
||||
|
||||
// Get quota information from the Fs
|
||||
About func() error
|
||||
}
|
||||
|
||||
// Disable nil's out the named feature. If it isn't found then it
|
||||
|
@ -466,6 +469,9 @@ func (ft *Features) Fill(f Fs) *Features {
|
|||
if do, ok := f.(ListRer); ok {
|
||||
ft.ListR = do.ListR
|
||||
}
|
||||
if do, ok := f.(Abouter); ok {
|
||||
ft.About = do.About
|
||||
}
|
||||
return ft.DisableList(Config.DisableFeatures)
|
||||
}
|
||||
|
||||
|
@ -519,6 +525,9 @@ func (ft *Features) Mask(f Fs) *Features {
|
|||
if mask.ListR == nil {
|
||||
ft.ListR = nil
|
||||
}
|
||||
if mask.About == nil {
|
||||
ft.About = nil
|
||||
}
|
||||
return ft.DisableList(Config.DisableFeatures)
|
||||
}
|
||||
|
||||
|
@ -706,6 +715,12 @@ type RangeSeeker interface {
|
|||
RangeSeek(offset int64, whence int, length int64) (int64, error)
|
||||
}
|
||||
|
||||
// Abouter is an optional interface for Fs
|
||||
type Abouter interface {
|
||||
// About gets quota information from the Fs
|
||||
About() error
|
||||
}
|
||||
|
||||
// ObjectsChan is a channel of Objects
|
||||
type ObjectsChan chan Object
|
||||
|
||||
|
|
|
@ -1049,6 +1049,19 @@ func CleanUp(f fs.Fs) error {
|
|||
return doCleanUp()
|
||||
}
|
||||
|
||||
// About gets quota information from the remote
|
||||
func About(f fs.Fs) error {
|
||||
doAbout := f.Features().About
|
||||
if doAbout == nil {
|
||||
return errors.Errorf("%v doesn't support about", f)
|
||||
}
|
||||
if fs.Config.DryRun {
|
||||
fs.Logf(f, "Not running about as --dry-run set")
|
||||
return nil
|
||||
}
|
||||
return doAbout()
|
||||
}
|
||||
|
||||
// wrap a Reader and a Closer together into a ReadCloser
|
||||
type readCloser struct {
|
||||
io.Reader
|
||||
|
|
Loading…
Reference in a new issue