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