v2 / vlib / net / http / download_terminal_downloader.v
51 lines · 45 sloc · 1.84 KB · cdfc0bba9081099a0a6a62fcbbe7f364ba38231b
Raw
1module http
2
3import time
4
5// TerminalStreamingDownloader is the same as http.SilentStreamingDownloader, but produces a progress line on stdout.
6pub struct TerminalStreamingDownloader {
7 SilentStreamingDownloader
8mut:
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.
15pub 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.
22pub 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.
47pub fn (mut d TerminalStreamingDownloader) on_finish(request &Request, response &Response) ! {
48 d.SilentStreamingDownloader.on_finish(request, response)!
49 println('')
50 flush_stdout()
51}
52