1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

Add --show-progress to force display progress bar

This is a relatively large commit that implements two major features:

1. Implement --show-progress switch to force the display of the progress bar in
   any verbosity level
2. Edit the implementation of the progress bar so that the filename is displayed
   in the same line.
This commit is contained in:
Darshit Shah 2014-05-01 01:04:11 +02:00
parent 67a4c6cf97
commit 8c2fd06ba8
15 changed files with 140 additions and 46 deletions

4
NEWS
View File

@ -8,6 +8,10 @@ Please send GNU Wget bug reports to <bug-wget@gnu.org>.
* Changes in Wget X.Y.Z
** Default progress bar output changed
** Introduce --show-progress to force display the progress bar
** Introduce --no-config.
** Introduce --start-pos to allow starting downloads from a specified position.

View File

@ -1,3 +1,7 @@
2014-05-01 Darshit Shah <darnir@gmail.com>
* wget.texi: Add documentation for --show-progress
2014-02-10 Yousong Zhou <yszhou4tech@gmail.com>
* wget.texi: Add documentation for --start-pos.

View File

@ -751,6 +751,16 @@ command line. The exception is that, when the output is not a TTY, the
``dot'' progress will be favored over ``bar''. To force the bar output,
use @samp{--progress=bar:force}.
@item --show-progress
Force wget to display the progress bar in any verbosity.
By default, wget only displays the progress bar in verbose mode. One may
however want wget to display the progress bar on screen in conjunction with
any other verbosity modes like @samp{--no-verbose} or @samp{--quiet}. This
is often a desired a property when invoking wget to download several small/large
files. In such a case, wget could simply be invoked with this parameter to get
a much cleaner output on the screen.
@item -N
@itemx --timestamping
Turn on time-stamping. @xref{Time-Stamping}, for details.

View File

@ -1,3 +1,39 @@
2014-04-19 Darshit Shah <darnir@gmail.com>
* log.h (log_options): Add new logging options, LOG_PROGRESS. All progress
bar related output should use LOG_PROGRESS.
* log.c (CHECK_VERBOSE): Implement LOG_PROGRESS output
* progress.c (dot_create, print_row_stats, dot_update, dot_finish,
bar_finish, display_image): Output progress information through LOG_PROGRESS
(progress_implementation, dot_create, bar_create, progress_create): The
progress bar create functions accept an extra paramter for the filename of the
local file
(bar_progress): Add new variable to store filename of currently downloading
file
(bar_finish): Aesthetic change. Print two newlines if in verbose mode, else
only one.
(MACRO): Define new macro, MIN
(create_image): Implement displaying filename in progress bar output
Filename tick implementation copied from Giuseppe's patch on parallel-wget
* progress.h (progress_create): Accept another parameter for filename
* http.c (gethttp): Remove unnecessary conditional
(read_response_body): Send local filename to fd_read_body so that it can be
printed on the progress bar
* main.c (option_data): Add new switch, --show-progress
(main): If in verbose output, show progress bar by default
(main): Set progress implemetation when displaying progress bar
(no_prefix): Increase buffer size to 2048 to prevent overflows
* init.c (commands): Add new command, showprogress
(defaults): By default initialize show_progress to false
* options.h (options): Add new option, show_progress
* retr.c (fd_read_body): Accept new parameter for filename of currently
downlaoding file
(fd_read_body): Create and update progress bar when opt.show_progress is set
(fd_read_body): Display progress information in Windows console titlebars
* retr.h (fd_read_body): Update declaration
* ftp.c (getftp): Send filename of the local file so that it can be printed
with the progress bar.
2013-11-02 Giuseppe Scrivano <gscrivan@redhat.com>
* progress.c (struct progress_implementation): New method draw.
@ -9,7 +45,7 @@
2014-04-22 Tim Ruehsen <tim.ruehsen@gmx.de>
* http.c (gethttp): Fix 204 response handling
* http.c (gethttp): Fix 204 response handling
2014-03-26 Darshit Shah <darnir@gmail.com>

View File

