github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/net/progress_reader.go (about) 1 package net 2 3 import ( 4 "io" 5 "os" 6 "time" 7 8 "github.com/cloudfoundry/cli/cf/formatters" 9 "github.com/cloudfoundry/cli/cf/terminal" 10 ) 11 12 type ProgressReader struct { 13 ioReadSeeker io.ReadSeeker 14 bytesRead int64 15 total int64 16 quit chan bool 17 ui terminal.UI 18 outputInterval time.Duration 19 } 20 21 func NewProgressReader(readSeeker io.ReadSeeker, ui terminal.UI, outputInterval time.Duration) *ProgressReader { 22 return &ProgressReader{ 23 ioReadSeeker: readSeeker, 24 ui: ui, 25 outputInterval: outputInterval, 26 } 27 } 28 29 func (progressReader *ProgressReader) Read(p []byte) (int, error) { 30 if progressReader.ioReadSeeker == nil { 31 return 0, os.ErrInvalid 32 } 33 34 n, err := progressReader.ioReadSeeker.Read(p) 35 36 if progressReader.total > int64(0) { 37 if n > 0 { 38 if progressReader.quit == nil { 39 progressReader.quit = make(chan bool) 40 go progressReader.printProgress(progressReader.quit) 41 } 42 43 progressReader.bytesRead += int64(n) 44 45 if progressReader.total == progressReader.bytesRead { 46 progressReader.quit <- true 47 return n, err 48 } 49 } 50 } 51 52 return n, err 53 } 54 55 func (progressReader *ProgressReader) Seek(offset int64, whence int) (int64, error) { 56 return progressReader.ioReadSeeker.Seek(offset, whence) 57 } 58 59 func (progressReader *ProgressReader) printProgress(quit chan bool) { 60 timer := time.NewTicker(progressReader.outputInterval) 61 62 for { 63 select { 64 case <-quit: 65 //The spaces are there to ensure we overwrite the entire line 66 //before using the terminal printer to output Done Uploading 67 progressReader.ui.PrintCapturingNoOutput("\r ") 68 progressReader.ui.Say("\rDone uploading") 69 return 70 case <-timer.C: 71 progressReader.ui.PrintCapturingNoOutput("\r%s uploaded...", formatters.ByteSize(progressReader.bytesRead)) 72 } 73 } 74 } 75 76 func (progressReader *ProgressReader) SetTotalSize(size int64) { 77 progressReader.total = size 78 }