From c05243444fde4da979d476eea8c018d5eacc6c2e Mon Sep 17 00:00:00 2001 From: abraunegg Date: Sun, 26 Apr 2020 06:52:29 +1000 Subject: [PATCH] Update progress bar to be more accurate when downloading large files (#888) * Change from round to floor, so % bar increases when downloaded data is at X% not potentially under, thus leading to under reporting * Add debug output when each % increase when downloading a file to assist with validating progress * Start displaying ETA starting at 5% rather than 10% --- src/log.d | 2 +- src/onedrive.d | 28 ++++++++++++++++++++++------ src/progress.d | 6 +++--- src/upload.d | 2 +- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/log.d b/src/log.d index fcbcf1f3..c868fd50 100644 --- a/src/log.d +++ b/src/log.d @@ -100,7 +100,7 @@ void vdebug(T...)(T args) } } -void vdebugUpload(T...)(T args) +void vdebugNewLine(T...)(T args) { if (verbose >= 2) { writeln("\n[DEBUG] ", args); diff --git a/src/onedrive.d b/src/onedrive.d index 0a3ee6ef..de4f2a88 100644 --- a/src/onedrive.d +++ b/src/onedrive.d @@ -567,18 +567,34 @@ final class OneDriveApi Progress p = new Progress(iteration); p.title = "Downloading"; writeln(); - + bool barInit = false; real previousDLPercent = -1.0; real percentCheck = 5.0; // Setup progress bar to display http.onProgress = delegate int(size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) { // For each onProgress, what is the % of dlnow to dltotal - real currentDLPercent = round(double(dlnow)/dltotal*100); - // If matching 5% of download, increment progress bar - if ((isIdentical(fmod(currentDLPercent, percentCheck), 0.0)) && (previousDLPercent != currentDLPercent)) { - p.next(); - previousDLPercent = currentDLPercent; + // floor - rounds down to nearest whole number + real currentDLPercent = floor(double(dlnow)/dltotal*100); + if (currentDLPercent > 0){ + // We have started downloading + // If matching 5% of download, increment progress bar + if ((isIdentical(fmod(currentDLPercent, percentCheck), 0.0)) && (previousDLPercent != currentDLPercent)) { + // What have we downloaded thus far + log.vdebugNewLine("Data Received = ", dlnow); + log.vdebug("Expected Total = ", dltotal); + log.vdebug("Percent Complete = ", currentDLPercent); + // Increment counter & show bar update + p.next(); + previousDLPercent = currentDLPercent; + } + } else { + if ((currentDLPercent == 0) && (!barInit)) { + // Initialise the download bar at 0% + // Downloading 0% | | ETA --:--:--:^C + p.next(); + barInit = true; + } } return 0; }; diff --git a/src/progress.d b/src/progress.d index d8b33e04..c07a43d0 100644 --- a/src/progress.d +++ b/src/progress.d @@ -82,7 +82,7 @@ class Progress header.formattedWrite("%s %3d%% |", caption, cast(int)(ratio * 100)); - if(counter <= 1 || ratio == 0.0) { + if(counter <= 0 || ratio == 0.0) { footer.formattedWrite("| ETA --:--:--:"); } else { int h, m, s; @@ -114,7 +114,7 @@ class Progress this(size_t iterations) { if(iterations <= 0) iterations = 1; - counter = 0; + counter = -1; this.iterations = iterations; start_time = Clock.currTime.toUnixTime; } @@ -140,7 +140,7 @@ class Progress } void reset() { - counter = 0; + counter = -1; start_time = Clock.currTime.toUnixTime; } diff --git a/src/upload.d b/src/upload.d index 275ac46a..d868dc4a 100644 --- a/src/upload.d +++ b/src/upload.d @@ -176,7 +176,7 @@ struct UploadSession while (true) { fragmentCount++; - log.vdebugUpload("Fragment: ", fragmentCount, " of ", iteration); + log.vdebugNewLine("Fragment: ", fragmentCount, " of ", iteration); p.next(); long fragSize = fragmentSize < fileSize - offset ? fragmentSize : fileSize - offset; // If the resume upload fails, we need to check for a return code here