-
Notifications
You must be signed in to change notification settings - Fork 0
/
progress_tracker.go
76 lines (64 loc) · 1.6 KB
/
progress_tracker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package main
import (
"github.com/cheggaaa/pb"
"github.com/dhillondeep/go-getrelease"
"io"
"path/filepath"
"sync"
)
// defaultProgressBar is the default instance of a cheggaaa
// progress bar.
var defaultProgressBar getrelease.ProgressTracker = &ProgressBar{}
// ProgressBar wraps a github.com/cheggaaa/pb.Pool
// in order to display download progress for one or multiple
// downloads.
//
// If two different instance of ProgressBar try to
// display a progress only one will be displayed.
// It is therefore recommended to use DefaultProgressBar
type ProgressBar struct {
// lock everything below
lock sync.Mutex
pool *pb.Pool
pbs int
}
func ProgressBarConfig(bar *pb.ProgressBar, prefix string) {
bar.SetUnits(pb.U_BYTES)
bar.Prefix(prefix)
}
// TrackProgress instantiates a new progress bar that will
// display the progress of stream until closed.
// total can be 0.
func (cpb *ProgressBar) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) io.ReadCloser {
cpb.lock.Lock()
defer cpb.lock.Unlock()
newPb := pb.New64(totalSize)
newPb.Set64(currentSize)
ProgressBarConfig(newPb, filepath.Base(src))
if cpb.pool == nil {
cpb.pool = pb.NewPool()
cpb.pool.Start()
}
cpb.pool.Add(newPb)
reader := newPb.NewProxyReader(stream)
cpb.pbs++
return &readCloser{
Reader: reader,
close: func() error {
cpb.lock.Lock()
defer cpb.lock.Unlock()
newPb.Finish()
cpb.pbs--
if cpb.pbs <= 0 {
cpb.pool.Stop()
cpb.pool = nil
}
return nil
},
}
}
type readCloser struct {
io.Reader
close func() error
}
func (c *readCloser) Close() error { return c.close() }