| 1 | module http |
| 2 | |
| 3 | import time |
| 4 | |
| 5 | // TerminalStreamingDownloader is the same as http.SilentStreamingDownloader, but produces a progress line on stdout. |
| 6 | pub struct TerminalStreamingDownloader { |
| 7 | SilentStreamingDownloader |
| 8 | mut: |
| 9 | start_time time.Time |
| 10 | past_time time.Time |
| 11 | past_received u64 |
| 12 | } |
| 13 | |
| 14 | // on_start is called once at the start of the download. |
| 15 | pub fn (mut d TerminalStreamingDownloader) on_start(mut request Request, path string) ! { |
| 16 | d.SilentStreamingDownloader.on_start(mut request, path)! |
| 17 | d.start_time = time.now() |
| 18 | d.past_time = time.now() |
| 19 | } |
| 20 | |
| 21 | // on_chunk is called multiple times, once per chunk of received content. |
| 22 | pub fn (mut d TerminalStreamingDownloader) on_chunk(request &Request, chunk []u8, already_received u64, |
| 23 | expected u64) ! { |
| 24 | now := time.now() |
| 25 | elapsed := now - d.start_time |
| 26 | // delta_elapsed := now - d.past_time |
| 27 | // delta_bytes := already_received - d.past_received |
| 28 | d.past_time = now |
| 29 | d.past_received = already_received |
| 30 | ratio := f64(already_received) / f64(expected) |
| 31 | res := f64(elapsed) / ratio |
| 32 | mut estimated := time.Duration(max_i64) |
| 33 | if f64(min_i64) < res && res < f64(max_i64) { |
| 34 | estimated = i64(res) |
| 35 | } |
| 36 | speed := f64(time.millisecond) * f64(already_received) / f64(elapsed) |
| 37 | elapsed_s := elapsed.seconds() |
| 38 | estimated_s := estimated.seconds() |
| 39 | eta_s := f64_max(estimated_s - elapsed_s, 0.0) |
| 40 | |
| 41 | d.SilentStreamingDownloader.on_chunk(request, chunk, already_received, expected)! |
| 42 | print('\rDownloading to `${d.path}` ${100.0 * ratio:6.2f}%, ${f64(already_received) / (1024 * 1024):7.3f}/${f64(expected) / (1024 * 1024):-7.3f}MB, ${speed:6.0f}KB/s, elapsed: ${elapsed_s:6.0f}s, eta: ${eta_s:6.0f}s') |
| 43 | flush_stdout() |
| 44 | } |
| 45 | |
| 46 | // on_finish is called once at the end of the download. |
| 47 | pub fn (mut d TerminalStreamingDownloader) on_finish(request &Request, response &Response) ! { |
| 48 | d.SilentStreamingDownloader.on_finish(request, response)! |
| 49 | println('') |
| 50 | flush_stdout() |
| 51 | } |
| 52 | |