/* sgodup -- File deduplication utility Copyright (C) 2020-2023 Sergey Matveev 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 . */ 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 }