瀏覽代碼

Make the progressbar human readable

Guillaume J. Charmes 12 年之前
父節點
當前提交
1e0738f63f
共有 1 個文件被更改,包括 20 次插入8 次删除
  1. 20 8
      utils/utils.go

+ 20 - 8
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")