forked from jedib0t/go-pretty
-
Notifications
You must be signed in to change notification settings - Fork 0
/
demo.go
173 lines (155 loc) · 5.71 KB
/
demo.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package main
import (
"flag"
"fmt"
"math/rand"
"time"
"github.com/SilverChard/go-pretty/v6/progress"
"github.com/SilverChard/go-pretty/v6/text"
)
var (
flagAutoStop = flag.Bool("auto-stop", false, "Auto-stop rendering?")
flagHideETA = flag.Bool("hide-eta", false, "Hide the ETA?")
flagHideETAOverall = flag.Bool("hide-eta-overall", false, "Hide the ETA in the overall tracker?")
flagHideOverallTracker = flag.Bool("hide-overall", false, "Hide the Overall Tracker?")
flagHidePercentage = flag.Bool("hide-percentage", false, "Hide the progress percent?")
flagHideTime = flag.Bool("hide-time", false, "Hide the time taken?")
flagHideValue = flag.Bool("hide-value", false, "Hide the tracker value?")
flagNumTrackers = flag.Int("num-trackers", 13, "Number of Trackers")
flagShowSpeed = flag.Bool("show-speed", false, "Show the tracker speed?")
flagShowSpeedOverall = flag.Bool("show-speed-overall", false, "Show the overall tracker speed?")
flagShowPinned = flag.Bool("show-pinned", false, "Show a pinned message?")
flagRandomFail = flag.Bool("rnd-fail", false, "Introduce random failures in tracking")
flagRandomLogs = flag.Bool("rnd-logs", false, "Output random logs in the middle of tracking")
messageColors = []text.Color{
text.FgRed,
text.FgGreen,
text.FgYellow,
text.FgBlue,
text.FgMagenta,
text.FgCyan,
text.FgWhite,
}
timeStart = time.Now()
)
func getMessage(idx int64, units *progress.Units) string {
var message string
switch units {
case &progress.UnitsBytes:
message = fmt.Sprintf("Downloading File #%3d", idx)
case &progress.UnitsCurrencyDollar, &progress.UnitsCurrencyEuro, &progress.UnitsCurrencyPound:
message = fmt.Sprintf("Transferring Amount #%3d", idx)
default:
message = fmt.Sprintf("Calculating Total #%3d", idx)
}
return message
}
func getUnits(idx int64) *progress.Units {
var units *progress.Units
switch {
case idx%5 == 0:
units = &progress.UnitsCurrencyPound
case idx%4 == 0:
units = &progress.UnitsCurrencyDollar
case idx%3 == 0:
units = &progress.UnitsBytes
default:
units = &progress.UnitsDefault
}
return units
}
func trackSomething(pw progress.Writer, idx int64, updateMessage bool) {
total := idx * idx * idx * 250
incrementPerCycle := idx * int64(*flagNumTrackers) * 250
units := getUnits(idx)
message := getMessage(idx, units)
tracker := progress.Tracker{Message: message, Total: total, Units: *units}
if idx == int64(*flagNumTrackers) {
tracker.Total = 0
}
pw.AppendTracker(&tracker)
ticker := time.Tick(time.Millisecond * 500)
updateTicker := time.Tick(time.Millisecond * 250)
for !tracker.IsDone() {
select {
case <-ticker:
tracker.Increment(incrementPerCycle)
if idx == int64(*flagNumTrackers) && tracker.Value() >= total {
tracker.MarkAsDone()
} else if *flagRandomFail && rand.Float64() < 0.1 {
tracker.MarkAsErrored()
}
pw.SetPinnedMessages(
fmt.Sprintf(">> Current Time: %-32s", time.Now().Format(time.RFC3339)),
fmt.Sprintf(">> Total Time: %-32s", time.Now().Sub(timeStart).Round(time.Millisecond)),
)
case <-updateTicker:
if updateMessage {
rndIdx := rand.Intn(len(messageColors))
if rndIdx == len(messageColors) {
rndIdx--
}
tracker.UpdateMessage(messageColors[rndIdx].Sprint(message))
}
}
}
}
func main() {
flag.Parse()
fmt.Printf("Tracking Progress of %d trackers ...\n\n", *flagNumTrackers)
// instantiate a Progress Writer and set up the options
pw := progress.NewWriter()
pw.SetAutoStop(*flagAutoStop)
pw.SetTrackerLength(25)
pw.SetMessageWidth(24)
pw.SetNumTrackersExpected(*flagNumTrackers)
pw.SetSortBy(progress.SortByPercentDsc)
pw.SetStyle(progress.StyleDefault)
pw.SetTrackerPosition(progress.PositionRight)
pw.SetUpdateFrequency(time.Millisecond * 100)
pw.Style().Colors = progress.StyleColorsExample
pw.Style().Options.PercentFormat = "%4.1f%%"
pw.Style().Visibility.ETA = !*flagHideETA
pw.Style().Visibility.ETAOverall = !*flagHideETAOverall
pw.Style().Visibility.Percentage = !*flagHidePercentage
pw.Style().Visibility.Speed = *flagShowSpeed
pw.Style().Visibility.SpeedOverall = *flagShowSpeedOverall
pw.Style().Visibility.Time = !*flagHideTime
pw.Style().Visibility.TrackerOverall = !*flagHideOverallTracker
pw.Style().Visibility.Value = !*flagHideValue
pw.Style().Visibility.Pinned = *flagShowPinned
// call Render() in async mode; yes we don't have any trackers at the moment
go pw.Render()
// add a bunch of trackers with random parameters to demo most of the
// features available; do this in async too like a client might do (for ex.
// when downloading a bunch of files in parallel)
for idx := int64(1); idx <= int64(*flagNumTrackers); idx++ {
go trackSomething(pw, idx, idx == int64(*flagNumTrackers))
// in auto-stop mode, the Render logic terminates the moment it detects
// zero active trackers; but in a manual-stop mode, it keeps waiting and
// is a good chance to demo trackers being added dynamically while other
// trackers are active or done
if !*flagAutoStop {
time.Sleep(time.Millisecond * 100)
}
}
// wait for one or more trackers to become active (just blind-wait for a
// second) and then keep watching until Rendering is in progress
time.Sleep(time.Second)
messagesLogged := make(map[string]bool)
for pw.IsRenderInProgress() {
if *flagRandomLogs && pw.LengthDone()%3 == 0 {
logMsg := text.Faint.Sprintf("[INFO] done with %d trackers", pw.LengthDone())
if !messagesLogged[logMsg] {
pw.Log(logMsg)
messagesLogged[logMsg] = true
}
}
// for manual-stop mode, stop when there are no more active trackers
if !*flagAutoStop && pw.LengthActive() == 0 {
pw.Stop()
}
time.Sleep(time.Millisecond * 100)
}
fmt.Println("\nAll done!")
}