gopkg.in/cavaliercoder/grab.v2@v2.0.0/cmd/grab/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "time" 7 8 "github.com/cavaliercoder/grab" 9 ) 10 11 var ( 12 inProgress = 0 13 failed = 0 14 succeeded = 0 15 ) 16 17 func main() { 18 // validate command args 19 if len(os.Args) < 2 { 20 fmt.Fprintf(os.Stderr, "usage: %s [url]...\n", os.Args[0]) 21 os.Exit(1) 22 } 23 urls := os.Args[1:] 24 25 // start file downloads, 3 at a time 26 fmt.Printf("Downloading %d files...\n", len(urls)) 27 respch, err := grab.GetBatch(3, ".", urls...) 28 if err != nil { 29 fmt.Fprintf(os.Stderr, "%v\n", err) 30 os.Exit(1) 31 } 32 33 // monitor downloads 34 responses := make([]*grab.Response, 0, len(urls)) 35 t := time.NewTicker(200 * time.Millisecond) 36 defer t.Stop() 37 38 Loop: 39 for { 40 select { 41 case resp := <-respch: 42 if resp != nil { 43 // a new response has been received and has started downloading 44 responses = append(responses, resp) 45 } else { 46 // channel is closed - all downloads are complete 47 updateUI(responses) 48 break Loop 49 } 50 51 case <-t.C: 52 // update UI every 200ms 53 updateUI(responses) 54 } 55 } 56 57 fmt.Printf( 58 "Finished %d successful, %d failed, %d incomplete.\n", 59 succeeded, 60 failed, 61 inProgress) 62 63 // return the number of failed downloads as exit code 64 os.Exit(failed) 65 } 66 67 // updateUI prints the progress of all downloads to the terminal 68 func updateUI(responses []*grab.Response) { 69 // clear lines for incomplete downloads 70 if inProgress > 0 { 71 fmt.Printf("\033[%dA\033[K", inProgress) 72 } 73 74 // print newly completed downloads 75 for i, resp := range responses { 76 if resp != nil && resp.IsComplete() { 77 if resp.Err() != nil { 78 failed++ 79 fmt.Fprintf(os.Stderr, "Error downloading %s: %v\n", 80 resp.Request.URL(), 81 resp.Err()) 82 } else { 83 succeeded++ 84 fmt.Printf("Finished %s %d / %d bytes (%d%%)\n", 85 resp.Filename, 86 resp.BytesComplete(), 87 resp.Size, 88 int(100*resp.Progress())) 89 } 90 responses[i] = nil 91 } 92 } 93 94 // print progress for incomplete downloads 95 inProgress = 0 96 for _, resp := range responses { 97 if resp != nil { 98 fmt.Printf("Downloading %s %d / %d bytes (%d%%) - %.02fKBp/s ETA: %ds \033[K\n", 99 resp.Filename, 100 resp.BytesComplete(), 101 resp.Size, 102 int(100*resp.Progress()), 103 resp.BytesPerSecond()/1024, 104 int64(resp.ETA().Sub(time.Now()).Seconds())) 105 inProgress++ 106 } 107 } 108 }