diff --git a/src/htsback.c b/src/htsback.c index e98494b2..6fc61dce 100644 --- a/src/htsback.c +++ b/src/htsback.c @@ -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); diff --git a/src/htsparse.c b/src/htsparse.c index 41f6adbd..b0d306d3 100644 --- a/src/htsparse.c +++ b/src/htsparse.c @@ -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 { diff --git a/src/httrack.c b/src/httrack.c index 798ecbdb..d1591269 100644 --- a/src/httrack.c +++ b/src/httrack.c @@ -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 */ @@ -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, @@ -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))