piwigo-cli/internal/piwigo/piwigotools/file_to_upload_stat.go

147 lines
2.6 KiB
Go

package piwigotools
import (
"fmt"
"github.com/apoorvam/goterminal"
ct "github.com/daviddengcn/go-colortext"
"os"
"strings"
"sync"
"time"
)
const (
megabytes = 1 << 20
kilobytes = 1 << 10
)
type FileToUploadStat struct {
Checked uint32
Total uint32
Uploaded uint32
Skipped uint32
Failed uint32
UploadedBytes int64
TotalBytes int64
progress *goterminal.Writer
mu sync.Mutex
lastRefresh time.Time
}
func NewFileToUploadStat() *FileToUploadStat {
return &FileToUploadStat{
progress: goterminal.New(os.Stdout),
}
}
func (s *FileToUploadStat) formatBytes(b int64) string {
if b > megabytes {
return fmt.Sprintf("%.2fMB", float64(b)/(1<<20))
} else if b > kilobytes {
return fmt.Sprintf("%.2fKB", float64(b)/(1<<10))
} else {
return fmt.Sprintf("%dB", b)
}
}
func (s *FileToUploadStat) refreshIfNeeded() {
if time.Since(s.lastRefresh) > 200*time.Millisecond {
s.refresh()
}
}
func (s *FileToUploadStat) refresh() {
s.progress.Clear()
_, _ = s.progress.Write([]byte("Statistics:\n"))
_, _ = fmt.Fprintf(
s.progress,
strings.Repeat("%20s: %d\n", 5)+strings.Repeat("%20s: %s\n", 2),
"Checked", s.Checked,
"Uploaded", s.Uploaded,
"Skipped", s.Skipped,
"Failed", s.Failed,
"Total", s.Total,
"Uploaded Bytes", s.formatBytes(s.UploadedBytes),
"Total Bytes", s.formatBytes(s.TotalBytes),
)
_ = s.progress.Print()
s.lastRefresh = time.Now()
}
func (s *FileToUploadStat) Check() {
s.mu.Lock()
defer s.mu.Unlock()
s.Checked++
s.refreshIfNeeded()
}
func (s *FileToUploadStat) Add() {
s.mu.Lock()
defer s.mu.Unlock()
s.Total++
s.refreshIfNeeded()
}
func (s *FileToUploadStat) AddBytes(filesize int64) {
s.mu.Lock()
defer s.mu.Unlock()
s.TotalBytes += filesize
s.refreshIfNeeded()
}
func (s *FileToUploadStat) Commit(fileread int64) {
s.mu.Lock()
defer s.mu.Unlock()
s.UploadedBytes += fileread
s.refreshIfNeeded()
}
func (s *FileToUploadStat) Done() {
s.mu.Lock()
defer s.mu.Unlock()
s.Uploaded++
s.refreshIfNeeded()
}
func (s *FileToUploadStat) Fail() {
s.mu.Lock()
defer s.mu.Unlock()
s.Failed++
s.refreshIfNeeded()
}
func (s *FileToUploadStat) Skip() {
s.mu.Lock()
defer s.mu.Unlock()
s.Skipped++
s.refreshIfNeeded()
}
func (s *FileToUploadStat) Error(origin string, filename string, err error) {
s.mu.Lock()
defer s.mu.Unlock()
s.progress.Clear()
ct.Foreground(ct.Red, false)
_, _ = fmt.Fprintf(s.progress, "[%s] %s: %s\n", origin, filename, err)
_ = s.progress.Print()
ct.ResetColor()
s.progress.Reset()
s.refreshIfNeeded()
}
func (s *FileToUploadStat) Close() {
s.refresh()
}