]> Sergey Matveev's repositories - sgodup.git/blobdiff - progress.go
Initial version
[sgodup.git] / progress.go
diff --git a/progress.go b/progress.go
new file mode 100644 (file)
index 0000000..863b37a
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+sgodup -- File deduplication utility
+Copyright (C) 2020 Sergey Matveev <stargrave@stargrave.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 3 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package main
+
+import (
+       "fmt"
+       "os"
+       "time"
+
+       "github.com/dustin/go-humanize"
+)
+
+const (
+       ESC = 27
+)
+
+var LineClear = fmt.Sprintf("%c[%dA%c[2K", ESC, 2, ESC)
+
+type Progress struct {
+       fullFiles   int64
+       fullSize    uint64
+       fullFilesS  string
+       fullSizeS   string
+       suffixFiles string
+       suffixSize  string
+       stop        chan struct{}
+}
+
+func NewProgress(
+       fullFiles int,
+       fullSize int64,
+       files *int,
+       size *int64,
+       suffixFiles, suffixSize string,
+) Progress {
+       p := Progress{
+               int64(fullFiles),
+               uint64(fullSize),
+               humanize.Comma(int64(fullFiles)),
+               humanize.IBytes(uint64(fullSize)),
+               suffixFiles,
+               suffixSize,
+               make(chan struct{}, 0),
+       }
+       go p.Run(files, size)
+       return p
+}
+
+func (p Progress) Log(prefix string, files int64, size uint64) {
+       percentageFiles := int64(0)
+       if p.fullFiles > 0 {
+               percentageFiles = 100 * files / p.fullFiles
+       }
+       percentageSize := uint64(0)
+       if p.fullSize > 0 {
+               percentageSize = 100 * size / p.fullSize
+       }
+       now := time.Now().Format("2006/01/02 15:04:05")
+       fmt.Fprintf(
+               os.Stderr,
+               "%s%s %s / %s (%d%%) files%s\n%s %s / %s (%d%%)%s\n",
+               prefix,
+               now, humanize.Comma(files), p.fullFilesS, percentageFiles, p.suffixFiles,
+               now, humanize.IBytes(size), p.fullSizeS, percentageSize, p.suffixSize,
+       )
+}
+
+func (p Progress) Run(files *int, size *int64) {
+       p.Log("", 0, 0)
+       ticker := time.NewTicker(250 * time.Millisecond)
+       for {
+               select {
+               case <-ticker.C:
+                       p.Log(LineClear, int64(*files), uint64(*size))
+               case <-p.stop:
+                       ticker.Stop()
+                       p.Log(LineClear, int64(*files), uint64(*size))
+                       close(p.stop)
+                       return
+               }
+       }
+}
+
+func (p Progress) Stop() {
+       p.stop <- struct{}{}
+       <-p.stop
+}