]> Sergey Matveev's repositories - sgodup.git/blob - progress.go
Raise copyright years
[sgodup.git] / progress.go
1 /*
2 sgodup -- File deduplication utility
3 Copyright (C) 2020-2023 Sergey Matveev <stargrave@stargrave.org>
4
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.
8
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.
13
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/>.
16 */
17
18 package main
19
20 import (
21         "fmt"
22         "os"
23         "time"
24
25         "github.com/dustin/go-humanize"
26 )
27
28 const (
29         ESC = 27
30 )
31
32 var LineClear = fmt.Sprintf("%c[%dA%c[2K", ESC, 2, ESC)
33
34 type Progress struct {
35         fullFiles   int64
36         fullSize    uint64
37         fullFilesS  string
38         fullSizeS   string
39         suffixFiles string
40         suffixSize  string
41         stop        chan struct{}
42 }
43
44 func NewProgress(
45         fullFiles int,
46         fullSize int64,
47         files *int,
48         size *int64,
49         suffixFiles, suffixSize string,
50 ) Progress {
51         p := Progress{
52                 int64(fullFiles),
53                 uint64(fullSize),
54                 humanize.Comma(int64(fullFiles)),
55                 humanize.IBytes(uint64(fullSize)),
56                 suffixFiles,
57                 suffixSize,
58                 make(chan struct{}, 0),
59         }
60         go p.Run(files, size)
61         return p
62 }
63
64 func (p Progress) Log(prefix string, files int64, size uint64) {
65         percentageFiles := int64(0)
66         if p.fullFiles > 0 {
67                 percentageFiles = 100 * files / p.fullFiles
68         }
69         percentageSize := uint64(0)
70         if p.fullSize > 0 {
71                 percentageSize = 100 * size / p.fullSize
72         }
73         now := time.Now().Format("2006/01/02 15:04:05")
74         fmt.Fprintf(
75                 os.Stderr,
76                 "%s%s %s / %s (%d%%) files%s\n%s %s / %s (%d%%)%s\n",
77                 prefix,
78                 now, humanize.Comma(files), p.fullFilesS, percentageFiles, p.suffixFiles,
79                 now, humanize.IBytes(size), p.fullSizeS, percentageSize, p.suffixSize,
80         )
81 }
82
83 func (p Progress) Run(files *int, size *int64) {
84         p.Log("", 0, 0)
85         ticker := time.NewTicker(250 * time.Millisecond)
86         for {
87                 select {
88                 case <-ticker.C:
89                         p.Log(LineClear, int64(*files), uint64(*size))
90                 case <-p.stop:
91                         ticker.Stop()
92                         p.Log(LineClear, int64(*files), uint64(*size))
93                         close(p.stop)
94                         return
95                 }
96         }
97 }
98
99 func (p Progress) Stop() {
100         p.stop <- struct{}{}
101         <-p.stop
102 }