Hi, I've recently been hacking on the progress bar implementation in Wget to improve it for multiple reasons. In the attached patch I've made the following changes:
1. Add support for --no-scroll switch. Lots of users, after my previous patch asked for the option to disable scrolling the filename in the progress bar. Hence, I have added support for --no-scroll 2. Add human readable output for th amount of download already complete. Wget used to output the total number of bytes downloaded for each file in the progress bar. This was fine a few years ago, when file sizes were relatively small. But now when people are regularly downloading files in the magnitude of a few Gigabytes, maybe outputing the number of bytes alone is not enough. Hence, I changed that to display a human readable value instead. This patch is currently only a RFC. There's a few things I'd like your comments on: 1. Should the numbers have localization support? They don't seem to have localization support as of now. i.e. 123.45 would be displayed as 123,45 for the Europeans. 2. I am not aware of anyone parsing the output of Wget's progress bar. Do you think changing the default output would cause a problem? 3. Should we add some kind of --human-readable option to toggle between bytes output and human readable output? This patch is currently not ready for merging since it is missing the relevant NEWS and info page entries. This is essentially a request for comments and criticism on the patch. -- Thanking You, Darshit Shah
From 231e638d8fa74488745d1eb5166faa82d126bc11 Mon Sep 17 00:00:00 2001 From: Darshit Shah <[email protected]> Date: Tue, 20 May 2014 00:15:45 +0530 Subject: [PATCH] More progress bar aesthetic changes This commit introduces two new changes to how the progress bar looks: 1. Support the --no-scroll option which will prevent the filename from scrolling in the progress bar 2. Print human readable value for the amount already downloaded for any file --- src/ChangeLog | 16 ++++++++++++++++ src/ftp.c | 4 ++-- src/http.c | 4 ++-- src/init.c | 2 ++ src/main.c | 5 +++-- src/options.h | 1 + src/progress.c | 46 +++++++++++++++++++++++++++++++--------------- src/utils.c | 8 ++++---- src/utils.h | 2 +- 9 files changed, 62 insertions(+), 26 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index f07ddc5..c3a5944 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,19 @@ +2014-05-20 Darshit Shah <[email protected]> + + * utils.c (human_readable): Add new parameters, acc and decimals for the + function. acc decides the number under which decimal values are shown for a + certain value, while decimals decides the number of decimal digits displayed + * utils.h (human_readable): Update declartion of the function + * ftp.c (print_length): Update call to human_readable + * http.c (gethttp): Same + * init.c (commands): Add new command noscroll + (defaults): Enable scrolling filenames by default + * main.c (option_data): Add new switch --no-scroll + (main): Update call to human_readable + * options.h (options): Add new option noscroll + * progress.c (create_image): Update the look of the progress bar. Human + readable download size by default and add support for --no-scroll + 2014-05-03 Tim Ruehsen <[email protected]> * ftp-ls.c (ftp_parse_vms_ls): Explicitly typecast strlen's output diff --git a/src/ftp.c b/src/ftp.c index 25f05a4..e63d98d 100644 --- a/src/ftp.c +++ b/src/ftp.c @@ -221,13 +221,13 @@ print_length (wgint size, wgint start, bool authoritative) { logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size)); if (size >= 1024) - logprintf (LOG_VERBOSE, " (%s)", human_readable (size)); + logprintf (LOG_VERBOSE, " (%s)", human_readable (size, 10, 1)); if (start > 0) { if (size - start >= 1024) logprintf (LOG_VERBOSE, _(", %s (%s) remaining"), number_to_static_string (size - start), - human_readable (size - start)); + human_readable (size - start, 10, 1)); else logprintf (LOG_VERBOSE, _(", %s remaining"), number_to_static_string (size - start)); diff --git a/src/http.c b/src/http.c index b50acf4..0583fae 100644 --- a/src/http.c +++ b/src/http.c @@ -2804,13 +2804,13 @@ read_header: logputs (LOG_VERBOSE, number_to_static_string (contlen + contrange)); if (contlen + contrange >= 1024) logprintf (LOG_VERBOSE, " (%s)", - human_readable (contlen + contrange)); + human_readable (contlen + contrange, 10, 1)); if (contrange) { if (contlen >= 1024) logprintf (LOG_VERBOSE, _(", %s (%s) remaining"), number_to_static_string (contlen), - human_readable (contlen)); + human_readable (contlen, 10, 1)); else logprintf (LOG_VERBOSE, _(", %s remaining"), number_to_static_string (contlen)); diff --git a/src/init.c b/src/init.c index fbef133..3cf3cc2 100644 --- a/src/init.c +++ b/src/init.c @@ -222,6 +222,7 @@ static const struct { { "noconfig", &opt.noconfig, cmd_boolean }, { "noparent", &opt.no_parent, cmd_boolean }, { "noproxy", &opt.no_proxy, cmd_vector }, + { "noscroll", &opt.noscroll, cmd_boolean}, { "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/ { "outputdocument", &opt.output_document, cmd_file }, { "pagerequisites", &opt.page_requisites, cmd_boolean }, @@ -413,6 +414,7 @@ defaults (void) /* Use a negative value to mark the absence of --start-pos option */ opt.start_pos = -1; opt.show_progress = false; + opt.noscroll = false; } /* Return the user's home directory (strdup-ed), or NULL if none is diff --git a/src/main.c b/src/main.c index 29c1324..72dacc6 100644 --- a/src/main.c +++ b/src/main.c @@ -234,6 +234,7 @@ static struct cmdline_option option_data[] = { "no-clobber", 0, OPT_BOOLEAN, "noclobber", -1 }, { "no-config", 0, OPT_BOOLEAN, "noconfig", -1}, { "no-parent", 0, OPT_BOOLEAN, "noparent", -1 }, + { "no-scroll", 0, OPT_BOOLEAN, "noscroll", -1}, { "output-document", 'O', OPT_VALUE, "outputdocument", -1 }, { "output-file", 'o', OPT_VALUE, "logfile", -1 }, { "page-requisites", 'p', OPT_BOOLEAN, "pagerequisites", -1 }, @@ -1714,7 +1715,7 @@ outputting to a regular file.\n")); datetime_str (time (NULL)), wall_time, numurls, - human_readable (total_downloaded_bytes), + human_readable (total_downloaded_bytes, 10, 1), download_time, retr_rate (total_downloaded_bytes, total_download_time)); xfree (wall_time); @@ -1724,7 +1725,7 @@ outputting to a regular file.\n")); if (opt.quota && total_downloaded_bytes > opt.quota) logprintf (LOG_NOTQUIET, _("Download quota of %s EXCEEDED!\n"), - human_readable (opt.quota)); + human_readable (opt.quota, 10, 1)); } if (opt.cookies_output) diff --git a/src/options.h b/src/options.h index 9358e30..2855149 100644 --- a/src/options.h +++ b/src/options.h @@ -135,6 +135,7 @@ struct options char *base_href; char *progress_type; /* progress indicator type. */ bool show_progress; /* Show only the progress bar */ + bool noscroll; /* Don't scroll the filename in the progressbar */ char *proxy_user; /*oli*/ char *proxy_passwd; diff --git a/src/progress.c b/src/progress.c index 6cb22d7..fd26b46 100644 --- a/src/progress.c +++ b/src/progress.c @@ -889,7 +889,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) int orig_filename_len = strlen (bp->f_download); /* The progress bar should look like this: - file xx% [=======> ] nn,nnn 12.34KB/s eta 36m 51s + file xx% [=======> ] nnn.nnK 12.34KB/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 @@ -898,17 +898,26 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) It would be especially bad for the progress bar to be resized randomly. - "file " - Downloaded filename - MAX MAX_FILENAME_LEN chars + 1 + "file " - Downloaded filename - MAX_FILENAME_LEN chars + 1 "xx% " or "100%" - percentage - 4 chars "[]" - progress bar decorations - 2 chars - " nnn,nnn,nnn" - downloaded bytes - 12 chars or very rarely more - " 12.5KB/s" - download rate - 9 chars + " nnn.nnK" - downloaded bytes - 7 chars + 1 + " 12.5KB/s" - download rate - 8 chars + 1 " eta 36m 51s" - ETA - 14 chars "=====>..." - progress bar - the rest */ - int dlbytes_size = 1 + MAX (size_grouped_len, 11); - int progress_size = bp->width - (MAX_FILENAME_LEN + 1 + 4 + 2 + dlbytes_size + 8 + 14); + +#define PROGRESS_FILENAME_LEN MAX_FILENAME_LEN + 1 +#define PROGRESS_PERCENT_LEN 4 +#define PROGRESS_DECORAT_LEN 2 +#define PROGRESS_FILESIZE_LEN 7 + 1 +#define PROGRESS_DWNLOAD_RATE 8 + 1 +#define PROGRESS_ETA_LEN 14 + + int progress_size = bp->width - (PROGRESS_FILENAME_LEN + PROGRESS_PERCENT_LEN + + PROGRESS_DECORAT_LEN + PROGRESS_FILESIZE_LEN + + PROGRESS_DWNLOAD_RATE + PROGRESS_ETA_LEN); /* The difference between the number of bytes used, and the number of columns used. */ @@ -929,7 +938,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) { int offset; - if (orig_filename_len > MAX_FILENAME_LEN) + if (((orig_filename_len > MAX_FILENAME_LEN) && !opt.noscroll) && !done) offset = ((int) bp->tick) % (orig_filename_len - MAX_FILENAME_LEN); else offset = 0; @@ -1014,13 +1023,20 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) } ++bp->tick; - /* " 234,567,890" */ - sprintf (p, " %s", size_grouped); + /* " 234.56M" */ + const char * down_size = human_readable (size, 1000, 2); + int cols_diff = 7 - count_cols (down_size); + while (cols_diff > 0) + { + *p++=' '; + cols_diff--; + } + sprintf (p, " %s", down_size); move_to_end (p); - /* Pad with spaces to 11 chars for the size_grouped field; + /* Pad with spaces to 7 chars for the size_grouped field; * couldn't use the field width specifier in sprintf, because * it counts in bytes, not characters. */ - for (size_grouped_pad = 11 - size_grouped_len; + for (size_grouped_pad = PROGRESS_FILESIZE_LEN - 7; size_grouped_pad > 0; --size_grouped_pad) { @@ -1030,20 +1046,20 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done) /* " 12.52Kb/s or 12.52KB/s" */ if (hist->total_time > 0 && hist->total_bytes) { - static const char *short_units[] = { "B/s", "KB/s", "MB/s", "GB/s" }; - static const char *short_units_bits[] = { "b/s", "Kb/s", "Mb/s", "Gb/s" }; + static const char *short_units[] = { " B/s", "KB/s", "MB/s", "GB/s" }; + static const char *short_units_bits[] = { " b/s", "Kb/s", "Mb/s", "Gb/s" }; int units = 0; /* Calculate the download speed using the history ring and recent data that hasn't made it to the ring yet. */ wgint dlquant = hist->total_bytes + bp->recent_bytes; double dltime = hist->total_time + (dl_total_time - bp->recent_start); double dlspeed = calc_rate (dlquant, dltime, &units); - sprintf (p, "%4.*f%s", dlspeed >= 99.95 ? 0 : dlspeed >= 9.995 ? 1 : 2, + sprintf (p, " %4.*f%s", dlspeed >= 99.95 ? 0 : dlspeed >= 9.995 ? 1 : 2, dlspeed, !opt.report_bps ? short_units[units] : short_units_bits[units]); move_to_end (p); } else - APPEND_LITERAL ("--.-KB/s"); + APPEND_LITERAL (" --.-KB/s"); if (!done) { diff --git a/src/utils.c b/src/utils.c index 11ca75c..8168fb3 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1523,7 +1523,7 @@ with_thousand_seps (wgint n) some detail. */ char * -human_readable (HR_NUMTYPE n) +human_readable (HR_NUMTYPE n, const int acc, const int decimals) { /* These suffixes are compatible with those of GNU `ls -lh'. */ static char powers[] = @@ -1556,10 +1556,10 @@ human_readable (HR_NUMTYPE n) if ((n / 1024) < 1024 || i == countof (powers) - 1) { double val = n / 1024.0; - /* Print values smaller than 10 with one decimal digits, and - others without any decimals. */ + /* Print values smaller than the accuracy level (acc) with (decimal) + * decimal digits, and others without any decimals. */ snprintf (buf, sizeof (buf), "%.*f%c", - val < 10 ? 1 : 0, val, powers[i]); + val < acc ? decimals : 0, val, powers[i]); return buf; } n /= 1024; diff --git a/src/utils.h b/src/utils.h index e244b8a..1f4cb69 100644 --- a/src/utils.h +++ b/src/utils.h @@ -121,7 +121,7 @@ const char *with_thousand_seps (wgint); #else # define HR_NUMTYPE double #endif -char *human_readable (HR_NUMTYPE); +char *human_readable (HR_NUMTYPE, const int, const int); int numdigit (wgint); -- 1.9.3
