mirror of
https://github.com/Xpl0itU/WiiUDownloader.git
synced 2025-05-09 13:52:02 -04:00
Improve progress tracking and reporting
This commit is contained in:
parent
5eb05670ad
commit
c69ede0ec5
3 changed files with 36 additions and 18 deletions
|
@ -65,6 +65,7 @@ type ProgressWindow struct {
|
|||
cancelled bool
|
||||
totalToDownload int64
|
||||
totalDownloaded int64
|
||||
progressPerFile map[string]int64 // map of filename to downloaded bytes
|
||||
progressMutex sync.Mutex
|
||||
speedAverager *SpeedAverager
|
||||
startTime time.Time
|
||||
|
@ -79,13 +80,19 @@ func (pw *ProgressWindow) SetGameTitle(title string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (pw *ProgressWindow) UpdateDownloadProgress(downloaded int64) {
|
||||
func (pw *ProgressWindow) UpdateDownloadProgress(downloaded int64, filename string) {
|
||||
glib.IdleAdd(func() {
|
||||
pw.cancelButton.SetSensitive(true)
|
||||
pw.AddToTotalDownloaded(downloaded)
|
||||
pw.bar.SetFraction(float64(pw.totalDownloaded) / float64(pw.totalToDownload))
|
||||
pw.speedAverager.AddSpeed(calculateDownloadSpeed(pw.totalDownloaded, pw.startTime, time.Now()))
|
||||
pw.bar.SetText(fmt.Sprintf("Downloading... (%s/%s) (%s/s)", humanize.Bytes(uint64(pw.totalDownloaded)), humanize.Bytes(uint64(pw.totalToDownload)), humanize.Bytes(uint64(int64(pw.speedAverager.GetAverageSpeed())))))
|
||||
pw.progressMutex.Lock()
|
||||
pw.progressPerFile[filename] += downloaded
|
||||
total := pw.totalDownloaded
|
||||
for _, v := range pw.progressPerFile {
|
||||
total += v
|
||||
}
|
||||
pw.progressMutex.Unlock()
|
||||
pw.bar.SetFraction(float64(total) / float64(pw.totalToDownload))
|
||||
pw.speedAverager.AddSpeed(calculateDownloadSpeed(total, pw.startTime, time.Now()))
|
||||
pw.bar.SetText(fmt.Sprintf("Downloading... (%s/%s) (%s/s)", humanize.Bytes(uint64(total)), humanize.Bytes(uint64(pw.totalToDownload)), humanize.Bytes(uint64(int64(pw.speedAverager.GetAverageSpeed())))))
|
||||
})
|
||||
for gtk.EventsPending() {
|
||||
gtk.MainIteration()
|
||||
|
@ -121,15 +128,20 @@ func (pw *ProgressWindow) SetDownloadSize(size int64) {
|
|||
pw.totalToDownload = size
|
||||
}
|
||||
|
||||
func (pw *ProgressWindow) SetTotalDownloaded(total int64) {
|
||||
func (pw *ProgressWindow) ResetTotalDownloaded() {
|
||||
pw.progressPerFile = make(map[string]int64)
|
||||
}
|
||||
|
||||
func (pw *ProgressWindow) MarkFileAsDone(filename string) {
|
||||
pw.progressMutex.Lock()
|
||||
pw.totalDownloaded = total
|
||||
pw.totalDownloaded += pw.progressPerFile[filename]
|
||||
delete(pw.progressPerFile, filename)
|
||||
pw.progressMutex.Unlock()
|
||||
}
|
||||
|
||||
func (pw *ProgressWindow) AddToTotalDownloaded(toAdd int64) {
|
||||
func (pw *ProgressWindow) SetTotalDownloadedForFile(filename string, downloaded int64) {
|
||||
pw.progressMutex.Lock()
|
||||
pw.totalDownloaded += toAdd
|
||||
pw.progressPerFile[filename] = downloaded
|
||||
pw.progressMutex.Unlock()
|
||||
}
|
||||
|
||||
|
|
|
@ -28,13 +28,14 @@ var (
|
|||
|
||||
type ProgressReporter interface {
|
||||
SetGameTitle(title string)
|
||||
UpdateDownloadProgress(downloaded int64)
|
||||
UpdateDownloadProgress(downloaded int64, filename string)
|
||||
UpdateDecryptionProgress(progress float64)
|
||||
Cancelled() bool
|
||||
SetCancelled()
|
||||
SetDownloadSize(size int64)
|
||||
SetTotalDownloaded(total int64)
|
||||
AddToTotalDownloaded(toAdd int64)
|
||||
ResetTotalDownloaded()
|
||||
MarkFileAsDone(filename string)
|
||||
SetTotalDownloadedForFile(filename string, downloaded int64)
|
||||
SetStartTime(startTime time.Time)
|
||||
}
|
||||
|
||||
|
@ -44,6 +45,8 @@ func downloadFileWithSemaphore(ctx context.Context, progressReporter ProgressRep
|
|||
}
|
||||
defer sem.Release(1)
|
||||
|
||||
basePath := filepath.Base(dstPath)
|
||||
|
||||
for attempt := 1; attempt <= maxRetries; attempt++ {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", downloadURL, nil)
|
||||
if err != nil {
|
||||
|
@ -77,7 +80,8 @@ func downloadFileWithSemaphore(ctx context.Context, progressReporter ProgressRep
|
|||
return err
|
||||
}
|
||||
|
||||
writerProgress := newWriterProgress(file, progressReporter)
|
||||
progressReporter.SetTotalDownloadedForFile(basePath, 0)
|
||||
writerProgress := newWriterProgress(file, progressReporter, basePath)
|
||||
_, err = io.Copy(writerProgress, resp.Body)
|
||||
if err != nil {
|
||||
file.Close()
|
||||
|
@ -92,6 +96,7 @@ func downloadFileWithSemaphore(ctx context.Context, progressReporter ProgressRep
|
|||
file.Close()
|
||||
resp.Body.Close()
|
||||
writerProgress.Close()
|
||||
progressReporter.MarkFileAsDone(basePath)
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -131,7 +136,7 @@ func downloadFile(progressReporter ProgressReporter, client *http.Client, downlo
|
|||
return err
|
||||
}
|
||||
|
||||
writerProgress := newWriterProgress(file, progressReporter)
|
||||
writerProgress := newWriterProgress(file, progressReporter, filepath.Base(dstPath))
|
||||
_, err = io.Copy(writerProgress, resp.Body)
|
||||
if err != nil {
|
||||
file.Close()
|
||||
|
@ -153,7 +158,7 @@ func downloadFile(progressReporter ProgressReporter, client *http.Client, downlo
|
|||
func DownloadTitle(titleID, outputDirectory string, doDecryption bool, progressReporter ProgressReporter, deleteEncryptedContents bool, logger *Logger, client *http.Client) error {
|
||||
tEntry := getTitleEntryFromTid(titleID)
|
||||
|
||||
progressReporter.SetTotalDownloaded(0)
|
||||
progressReporter.ResetTotalDownloaded()
|
||||
progressReporter.SetGameTitle(tEntry.Name)
|
||||
|
||||
outputDir := strings.TrimRight(outputDirectory, "/\\")
|
||||
|
|
|
@ -10,16 +10,17 @@ type WriterProgress struct {
|
|||
progressReporter ProgressReporter
|
||||
updateProgressTicker *time.Ticker
|
||||
downloadToReport int64 // Number of bytes to report to the progressReporter since the last update
|
||||
filename string
|
||||
}
|
||||
|
||||
func newWriterProgress(writer io.Writer, progressReporter ProgressReporter) *WriterProgress {
|
||||
return &WriterProgress{writer: writer, progressReporter: progressReporter, updateProgressTicker: time.NewTicker(25 * time.Millisecond), downloadToReport: 0}
|
||||
func newWriterProgress(writer io.Writer, progressReporter ProgressReporter, filename string) *WriterProgress {
|
||||
return &WriterProgress{writer: writer, progressReporter: progressReporter, updateProgressTicker: time.NewTicker(25 * time.Millisecond), downloadToReport: 0, filename: filename}
|
||||
}
|
||||
|
||||
func (r *WriterProgress) Write(p []byte) (n int, err error) {
|
||||
select {
|
||||
case <-r.updateProgressTicker.C:
|
||||
r.progressReporter.UpdateDownloadProgress(r.downloadToReport)
|
||||
r.progressReporter.UpdateDownloadProgress(r.downloadToReport, r.filename)
|
||||
r.downloadToReport = 0
|
||||
default:
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue