mirror of
https://github.com/runbear-io/beardrive.git
synced 2026-08-25 08:08:08 +02:00
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
package main
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"os"
|
||
|
|
"strings"
|
||
|
|
"sync"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"github.com/mattn/go-isatty"
|
||
|
|
|
||
|
|
"github.com/runbear-io/beardrive/internal/syncer"
|
||
|
|
)
|
||
|
|
|
||
|
|
// progressReporter returns a syncer.OnProgress callback that shows upload
|
||
|
|
// progress: an in-place bar on a TTY, periodic percentage lines otherwise.
|
||
|
|
// It's safe to call concurrently from upload workers, and renders are
|
||
|
|
// throttled so many small blobs don't thrash the terminal. It stays silent
|
||
|
|
// when there's nothing to upload.
|
||
|
|
func progressReporter() func(syncer.Progress) {
|
||
|
|
tty := isatty.IsTerminal(os.Stderr.Fd())
|
||
|
|
var mu sync.Mutex
|
||
|
|
var lastDraw time.Time
|
||
|
|
lastPct := -1
|
||
|
|
return func(p syncer.Progress) {
|
||
|
|
if p.Total == 0 {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
mu.Lock()
|
||
|
|
defer mu.Unlock()
|
||
|
|
final := p.Done >= p.Total
|
||
|
|
pct := p.Done * 100 / p.Total
|
||
|
|
if tty {
|
||
|
|
if !final && time.Since(lastDraw) < 100*time.Millisecond {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
lastDraw = time.Now()
|
||
|
|
const w = 24
|
||
|
|
filled := pct * w / 100
|
||
|
|
bar := strings.Repeat("█", filled) + strings.Repeat("░", w-filled)
|
||
|
|
fmt.Fprintf(os.Stderr, "\r uploading [%s] %3d%% %d/%d files %s / %s",
|
||
|
|
bar, pct, p.Done, p.Total, humanBytes(p.Bytes), humanBytes(p.ToBytes))
|
||
|
|
if final {
|
||
|
|
fmt.Fprintln(os.Stderr)
|
||
|
|
}
|
||
|
|
return
|
||
|
|
}
|
||
|
|
// Non-TTY: announce the total once, then a line every ~10% and at the end.
|
||
|
|
if lastPct < 0 {
|
||
|
|
fmt.Fprintf(os.Stderr, " uploading %d files (%s)\n", p.Total, humanBytes(p.ToBytes))
|
||
|
|
}
|
||
|
|
if final || pct/10 > lastPct/10 {
|
||
|
|
fmt.Fprintf(os.Stderr, " %d%% %d/%d files %s / %s\n",
|
||
|
|
pct, p.Done, p.Total, humanBytes(p.Bytes), humanBytes(p.ToBytes))
|
||
|
|
}
|
||
|
|
lastPct = pct
|
||
|
|
}
|
||
|
|
}
|