From 177dbbc29aab7092fbb98f2fd1b4e6be9120310a Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 2 Oct 2015 19:48:48 +0100 Subject: [PATCH] Implement rclone size for measuring remotes - fixes #153 --- docs/content/docs.md | 13 +++++++++---- fs/operations.go | 10 ++++++++++ fs/operations_test.go | 14 ++++++++++++++ rclone.go | 26 ++++++++++++++++++++++---- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/docs/content/docs.md b/docs/content/docs.md index ab94940d0..bacbf6a2b 100644 --- a/docs/content/docs.md +++ b/docs/content/docs.md @@ -58,24 +58,29 @@ modification time or MD5SUM. Destination is updated to match source, including deleting files if necessary. Since this can cause data loss, test first with the `--dry-run` flag. -### rclone ls [remote:path] ### +### rclone ls remote:path ### List all the objects in the the path with size and path. -### rclone lsd [remote:path] ### +### rclone lsd remote:path ### List all directories/containers/buckets in the the path. -### rclone lsl [remote:path] ### +### rclone lsl remote:path ### List all the objects in the the path with modification time, size and path. -### rclone md5sum [remote:path] ### +### rclone md5sum remote:path ### Produces an md5sum file for all the objects in the path. This is in the same format as the standard md5sum tool produces. +### rclone size remote:path ### + +Prints the total size of objects in remote:path and the number of +objects. + ### rclone mkdir remote:path ### Make the path if it doesn't already exist diff --git a/fs/operations.go b/fs/operations.go index cd5b49146..ffd1b1949 100644 --- a/fs/operations.go +++ b/fs/operations.go @@ -8,6 +8,7 @@ import ( "mime" "path" "sync" + "sync/atomic" "time" ) @@ -680,6 +681,15 @@ func Md5sum(f Fs, w io.Writer) error { }) } +// Count counts the objects and their sizes in the Fs +func Count(f Fs) (objects int64, size int64, err error) { + err = ListFn(f, func(o Object) { + atomic.AddInt64(&objects, 1) + atomic.AddInt64(&size, o.Size()) + }) + return +} + // ListDir lists the directories/buckets/containers in the Fs to the supplied writer func ListDir(f Fs, w io.Writer) error { for dir := range f.ListDir() { diff --git a/fs/operations_test.go b/fs/operations_test.go index 6ebb8409e..0f32c31cb 100644 --- a/fs/operations_test.go +++ b/fs/operations_test.go @@ -583,7 +583,21 @@ func TestMd5sum(t *testing.T) { } } +func TestCount(t *testing.T) { + objects, size, err := fs.Count(fremote) + if err != nil { + t.Fatalf("Count failed: %v", err) + } + if objects != 2 { + t.Errorf("want 2 objects got %d", objects) + } + if size != 60 { + t.Errorf("want size 60 got %d", size) + } +} + func TestCheck(t *testing.T) { + // FIXME } // Clean the temporary directory diff --git a/rclone.go b/rclone.go index 7debe3318..c241227f0 100644 --- a/rclone.go +++ b/rclone.go @@ -109,7 +109,7 @@ var Commands = []Command{ }, { Name: "ls", - ArgsHelp: "[remote:path]", + ArgsHelp: "remote:path", Help: ` List all the objects in the the path with size and path.`, Run: func(fdst, fsrc fs.Fs) error { @@ -120,7 +120,7 @@ var Commands = []Command{ }, { Name: "lsd", - ArgsHelp: "[remote:path]", + ArgsHelp: "remote:path", Help: ` List all directories/containers/buckets in the the path.`, Run: func(fdst, fsrc fs.Fs) error { @@ -131,7 +131,7 @@ var Commands = []Command{ }, { Name: "lsl", - ArgsHelp: "[remote:path]", + ArgsHelp: "remote:path", Help: ` List all the objects in the the path with modification time, size and path.`, @@ -143,7 +143,7 @@ var Commands = []Command{ }, { Name: "md5sum", - ArgsHelp: "[remote:path]", + ArgsHelp: "remote:path", Help: ` Produces an md5sum file for all the objects in the path. This is in the same format as the standard md5sum tool produces.`, @@ -153,6 +153,24 @@ var Commands = []Command{ MinArgs: 1, MaxArgs: 1, }, + { + Name: "size", + ArgsHelp: "remote:path", + Help: ` + Returns the total size of objects in remote:path and the number + of objects.`, + Run: func(fdst, fsrc fs.Fs) error { + objects, size, err := fs.Count(fdst) + if err != nil { + return err + } + fmt.Printf("Total objects: %d\n", objects) + fmt.Printf("Total size: %v (%d bytes)\n", fs.SizeSuffix(size), size) + return nil + }, + MinArgs: 1, + MaxArgs: 1, + }, { Name: "mkdir", ArgsHelp: "remote:path",