eta decor with producer func
Vladimir Bauer
6 years ago
| 46 | 46 | wc.Init() |
| 47 | 47 | d := &movingAverageETA{ |
| 48 | 48 | WC: wc, |
| 49 | style: style, | |
| 50 | 49 | average: average, |
| 51 | 50 | normalizer: normalizer, |
| 51 | producer: chooseProducer(style), | |
| 52 | 52 | } |
| 53 | 53 | return d |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | 56 | type movingAverageETA struct { |
| 57 | 57 | WC |
| 58 | style TimeStyle | |
| 59 | 58 | average ewma.MovingAverage |
| 59 | normalizer TimeNormalizer | |
| 60 | producer func(time.Duration) string | |
| 60 | 61 | completeMsg *string |
| 61 | normalizer TimeNormalizer | |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | func (d *movingAverageETA) Decor(st *Statistics) string { |
| 66 | 66 | return d.FormatMsg(*d.completeMsg) |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | v := math.Round(d.average.Value()) | |
| 70 | remaining := time.Duration((st.Total - st.Current) * int64(v)) | |
| 69 | v := d.average.Value() | |
| 70 | remaining := time.Duration((st.Total - st.Current) * int64(math.Round(v))) | |
| 71 | 71 | if d.normalizer != nil { |
| 72 | 72 | remaining = d.normalizer.Normalize(remaining) |
| 73 | 73 | } |
| 74 | hours := int64((remaining / time.Hour) % 60) | |
| 75 | minutes := int64((remaining / time.Minute) % 60) | |
| 76 | seconds := int64((remaining / time.Second) % 60) | |
| 77 | ||
| 78 | var str string | |
| 79 | switch d.style { | |
| 80 | case ET_STYLE_GO: | |
| 81 | str = fmt.Sprint(time.Duration(remaining.Seconds()) * time.Second) | |
| 82 | case ET_STYLE_HHMMSS: | |
| 83 | str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) | |
| 84 | case ET_STYLE_HHMM: | |
| 85 | str = fmt.Sprintf("%02d:%02d", hours, minutes) | |
| 86 | case ET_STYLE_MMSS: | |
| 87 | if hours > 0 { | |
| 88 | str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) | |
| 89 | } else { | |
| 90 | str = fmt.Sprintf("%02d:%02d", minutes, seconds) | |
| 91 | } | |
| 92 | } | |
| 93 | ||
| 94 | return d.FormatMsg(str) | |
| 74 | return d.FormatMsg(d.producer(remaining)) | |
| 95 | 75 | } |
| 96 | 76 | |
| 97 | 77 | func (d *movingAverageETA) NextAmount(n int64, wdd ...time.Duration) { |
| 134 | 114 | wc.Init() |
| 135 | 115 | d := &averageETA{ |
| 136 | 116 | WC: wc, |
| 137 | style: style, | |
| 138 | 117 | startTime: startTime, |
| 118 | producer: chooseProducer(style), | |
| 139 | 119 | } |
| 140 | 120 | return d |
| 141 | 121 | } |
| 142 | 122 | |
| 143 | 123 | type averageETA struct { |
| 144 | 124 | WC |
| 145 | style TimeStyle | |
| 146 | 125 | startTime time.Time |
| 126 | producer func(time.Duration) string | |
| 147 | 127 | completeMsg *string |
| 148 | 128 | } |
| 149 | 129 | |
| 152 | 132 | return d.FormatMsg(*d.completeMsg) |
| 153 | 133 | } |
| 154 | 134 | |
| 155 | var str string | |
| 156 | 135 | timeElapsed := time.Since(d.startTime) |
| 157 | v := math.Round(float64(timeElapsed) / float64(st.Current)) | |
| 136 | v := float64(timeElapsed) / float64(st.Current) | |
| 158 | 137 | if math.IsInf(v, 0) || math.IsNaN(v) { |
| 159 | 138 | v = 0 |
| 160 | 139 | } |
| 161 | remaining := time.Duration((st.Total - st.Current) * int64(v)) | |
| 162 | hours := int64((remaining / time.Hour) % 60) | |
| 163 | minutes := int64((remaining / time.Minute) % 60) | |
| 164 | seconds := int64((remaining / time.Second) % 60) | |
| 165 | ||
| 166 | switch d.style { | |
| 167 | case ET_STYLE_GO: | |
| 168 | str = fmt.Sprint(time.Duration(remaining.Seconds()) * time.Second) | |
| 169 | case ET_STYLE_HHMMSS: | |
| 170 | str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) | |
| 171 | case ET_STYLE_HHMM: | |
| 172 | str = fmt.Sprintf("%02d:%02d", hours, minutes) | |
| 173 | case ET_STYLE_MMSS: | |
| 174 | if hours > 0 { | |
| 175 | str = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) | |
| 176 | } else { | |
| 177 | str = fmt.Sprintf("%02d:%02d", minutes, seconds) | |
| 178 | } | |
| 179 | } | |
| 180 | ||
| 181 | return d.FormatMsg(str) | |
| 140 | remaining := time.Duration((st.Total - st.Current) * int64(math.Round(v))) | |
| 141 | return d.FormatMsg(d.producer(remaining)) | |
| 182 | 142 | } |
| 183 | 143 | |
| 184 | 144 | func (d *averageETA) OnCompleteMessage(msg string) { |
| 224 | 184 | return remaining |
| 225 | 185 | }) |
| 226 | 186 | } |
| 187 | ||
| 188 | func chooseProducer(style TimeStyle) func(time.Duration) string { | |
| 189 | switch style { | |
| 190 | case ET_STYLE_HHMMSS: | |
| 191 | return func(remaining time.Duration) string { | |
| 192 | hours := int64(remaining/time.Hour) % 60 | |
| 193 | minutes := int64(remaining/time.Minute) % 60 | |
| 194 | seconds := int64(remaining/time.Second) % 60 | |
| 195 | return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) | |
| 196 | } | |
| 197 | case ET_STYLE_HHMM: | |
| 198 | return func(remaining time.Duration) string { | |
| 199 | hours := int64(remaining/time.Hour) % 60 | |
| 200 | minutes := int64(remaining/time.Minute) % 60 | |
| 201 | return fmt.Sprintf("%02d:%02d", hours, minutes) | |
| 202 | } | |
| 203 | case ET_STYLE_MMSS: | |
| 204 | return func(remaining time.Duration) string { | |
| 205 | hours := int64(remaining/time.Hour) % 60 | |
| 206 | minutes := int64(remaining/time.Minute) % 60 | |
| 207 | seconds := int64(remaining/time.Second) % 60 | |
| 208 | if hours > 0 { | |
| 209 | return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) | |
| 210 | } | |
| 211 | return fmt.Sprintf("%02d:%02d", minutes, seconds) | |
| 212 | } | |
| 213 | default: | |
| 214 | return func(remaining time.Duration) string { | |
| 215 | // strip off nanoseconds | |
| 216 | return ((remaining / time.Second) * time.Second).String() | |
| 217 | } | |
| 218 | } | |
| 219 | } | |