diff --git a/utils/utils.go b/utils/utils.go index c3f9e571d3..b92b30633c 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -70,7 +70,7 @@ type progressReader struct { readProgress int // How much has been read so far (bytes) lastUpdate int // How many bytes read at least update template string // Template to print. Default "%v/%v (%v)" - sf *StreamFormatter + sf *StreamFormatter } func (r *progressReader) Read(p []byte) (n int, err error) { @@ -86,7 +86,7 @@ func (r *progressReader) Read(p []byte) (n int, err error) { } if r.readProgress-r.lastUpdate > updateEvery || err != nil { if r.readTotal > 0 { - fmt.Fprintf(r.output, r.template, r.readProgress, r.readTotal, fmt.Sprintf("%.0f%%", float64(r.readProgress)/float64(r.readTotal)*100)) + fmt.Fprintf(r.output, r.template, HumanSize(r.readProgress), HumanSize(r.readTotal), fmt.Sprintf("%.0f%%", float64(r.readProgress)/float64(r.readTotal)*100)) } else { fmt.Fprintf(r.output, r.template, r.readProgress, "?", "n/a") } @@ -103,13 +103,25 @@ func (r *progressReader) Close() error { return io.ReadCloser(r.reader).Close() } func ProgressReader(r io.ReadCloser, size int, output io.Writer, template []byte, sf *StreamFormatter) *progressReader { - tpl := string(template) + tpl := string(template) if tpl == "" { tpl = string(sf.FormatProgress("", "%v/%v (%v)")) } return &progressReader{r, NewWriteFlusher(output), size, 0, 0, tpl, sf} } +func HumanSize(origSize int) string { + size := float64(origSize) + for _, unit := range []string{"b", "Kb", "Mb", "Gb", "Tb"} { + if int(size)/1024 == 0 { + return fmt.Sprintf("%.03f%s", size, unit) + } else { + size = size / 1024 + } + } + return strconv.Itoa(origSize) +} + // HumanDuration returns a human-readable approximation of a duration // (eg. "About a minute", "4 hours ago", etc.) func HumanDuration(d time.Duration) string { @@ -585,7 +597,7 @@ func (sf *StreamFormatter) FormatStatus(format string, a ...interface{}) []byte sf.used = true str := fmt.Sprintf(format, a...) if sf.json { - b, err := json.Marshal(&JSONMessage{Status:str}); + b, err := json.Marshal(&JSONMessage{Status: str}) if err != nil { return sf.FormatError(err) } @@ -597,7 +609,7 @@ func (sf *StreamFormatter) FormatStatus(format string, a ...interface{}) []byte func (sf *StreamFormatter) FormatError(err error) []byte { sf.used = true if sf.json { - if b, err := json.Marshal(&JSONMessage{Error:err.Error()}); err == nil { + if b, err := json.Marshal(&JSONMessage{Error: err.Error()}); err == nil { return b } return []byte("{\"error\":\"format error\"}") @@ -608,10 +620,10 @@ func (sf *StreamFormatter) FormatError(err error) []byte { func (sf *StreamFormatter) FormatProgress(action, str string) []byte { sf.used = true if sf.json { - b, err := json.Marshal(&JSONMessage{Status: action, Progress:str}) + b, err := json.Marshal(&JSONMessage{Status: action, Progress: str}) if err != nil { - return nil - } + return nil + } return b } return []byte(action + " " + str + "\r")