]> sjero.net Git - wget/blobdiff - src/progress.c
[svn] When the download is finished, print the time the download took.
[wget] / src / progress.c
index 5bb63fcbda0deec82bf6860a5dd55bfea2bc825e..1efc590e6766e5feb95775c9f80d0412092bd48f 100644 (file)
@@ -265,8 +265,8 @@ print_percentage (wgint bytes, wgint expected)
 static void
 print_download_speed (struct dot_progress *dp, wgint bytes, double dltime)
 {
-  logprintf (LOG_VERBOSE, " %s",
-            retr_rate (bytes, dltime - dp->last_timer_value, 1));
+  logprintf (LOG_VERBOSE, " %7s",
+            retr_rate (bytes, dltime - dp->last_timer_value));
   dp->last_timer_value = dltime;
 }
 
@@ -486,10 +486,10 @@ struct bar_progress {
   double last_eta_time;                /* time of the last update to download
                                   speed and ETA, measured since the
                                   beginning of download. */
-  wgint last_eta_value;
+  int last_eta_value;
 };
 
-static void create_image (struct bar_progress *, double);
+static void create_image (struct bar_progress *, double, bool);
 static void display_image (char *);
 
 static void *
@@ -524,7 +524,7 @@ bar_create (wgint initial, wgint total)
 
   logputs (LOG_VERBOSE, "\n");
 
-  create_image (bp, 0);
+  create_image (bp, 0, false);
   display_image (bp->buffer);
 
   return bp;
@@ -573,7 +573,7 @@ bar_update (void *progress, wgint howmuch, double dltime)
     /* Don't update more often than five times per second. */
     return;
 
-  create_image (bp, dltime);
+  create_image (bp, dltime, false);
   display_image (bp->buffer);
   bp->last_screen_update = dltime;
 }
@@ -588,7 +588,7 @@ bar_finish (void *progress, double dltime)
     /* See bar_update() for explanation. */
     bp->total_length = bp->initial_length + bp->count;
 
-  create_image (bp, dltime);
+  create_image (bp, dltime, true);
   display_image (bp->buffer);
 
   logputs (LOG_VERBOSE, "\n\n");
@@ -700,6 +700,8 @@ update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
 #endif
 }
 
+static const char *eta_to_human_short (int);
+
 #define APPEND_LITERAL(s) do {                 \
   memcpy (p, s, sizeof (s) - 1);               \
   p += sizeof (s) - 1;                         \
@@ -710,18 +712,18 @@ update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
 #endif
 
 static void
