Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/htsback.c
Original file line number Diff line number Diff line change
Expand Up @@ -3840,10 +3840,10 @@ void back_wait(struct_back * sback, httrackp * opt, cache_back * cache,
if (opt->verbosedisplay == 1) {
if (back[i].status == STATUS_READY) {
if (back[i].r.statuscode == HTTP_OK)
printf("* %s%s (" LLintP " bytes) - OK" VT_CLREOL "\r",
printf("\r* %s%s (" LLintP " bytes) - OK" VT_CLREOL "\n",
back[i].url_adr, back[i].url_fil, (LLint) back[i].r.size);
else
printf("* %s%s (" LLintP " bytes) - %d" VT_CLREOL "\r",
printf("\r* %s%s (" LLintP " bytes) - %d" VT_CLREOL "\n",
back[i].url_adr, back[i].url_fil, (LLint) back[i].r.size,
back[i].r.statuscode);
fflush(stdout);
Expand Down
4 changes: 2 additions & 2 deletions src/htsparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -4361,10 +4361,10 @@ int hts_mirror_wait_for_next_file(htsmoduleStruct * str,
} else if (opt->verbosedisplay == 1) {
if (b >= 0) {
if (back[b].r.statuscode == HTTP_OK)
printf("%d/%d: %s%s (" LLintP " bytes) - OK\33[K\r", ptr, opt->lien_tot,
printf("\r%d/%d: %s%s (" LLintP " bytes) - OK\33[K\n", ptr, opt->lien_tot,
back[b].url_adr, back[b].url_fil, (LLint) back[b].r.size);
else
printf("%d/%d: %s%s (" LLintP " bytes) - %d\33[K\r", ptr, opt->lien_tot,
printf("\r%d/%d: %s%s (" LLintP " bytes) - %d\33[K\n", ptr, opt->lien_tot,
back[b].url_adr, back[b].url_fil, (LLint) back[b].r.size,
back[b].r.statuscode);
} else {
Expand Down
102 changes: 101 additions & 1 deletion src/httrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,99 @@ int main(int argc, char **argv) {
return ret;
}

static int print_progress_bar(int lien_n, int lien_tot, int stat_time, hts_stat_struct *stats) {
static TStamp last_update = 0;
static int finished = 0;
static int last_lien_n = -1;
TStamp now = mtime_local();
int force_update;

if (lien_n < lien_tot) {
finished = 0;
}
if (finished) {
return 1;
}

/* Force update if a new file has finished downloading (lien_n changed) */
force_update = (lien_n != last_lien_n);
last_lien_n = lien_n;

/* Throttling: update the screen only every 200ms to reduce CPU overhead. */
/* Force update when the mirror finishes (when lien_n == lien_tot) or a file finishes. */
if (last_update == 0 || (now - last_update) >= 200 || (lien_n == lien_tot && lien_tot > 0) || force_update) {
double percent = 0.0;
int bar_width = 20;
int filled = 0;
int i;
char bar_str[24]; /* 20 + '>' + intermediate stages + \0 */
double speed_kbs = 0.0;
char eta_str[32];

last_update = now;
strcpybuff(eta_str, "unknown");

/* Visual progress bar calculation */
memset(bar_str, ' ', bar_width);
bar_str[bar_width] = '\0';

if (lien_tot > 0) {
percent = ((double)lien_n / lien_tot) * 100.0;
if (percent > 100.0)
percent = 100.0; /* Fail-safe if lien_tot fluctuates downwards */

filled = (int)((percent / 100.0) * bar_width);
for (i = 0; i < filled; i++) {
bar_str[i] = '=';
}
if (filled < bar_width) {
bar_str[filled] = '>';
}
}

/* Calculate download speed (KB/s) */
if (stat_time > 0 && stats != NULL) {
speed_kbs = (double)(stats->HTS_TOTAL_RECV / 1024.0) / stat_time;
}

/* Calculate ETA (Estimated Time of Arrival) */
if (lien_n > 0 && lien_tot > lien_n && stat_time > 0) {
/* Simple linear calculation: avg_time_per_link * remaining_links */
double time_per_link = (double)stat_time / lien_n;
int links_remaining = lien_tot - lien_n;
TStamp eta_seconds = (TStamp)(time_per_link * links_remaining);

if (eta_seconds > 0) {
int eta_m = (int)(eta_seconds / 60);
int eta_s = (int)(eta_seconds % 60);
if (eta_m > 0) {
snprintf(eta_str, sizeof(eta_str), "%dm %ds", eta_m, eta_s);
} else {
snprintf(eta_str, sizeof(eta_str), "%ds", eta_s);
}
}
} else if (lien_tot == 0) {
strcpybuff(eta_str, "calculating...");
} else if (lien_n == lien_tot) {
strcpybuff(eta_str, "0s");
}

/* Print on the same line using \r, and clear to end of line to prevent trailing chars */
printf("\r[%s] %.1f%% | %d/%d links | DL: %.1f KB/s | ETA: %s ", bar_str,
percent, lien_n, lien_tot, speed_kbs, eta_str);

if (lien_n == lien_tot && lien_tot > 0) {
finished = 1;
printf("\n");
}

/* Flush output explicitly since we don't write a newline character */
fflush(stdout);
}

return 1;
}

/* CALLBACK FUNCTIONS */

/* Initialize the Winsock */
Expand All @@ -298,6 +391,9 @@ static int __cdecl htsshow_chopt(t_hts_callbackarg * carg, httrackp * opt) {
return htsshow_start(carg, opt);
}
static int __cdecl htsshow_end(t_hts_callbackarg * carg, httrackp * opt) {
if (opt->verbosedisplay == 1) {
print_progress_bar(opt->lien_tot, opt->lien_tot, (int)(time(NULL) - HTS_STAT.stat_timestart), &HTS_STAT);
}
return 1;
}
static int __cdecl htsshow_preprocesshtml(t_hts_callbackarg * carg,
Expand Down Expand Up @@ -352,8 +448,12 @@ static int __cdecl htsshow_loop(t_hts_callbackarg * carg, httrackp * opt, lien_b
stat_bytes_recv = stats->HTS_TOTAL_RECV;
}

if (!use_show)
if (!use_show) {
if (opt->verbosedisplay == 1) {
print_progress_bar(lien_n, lien_tot, stat_time, stats);
}
return 1;
}

mytime = mtime_local();
if ((stat_time > 0) && (stat_bytes_recv > 0))
Expand Down
Loading