97 lines
2.0 KiB
Go
97 lines
2.0 KiB
Go
package fetch
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/inancgumus/screen"
|
|
)
|
|
|
|
const refreshPeriod = time.Second / 10
|
|
|
|
// uiProgress is the default UI for the downloader
|
|
type uiProgress struct {
|
|
urls []string
|
|
transfers map[string]Progress
|
|
}
|
|
|
|
// UI listens for the progress updates from the updates chan
|
|
// and it refreshes the ui
|
|
func UI(updates <-chan Progress) {
|
|
ui := &uiProgress{transfers: make(map[string]Progress)}
|
|
|
|
// NOTE: we didn't use time.After here directly
|
|
// because doing so can create a lot of Timer chans unnecessarily
|
|
// instead we're just waiting on the same timer value
|
|
tick := time.After(refreshPeriod)
|
|
for {
|
|
select {
|
|
case p, ok := <-updates:
|
|
// if no more updates close the ui
|
|
if !ok {
|
|
ui.shutdown()
|
|
return
|
|
}
|
|
ui.update(p)
|
|
|
|
case <-tick:
|
|
// `case <-tick:` allows updating the ui independently
|
|
// from the progress update signals. or the ui would hang
|
|
// the updaters (transfers).
|
|
ui.refresh()
|
|
tick = time.After(refreshPeriod)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// shutdown refreshes the ui for the last time and closes it
|
|
func (ui *uiProgress) shutdown() {
|
|
ui.refresh()
|
|
|
|
if debug {
|
|
fmt.Printf("[ UI ] DONE\n")
|
|
}
|
|
}
|
|
|
|
// update updates the progress data from the received message
|
|
func (ui *uiProgress) update(p Progress) {
|
|
if _, ok := ui.transfers[p.URL]; !ok {
|
|
ui.urls = append(ui.urls, p.URL)
|
|
}
|
|
|
|
// update the latest progress for the url
|
|
ui.transfers[p.URL] = p
|
|
}
|
|
|
|
// refresh refreshes the UI with the latest progress
|
|
func (ui *uiProgress) refresh() {
|
|
if !debug {
|
|
screen.Clear()
|
|
screen.MoveTopLeft()
|
|
}
|
|
|
|
var total, downloaded int
|
|
|
|
for _, u := range ui.urls {
|
|
p := ui.transfers[u]
|
|
|
|
msg := "Downloading"
|
|
if p.Done && p.Error == nil {
|
|
msg = "👍 Completed"
|
|
}
|
|
if p.Error != nil {
|
|
msg = fmt.Sprintf("❌ %s", p.Error)
|
|
}
|
|
|
|
fmt.Println(p.URL)
|
|
fmt.Printf("\t%d/%d\n", p.Downloaded, p.Total)
|
|
fmt.Printf("\t%s\n", msg)
|
|
|
|
total += p.Total
|
|
downloaded += p.Downloaded
|
|
}
|
|
|
|
fmt.Printf("\n%s %d/%d\n", "TOTAL DOWNLOADED BYTES:", downloaded, total)
|
|
}
|