-create_image (struct bar_progress *bp, double dl_total_time)
+create_image (struct bar_progress *bp, double dl_total_time, bool done)
 {
   char *p = bp->buffer;
   wgint size = bp->initial_length + bp->count;
 
-  char *size_legible = with_thousand_seps (size);
-  int size_legible_len = strlen (size_legible);
+  const char *size_grouped = with_thousand_seps (size);
+  int size_grouped_len = strlen (size_grouped);
 
   struct bar_progress_hist *hist = &bp->hist;
 
   /* The progress bar should look like this:
-     xx% [=======>             ] nn,nnn 12.34K/s ETA 00:00
+     xx% [=======>             ] nn,nnn 12.34K/s  eta 36m 51s
 
      Calculate the geometry.  The idea is to assign as much room as
      possible to the progress bar.  The other idea is to never let
@@ -734,11 +736,11 @@ create_image (struct bar_progress *bp, double dl_total_time)
      "[]"              - progress bar decorations - 2 chars
      " nnn,nnn,nnn"    - downloaded bytes         - 12 chars or very rarely more
      " 1012.56K/s"     - dl rate                  - 11 chars
-     " ETA xx:xx:xx"   - ETA                      - 13 chars
+     "  eta 36m 51s"   - ETA                      - 13 chars
 
      "=====>..."       - progress bar             - the rest
   */
-  int dlbytes_size = 1 + MAX (size_legible_len, 11);
+  int dlbytes_size = 1 + MAX (size_grouped_len, 11);
   int progress_size = bp->width - (4 + 2 + dlbytes_size + 11 + 13);
 
   if (progress_size < 5)
@@ -748,7 +750,6 @@ create_image (struct bar_progress *bp, double dl_total_time)
   if (bp->total_length > 0)
     {
       int percentage = (int)(100.0 * size / bp->total_length);
-
       assert (percentage <= 100);
 
       if (percentage < 100)
@@ -822,7 +823,7 @@ create_image (struct bar_progress *bp, double dl_total_time)
     }
 
   /* " 234,567,890" */
-  sprintf (p, " %-11s", with_thousand_seps (size));
+  sprintf (p, " %-11s", size_grouped);
   p += strlen (p);
 
   /* " 1012.45K/s" */
@@ -841,62 +842,50 @@ create_image (struct bar_progress *bp, double dl_total_time)
   else
     APPEND_LITERAL ("   --.--K/s");
 
-  /* " ETA xx:xx:xx"; wait for three seconds before displaying the ETA.
-     That's because the ETA value needs a while to become
-     reliable.  */
-  if (bp->total_length > 0 && bp->count > 0 && dl_total_time > 3000)
+  if (!done)
     {
-      wgint eta;
-      int eta_hrs, eta_min, eta_sec;
-
-      /* Don't change the value of ETA more than approximately once
-        per second; doing so would cause flashing without providing
-        any value to the user. */
-      if (bp->total_length != size
-         && bp->last_eta_value != 0
-         && dl_total_time - bp->last_eta_time < 900)
-       eta = bp->last_eta_value;
-      else
-       {
-         /* Calculate ETA using the average download speed to predict
-            the future speed.  If you want to use a speed averaged
-            over a more recent period, replace dl_total_time with
-            hist->total_time and bp->count with hist->total_bytes.
-            I found that doing that results in a very jerky and
-            ultimately unreliable ETA.  */
-         double time_sofar = (double)dl_total_time / 1000;
-         wgint bytes_remaining = bp->total_length - size;
-         eta = (wgint) (time_sofar * bytes_remaining / bp->count);
-         bp->last_eta_value = eta;
-         bp->last_eta_time = dl_total_time;
-       }
-
-      eta_hrs = eta / 3600, eta %= 3600;
-      eta_min = eta / 60,   eta %= 60;
-      eta_sec = eta;
-
-      if (eta_hrs > 99)
-       goto no_eta;
-
-      if (eta_hrs == 0)
+      /* "  eta ..m ..s"; wait for three seconds before displaying the ETA.
+        That's because the ETA value needs a while to become
+        reliable.  */
+      if (bp->total_length > 0 && bp->count > 0 && dl_total_time > 3000)
        {
-         /* Hours not printed: pad with three spaces. */
-         APPEND_LITERAL ("   ");
-         sprintf (p, " ETA %02d:%02d", eta_min, eta_sec);
+         int eta;
+
+         /* Don't change the value of ETA more than approximately once
+            per second; doing so would cause flashing without providing
+            any value to the user. */
+         if (bp->total_length != size
+             && bp->last_eta_value != 0
+             && dl_total_time - bp->last_eta_time < 900)
+           eta = bp->last_eta_value;
+         else
+           {
+             /* Calculate ETA using the average download speed to predict
+                the future speed.  If you want to use a speed averaged
+                over a more recent period, replace dl_total_time with
+                hist->total_time and bp->count with hist->total_bytes.
+                I found that doing that results in a very jerky and
+                ultimately unreliable ETA.  */
+             double time_sofar = (double) dl_total_time / 1000;
+             wgint bytes_remaining = bp->total_length - size;
+             eta = (int) (time_sofar * bytes_remaining / bp->count + 0.5);
+             bp->last_eta_value = eta;
+             bp->last_eta_time = dl_total_time;
+           }
+
+         sprintf (p, "  eta %s", eta_to_human_short (eta));
+         p += strlen (p);
        }
-      else
+      else if (bp->total_length > 0)
        {
-         if (eta_hrs < 10)
-           /* Hours printed with one digit: pad with one space. */
-           *p++ = ' ';
-         sprintf (p, " ETA %d:%02d:%02d", eta_hrs, eta_min, eta_sec);
+         APPEND_LITERAL ("             ");
        }
-      p += strlen (p);
     }
-  else if (bp->total_length > 0)
+  else
     {
-    no_eta:
-      APPEND_LITERAL ("             ");
+      /* When the download is done, print the elapsed time.  */
+      sprintf (p, _("   in %s"), eta_to_human_short (dl_total_time / 1000 + 0.5));
+      p += strlen (p);
     }
 
   assert (p - bp->buffer <= bp->width);
@@ -961,3 +950,34 @@ progress_handle_sigwinch (int sig)
   signal (SIGWINCH, progress_handle_sigwinch);
 }
 #endif
+
+/* Provide a short human-readable rendition of the ETA.  It never
+   occupies more than 7 characters of screen space.  */
+
+static const char *
+eta_to_human_short (int secs)
+{
+  static char buf[10];         /* 8 is enough, but just in case */
+  static int last = -1;
+
+  /* Trivial optimization.  This function can be called every 200
+     msecs (see bar_update) for fast downloads, but ETA will only
+     change once per 900 msecs (see create_image).  */
+  if (secs == last)
+    return buf;
+  last = secs;
+
+  if (secs < 100)
+    sprintf (buf, _("%ds"), secs);
+  else if (secs < 100 * 60)
+    sprintf (buf, _("%dm %ds"), secs / 60, secs % 60);
+  else if (secs < 100 * 3600)
+    sprintf (buf, _("%dh %dm"), secs / 3600, (secs / 60) % 60);
+  else if (secs < 100 * 86400)
+    sprintf (buf, _("%dd %dh"), secs / 86400, (secs / 3600) % 60);
+  else
+    /* (2^31-1)/86400 doesn't overflow BUF. */
+    sprintf (buf, _("%dd"), secs / 86400);
+
+  return buf;
+}