🧱 Chunk is a download manager for slow and unstable servers
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #23 from cuducos/client

Creates usage example with download status

authored by

Daniel Fireman and committed by
GitHub
5195d58e 1919d299

+86 -8
+79
example.go
··· 1 + package main 2 + 3 + import ( 4 + "context" 5 + "fmt" 6 + "time" 7 + ) 8 + 9 + func humanSize(s float64) string { 10 + size, unit := func(s float64) (float64, string) { 11 + m := []string{"B", "kB", "MB", "GB", "TB"} 12 + i := 0 13 + b := 1000.0 14 + for s >= b && i < len(m)-1 { 15 + s = s / b 16 + i++ 17 + } 18 + return s, m[i] 19 + }(s) 20 + return fmt.Sprintf("%.1f%s", size, unit) 21 + } 22 + 23 + type file struct{ total, done int64 } 24 + 25 + type downloadProgress struct { 26 + files map[string]file 27 + startedAt time.Time 28 + close context.CancelFunc 29 + } 30 + 31 + func (p *downloadProgress) total() (t int64) { 32 + for _, f := range p.files { 33 + t += f.total 34 + } 35 + return 36 + } 37 + 38 + func (p *downloadProgress) done() (d int64) { 39 + for _, f := range p.files { 40 + d += f.done 41 + } 42 + return 43 + } 44 + 45 + func (p *downloadProgress) String() string { 46 + perc := float64(p.done()) / float64(p.total()) 47 + speed := float64(p.done()) / time.Since(p.startedAt).Seconds() 48 + return fmt.Sprintf( 49 + "Downloading %s of %s\t%.2f%%\t%s/s", 50 + humanSize(float64(p.done())), 51 + humanSize(float64(p.total())), 52 + perc*100, 53 + humanSize(speed), 54 + ) 55 + } 56 + 57 + func (p *downloadProgress) update(d DownloadStatus) { 58 + p.files[d.DownloadedFilePath] = file{d.FileSizeBytes, d.DownloadedFileBytes} 59 + if p.done() == p.total() { 60 + p.close() 61 + } 62 + } 63 + 64 + func NewProgress() *downloadProgress { 65 + ctx, cancel := context.WithCancel(context.Background()) 66 + bar := downloadProgress{make(map[string]file), time.Now(), cancel} 67 + tick := time.Tick(1 * time.Second) 68 + go func() { 69 + for { 70 + select { 71 + case <-tick: 72 + fmt.Printf("\r%s", bar.String()) 73 + case <-ctx.Done(): 74 + return 75 + } 76 + } 77 + }() 78 + return &bar 79 + }
+7 -8
main.go
··· 306 306 } 307 307 308 308 func main() { 309 - d := DefaultDownloader() 310 - for s := range d.Download(os.Args[1:len(os.Args)]...) { 311 - if s.Error != nil { 312 - log.Fatal(s.Error) 309 + chunk := DefaultDownloader() 310 + prog := NewProgress() 311 + for status := range chunk.Download(os.Args[1:len(os.Args)]...) { 312 + if status.Error != nil { 313 + log.Fatal(status.Error) 313 314 } 314 - if s.IsFinished() { 315 - log.Printf("Downloaded %s (%d bytes) to %s (%d bytes).", s.URL, s.FileSizeBytes, s.DownloadedFilePath, s.DownloadedFileBytes) 316 - } 315 + prog.update(status) 317 316 } 318 - log.Println("All download(s) finished successfully.") 317 + fmt.Printf("\r%s\nDownloaded to: %s", prog.String(), os.TempDir()) 319 318 }