diff --git a/fs/operations.go b/fs/operations.go index 8019c4f11..5ad170208 100644 --- a/fs/operations.go +++ b/fs/operations.go @@ -159,7 +159,7 @@ func checkOne(pair ObjectPair, out ObjectPairChan) { out <- pair } -// Read FsObjects~s on in send to out if they need uploading +// Read Objects~s on in send to out if they need uploading // // FIXME potentially doing lots of MD5SUMS at once func PairChecker(in ObjectPairChan, out ObjectPairChan, wg *sync.WaitGroup) { @@ -172,7 +172,7 @@ func PairChecker(in ObjectPairChan, out ObjectPairChan, wg *sync.WaitGroup) { } } -// Read FsObjects on in and copy them +// Read Objects on in and copy them func Copier(in ObjectPairChan, fdst Fs, wg *sync.WaitGroup) { defer wg.Done() for pair := range in { @@ -376,10 +376,10 @@ func Check(fdst, fsrc Fs) error { return nil } -// List the Fs to stdout +// List the Fs to the supplied function // // Lists in parallel which may get them out of order -func List(f Fs) error { +func ListFn(f Fs, fn func(Object)) error { in := f.List() var wg sync.WaitGroup wg.Add(Config.Checkers) @@ -387,10 +387,7 @@ func List(f Fs) error { go func() { defer wg.Done() for o := range in { - Stats.Checking(o) - modTime := o.ModTime() - Stats.DoneChecking(o) - fmt.Printf("%9d %19s %s\n", o.Size(), modTime.Format("2006-01-02 15:04:05.00000000"), o.Remote()) + fn(o) } }() } @@ -398,6 +395,49 @@ func List(f Fs) error { return nil } +// List the Fs to stdout +// +// Shows size and path +// +// Lists in parallel which may get them out of order +func List(f Fs) error { + return ListFn(f, func(o Object) { + fmt.Printf("%9d %s\n", o.Size(), o.Remote()) + }) +} + +// List the Fs to stdout +// +// Shows size, mod time and path +// +// Lists in parallel which may get them out of order +func ListLong(f Fs) error { + return ListFn(f, func(o Object) { + Stats.Checking(o) + modTime := o.ModTime() + Stats.DoneChecking(o) + fmt.Printf("%9d %19s %s\n", o.Size(), modTime.Format("2006-01-02 15:04:05.00000000"), o.Remote()) + }) +} + +// List the Fs to stdout +// +// Produces the same output as the md5sum command +// +// Lists in parallel which may get them out of order +func Md5sum(f Fs) error { + return ListFn(f, func(o Object) { + Stats.Checking(o) + md5sum, err := o.Md5sum() + Stats.DoneChecking(o) + if err != nil { + Debug(o, "Failed to read MD5: %v", err) + md5sum = "UNKNOWN" + } + fmt.Printf("%32s %s\n", md5sum, o.Remote()) + }) +} + // List the directories/buckets/containers in the Fs to stdout func ListDir(f Fs) error { for dir := range f.ListDir() { diff --git a/rclone.go b/rclone.go index 7ef6fbeb5..4f0f3bcfc 100644 --- a/rclone.go +++ b/rclone.go @@ -92,7 +92,7 @@ var Commands = []Command{ Name: "ls", ArgsHelp: "[remote://path]", Help: ` - List all the objects in the the path.`, + List all the objects in the the path with size and path.`, Run: func(fdst, fsrc fs.Fs) { err := fs.List(fdst) if err != nil { @@ -116,6 +116,34 @@ var Commands = []Command{ MinArgs: 1, MaxArgs: 1, }, + { + Name: "lsl", + ArgsHelp: "[remote://path]", + Help: ` + List all the objects in the the path with modification time, size and path.`, + Run: func(fdst, fsrc fs.Fs) { + err := fs.ListLong(fdst) + if err != nil { + log.Fatalf("Failed to list long: %v", err) + } + }, + MinArgs: 1, + MaxArgs: 1, + }, + { + Name: "md5sum", + ArgsHelp: "[remote://path]", + Help: ` + Produces an md5sum file for all the objects in the path.`, + Run: func(fdst, fsrc fs.Fs) { + err := fs.Md5sum(fdst) + if err != nil { + log.Fatalf("Failed to list: %v", err) + } + }, + MinArgs: 1, + MaxArgs: 1, + }, { Name: "mkdir", ArgsHelp: "remote://path",