@ -1310,7 +1310,7 @@ Error in server response, closing control connection.\n"));
if (restval && rest_failed)
flags |= rb_skip_startpos;
rd_size = 0;
res = fd_read_body (dtsock, fp,
res = fd_read_body (con->target, dtsock, fp,
expected_bytes ? expected_bytes - restval : 0,
restval, &rd_size, qtyread, &con->dltime, flags, warc_tmp);

View File

@ -1586,7 +1586,7 @@ read_response_body (struct http_stat *hs, int sock, FILE *fp, wgint contlen,
/* Download the response body and write it to fp.
If we are working on a WARC file, we simultaneously write the
response body to warc_tmp. */
hs->res = fd_read_body (sock, fp, contlen != -1 ? contlen : 0,
hs->res = fd_read_body (hs->local_file, sock, fp, contlen != -1 ? contlen : 0,
hs->restval, &hs->rd_size, &hs->len, &hs->dltime,
flags, warc_tmp);
if (hs->res >= 0)
@ -2961,11 +2961,8 @@ read_header:
fp = output_stream;
/* Print fetch message, if opt.verbose. */
if (opt.verbose)
{
logprintf (LOG_NOTQUIET, _("Saving to: %s\n"),
logprintf (LOG_VERBOSE, _("Saving to: %s\n"),
HYPHENP (hs->local_file) ? quote ("STDOUT") : quote (hs->local_file));
}
err = read_response_body (hs, sock, fp, contlen, contrange,

View File

@ -268,6 +268,7 @@ static const struct {
#endif
{ "serverresponse", &opt.server_response, cmd_boolean },
{ "showalldnsentries", &opt.show_all_dns_entries, cmd_boolean },
{ "showprogress", &opt.show_progress, cmd_boolean },
{ "spanhosts", &opt.spanhost, cmd_boolean },
{ "spider", &opt.spider, cmd_boolean },
{ "startpos", &opt.start_pos, cmd_bytes },
@ -410,6 +411,7 @@ defaults (void)
/* Use a negative value to mark the absence of --start-pos option */
opt.start_pos = -1;
opt.show_progress = false;
}
/* Return the user's home directory (strdup-ed), or NULL if none is

View File

@ -278,6 +278,10 @@ saved_append (const char *s)
#define CHECK_VERBOSE(x) \
switch (x) \
{ \
case LOG_PROGRESS: \
if (!opt.show_progress) \
return; \
break; \
case LOG_ALWAYS: \
break; \
case LOG_NOTQUIET: \

View File

@ -36,7 +36,7 @@ as that of the covered work. */
#include <stdio.h>
enum log_options { LOG_VERBOSE, LOG_NOTQUIET, LOG_NONVERBOSE, LOG_ALWAYS };
enum log_options { LOG_VERBOSE, LOG_NOTQUIET, LOG_NONVERBOSE, LOG_ALWAYS, LOG_PROGRESS };
void log_set_warc_log_fp (FILE *);

View File

@ -247,6 +247,7 @@ static struct cmdline_option option_data[] =
{ IF_SSL ("private-key"), 0, OPT_VALUE, "privatekey", -1 },
{ IF_SSL ("private-key-type"), 0, OPT_VALUE, "privatekeytype", -1 },
{ "progress", 0, OPT_VALUE, "progress", -1 },
{ "show-progress", 0, OPT_BOOLEAN, "showprogress", -1 },
{ "protocol-directories", 0, OPT_BOOLEAN, "protocoldirectories", -1 },
{ "proxy", 0, OPT_BOOLEAN, "useproxy", -1 },
{ "proxy__compat", 'Y', OPT_VALUE, "useproxy", -1 }, /* back-compatible */
@ -316,7 +317,7 @@ static struct cmdline_option option_data[] =
static char *
no_prefix (const char *s)
{
static char buffer[1024];
static char buffer[2048];
static char *p = buffer;
char *cp = p;
@ -490,6 +491,8 @@ Download:\n"),
--start-pos=OFFSET start downloading from zero-based position OFFSET.\n"),
N_("\
--progress=TYPE select progress gauge type.\n"),
N_("\
--show-progress display the progress bar in any verbosity mode.\n"),
N_("\
-N, --timestamping don't re-retrieve files unless newer than\n\
local.\n"),
@ -1218,6 +1221,7 @@ main (int argc, char **argv)
/* All user options have now been processed, so it's now safe to do
interoption dependency checks. */
if (opt.noclobber && opt.convert_links)
{
fprintf (stderr,
@ -1245,6 +1249,8 @@ main (int argc, char **argv)
if (opt.verbose == -1)
opt.verbose = !opt.quiet;
if (opt.verbose == 1)
opt.show_progress = true;
/* Sanity checks. */
if (opt.verbose && opt.quiet)
@ -1502,7 +1508,7 @@ for details.\n\n"));
/* Initialize progress. Have to do this after the options are
processed so we know where the log file is. */
if (opt.verbose)
if (opt.show_progress)
set_progress_implementation (opt.progress_type);
/* Fill in the arguments. */

View File

@ -134,6 +134,7 @@ struct options
char **no_proxy;
char *base_href;
char *progress_type; /* progress indicator type. */
bool show_progress; /* Show only the progress bar */
char *proxy_user; /*oli*/
char *proxy_passwd;

View File

@ -47,7 +47,7 @@ as that of the covered work. */
struct progress_implementation {
const char *name;
bool interactive;
void *(*create) (wgint, wgint);
void *(*create) (const char *, wgint, wgint);
void (*update) (void *, wgint, double);
void (*draw) (void *);
void (*finish) (void *, double);
@ -56,13 +56,13 @@ struct progress_implementation {
/* Necessary forward declarations. */
static void *dot_create (wgint, wgint);
static void *dot_create (const char *, wgint, wgint);
static void dot_update (void *, wgint, double);
static void dot_finish (void *, double);
static void dot_draw (void *);
static void dot_set_params (const char *);
static void *bar_create (wgint, wgint);
static void *bar_create (const char *, wgint, wgint);
static void bar_update (void *, wgint, double);
static void bar_draw (void *);
static void bar_finish (void *, double);
@ -154,7 +154,7 @@ progress_schedule_redirect (void)
advance. */
void *
progress_create (wgint initial, wgint total)
progress_create (const char *f_download, wgint initial, wgint total)
{
/* Check if the log status has changed under our feet. */
if (output_redirected)
@ -164,7 +164,7 @@ progress_create (wgint initial, wgint total)
output_redirected = 0;
}
return current_impl->create (initial, total);
return current_impl->create (f_download, initial, total);
}
/* Return true if the progress gauge is "interactive", i.e. if it can
@ -218,7 +218,7 @@ struct dot_progress {
/* Dot-progress backend for progress_create. */
static void *
dot_create (wgint initial, wgint total)
dot_create (const char *f_download _GL_UNUSED, wgint initial, wgint total)
{
struct dot_progress *dp = xnew0 (struct dot_progress);
dp->initial_length = initial;
@ -242,18 +242,18 @@ dot_create (wgint initial, wgint total)
/* Align the [ skipping ... ] line with the dots. To do
that, insert the number of spaces equal to the number of
digits in the skipped amount in K. */
logprintf (LOG_VERBOSE, _("\n%*s[ skipping %sK ]"),
logprintf (LOG_PROGRESS, _("\n%*s[ skipping %sK ]"),
2 + skipped_k_len, "",
number_to_static_string (skipped_k));
}
logprintf (LOG_VERBOSE, "\n%6sK",
logprintf (LOG_PROGRESS, "\n%6sK",
number_to_static_string (skipped / 1024));
for (; remainder >= dot_bytes; remainder -= dot_bytes)
{
if (dp->dots % opt.dot_spacing == 0)
logputs (LOG_VERBOSE, " ");
logputs (LOG_VERBOSE, ",");
logputs (LOG_PROGRESS, " ");
logputs (LOG_PROGRESS, ",");
++dp->dots;
}
assert (dp->dots < opt.dots_in_line);
@ -294,7 +294,7 @@ print_row_stats (struct dot_progress *dp, double dltime, bool last)
been retrieved. 12.8% will round to 12% because the 13% mark
has not yet been reached. 100% is only shown when done. */
int percentage = 100.0 * bytes_displayed / dp->total_length;
logprintf (LOG_VERBOSE, "%3d%%", percentage);
logprintf (LOG_PROGRESS, "%3d%%", percentage);
}
{
@ -311,7 +311,7 @@ print_row_stats (struct dot_progress *dp, double dltime, bool last)
if (dp->rows == dp->initial_length / ROW_BYTES)
bytes_this_row -= dp->initial_length % ROW_BYTES;
rate = calc_rate (bytes_this_row, dltime - dp->last_timer_value, &units);
logprintf (LOG_VERBOSE, " %4.*f%c",
logprintf (LOG_PROGRESS, " %4.*f%c",
rate >= 99.95 ? 0 : rate >= 9.995 ? 1 : 2,
rate, names[units]);
dp->last_timer_value = dltime;
@ -328,7 +328,7 @@ print_row_stats (struct dot_progress *dp, double dltime, bool last)
wgint bytes_sofar = bytes_displayed - dp->initial_length;
double eta = dltime * bytes_remaining / bytes_sofar;
if (eta < INT_MAX - 1)
logprintf (LOG_VERBOSE, " %s",
logprintf (LOG_PROGRESS, " %s",
eta_to_human_short ((int) (eta + 0.5), true));
}
}
@ -336,10 +336,10 @@ print_row_stats (struct dot_progress *dp, double dltime, bool last)
{
/* When done, print the total download time */
if (dltime >= 10)
logprintf (LOG_VERBOSE, "=%s",
logprintf (LOG_PROGRESS, "=%s",
eta_to_human_short ((int) (dltime + 0.5), true));
else
logprintf (LOG_VERBOSE, "=%ss", print_decimal (dltime));
logprintf (LOG_PROGRESS, "=%ss", print_decimal (dltime));
}
}
@ -365,12 +365,12 @@ dot_draw (void *progress)
for (; dp->accumulated >= dot_bytes; dp->accumulated -= dot_bytes)
{
if (dp->dots == 0)
logprintf (LOG_VERBOSE, "\n%6sK",
logprintf (LOG_PROGRESS, "\n%6sK",
number_to_static_string (dp->rows * ROW_BYTES / 1024));
if (dp->dots % opt.dot_spacing == 0)
logputs (LOG_VERBOSE, " ");
logputs (LOG_VERBOSE, ".");
logputs (LOG_PROGRESS, " ");
logputs (LOG_PROGRESS, ".");
++dp->dots;
if (dp->dots >= opt.dots_in_line)
@ -397,17 +397,17 @@ dot_finish (void *progress, double dltime)
log_set_flush (false);
if (dp->dots == 0)
logprintf (LOG_VERBOSE, "\n%6sK",
logprintf (LOG_PROGRESS, "\n%6sK",
number_to_static_string (dp->rows * ROW_BYTES / 1024));
for (i = dp->dots; i < opt.dots_in_line; i++)
{
if (i % opt.dot_spacing == 0)
logputs (LOG_VERBOSE, " ");
logputs (LOG_VERBOSE, " ");
logputs (LOG_PROGRESS, " ");
logputs (LOG_PROGRESS, " ");
}
print_row_stats (dp, dltime, true);
logputs (LOG_VERBOSE, "\n\n");
logputs (LOG_PROGRESS, "\n\n");
log_set_flush (false);
xfree (dp);
@ -507,6 +507,7 @@ static volatile sig_atomic_t received_sigwinch;
#define ETA_REFRESH_INTERVAL 0.99
struct bar_progress {
const char *f_download; /* Filename of the downloaded file */
wgint initial_length; /* how many bytes have been downloaded
previously. */
wgint total_length; /* expected total byte count when the
@ -564,7 +565,7 @@ static void create_image (struct bar_progress *, double, bool);
static void display_image (char *);
static void *
bar_create (wgint initial, wgint total)
bar_create (const char *f_download, wgint initial, wgint total)
{
struct bar_progress *bp = xnew0 (struct bar_progress);
@ -575,6 +576,7 @@ bar_create (wgint initial, wgint total)
bp->initial_length = initial;
bp->total_length = total;
bp->f_download = f_download;
/* Initialize screen_width if this hasn't been done or if it might
have changed, as indicated by receiving SIGWINCH. */
@ -670,7 +672,8 @@ bar_finish (void *progress, double dltime)
create_image (bp, dltime, true);
display_image (bp->buffer);
logputs (LOG_VERBOSE, "\n\n");
logputs (LOG_VERBOSE, "\n");
logputs (LOG_PROGRESS, "\n");
xfree (bp->buffer);
xfree (bp);
@ -865,10 +868,14 @@ get_eta (int *bcd)
#ifndef MAX
# define MAX(a, b) ((a) >= (b) ? (a) : (b))
#endif
#ifndef MIN
# define MIN(a, b) ((a) <= (b) ? (a) : (b))
#endif
static void
create_image (struct bar_progress *bp, double dl_total_time, bool done)
{
const int MAX_FILENAME_LEN = bp->width / 3;
char *p = bp->buffer;
wgint size = bp->initial_length + bp->count;
@ -879,9 +886,11 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
int size_grouped_pad; /* Used to pad the field width for size_grouped. */
struct bar_progress_hist *hist = &bp->hist;
int orig_filename_len = strlen (bp->f_download);
int filename_len = MIN (orig_filename_len, MAX_FILENAME_LEN);
/* The progress bar should look like this:
xx% [=======> ] nn,nnn 12.34KB/s eta 36m 51s
file xx% [=======> ] nn,nnn 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
@ -890,16 +899,17 @@ 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
"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
" 12.5KB/s" - download rate - 9 chars
" eta 36m 51s" - ETA - 14 chars
"=====>..." - progress bar - the rest
*/
int dlbytes_size = 1 + MAX (size_grouped_len, 11);
int progress_size = bp->width - (4 + 2 + dlbytes_size + 8 + 14);
int progress_size = bp->width - (filename_len + 1 + 4 + 2 + dlbytes_size + 8 + 14);
/* The difference between the number of bytes used,
and the number of columns used. */
@ -908,6 +918,25 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
if (progress_size < 5)
progress_size = 0;
if (orig_filename_len <= MAX_FILENAME_LEN)
{
sprintf (p, "%s ", bp->f_download);
p += filename_len + 1;
}
else
{
int offset;
if (orig_filename_len > MAX_FILENAME_LEN)
offset = ((int) bp->tick) % (orig_filename_len - MAX_FILENAME_LEN);
else
offset = 0;
*p++ = ' ';
memcpy (p, bp->f_download + offset, MAX_FILENAME_LEN);
p += MAX_FILENAME_LEN;
*p++ = ' ';
}
/* "xx% " */
if (bp->total_length > 0)
{
@ -981,8 +1010,8 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
}
*p++ = ']';
++bp->tick;
}
++bp->tick;
/* " 234,567,890" */
sprintf (p, " %s", size_grouped);
@ -1090,8 +1119,8 @@ static void
display_image (char *buf)
{
bool old = log_set_save_context (false);
logputs (LOG_VERBOSE, "\r");
logputs (LOG_VERBOSE, buf);
logputs (LOG_PROGRESS, "\r");
logputs (LOG_PROGRESS, buf);
log_set_save_context (old);
}

View File

@ -35,7 +35,7 @@ bool valid_progress_implementation_p (const char *);
void set_progress_implementation (const char *);
void progress_schedule_redirect (void);
void *progress_create (wgint, wgint);
void *progress_create (const char *, wgint, wgint);
bool progress_interactive_p (void *);
void progress_update (void *, wgint, double);
void progress_finish (void *, double);

View File

@ -226,7 +226,8 @@ write_data (FILE *out, FILE *out2, const char *buf, int bufsize,
data to OUT2, -3 is returned. */
int
fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread, wgint startpos,
wgint *qtyread, wgint *qtywritten, double *elapsed, int flags,
FILE *out2)
{
@ -262,13 +263,13 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
if (flags & rb_skip_startpos)
skip = startpos;
if (opt.verbose)
if (opt.show_progress)
{
/* If we're skipping STARTPOS bytes, pass 0 as the INITIAL
argument to progress_create because the indicator doesn't
(yet) know about "skipping" data. */
wgint start = skip ? 0 : startpos;
progress = progress_create (start, start + toread);
progress = progress_create (downloaded_filename, start, start + toread);
progress_interactive = progress_interactive_p (progress);
}
@ -411,7 +412,7 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
if (progress)
progress_update (progress, ret, ptimer_read (timer));
#ifdef WINDOWS
if (toread > 0 && !opt.quiet)
if (toread > 0 && opt.show_progress)
ws_percenttitle (100.0 *
(startpos + sum_read) / (startpos + toread));
#endif

View File

@ -50,7 +50,7 @@ enum {
rb_chunked_transfer_encoding = 4
};
int fd_read_body (int, FILE *, wgint, wgint, wgint *, wgint *, double *, int, FILE *);
int fd_read_body (const char *, int, FILE *, wgint, wgint, wgint *, wgint *, double *, int, FILE *);
typedef const char *(*hunk_terminator_t) (const char *, const char *, int);