2 NNCP -- Node to Node copy, utilities for store-and-forward data exchange
3 Copyright (C) 2016-2019 Sergey Matveev <stargrave@stargrave.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 "github.com/dustin/go-humanize"
29 "go.cypherpunks.ru/nncp/v5/uilive"
33 uilive.Out = os.Stderr
36 var progressBars = make(map[string]*ProgressBar)
37 var progressBarsLock sync.RWMutex
39 type ProgressBar struct {
47 func ProgressBarNew(initial, full int64) *ProgressBar {
58 func (pb ProgressBar) Render(what string, size int64) {
59 now := time.Now().UTC()
60 timeDiff := now.Sub(pb.started).Seconds()
64 percentage := int64(100)
66 percentage = 100 * size / pb.full
69 pb.w, "%s %s %s/%s %d%% (%s/sec)\n",
70 now.Format(time.RFC3339), what,
71 humanize.IBytes(uint64(size)),
72 humanize.IBytes(uint64(pb.full)),
74 humanize.IBytes(uint64(float64(size-pb.initial)/timeDiff)),
78 func (pb ProgressBar) Kill() {
87 ) (written int64, err error) {
88 buf := make([]byte, EncBlkSize)
92 nr, er = src.Read(buf)
94 nw, ew = dst.Write(buf[:nr])
107 err = io.ErrShortWrite
121 func Progress(sds SDS) {
122 pkt := sds["pkt"].(string)
124 if sizeI, exists := sds["size"]; exists {
127 fullsize := sds["fullsize"].(int64)
128 progressBarsLock.RLock()
129 pb, exists := progressBars[pkt]
130 progressBarsLock.RUnlock()
132 progressBarsLock.Lock()
133 pb = ProgressBarNew(size, fullsize)
134 progressBars[pkt] = pb
135 progressBarsLock.Unlock()
138 if len(what) >= 52 { // Base32 encoded
139 what = what[:16] + ".." + what[len(what)-16:]
141 if xx, exists := sds["xx"]; exists {
142 what = strings.Title(xx.(string)) + " " + what
144 pb.Render(what, size)
145 if size >= fullsize {
147 progressBarsLock.Lock()
148 delete(progressBars, pkt)
149 progressBarsLock.Unlock()