aboutsummaryrefslogtreecommitdiff
path: root/etc
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2001-09-27 20:02:34 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2001-09-27 20:02:34 +0000
commite5e1f3dc7a750595bb3fbe219c369c3950220986 (patch)
treed5d2242b96c79a0b25434e8c80d3cf028ef3493d /etc
parent2f0754972219496fb0216c47522490cb4e4133ad (diff)
downloadluasocket-e5e1f3dc7a750595bb3fbe219c369c3950220986.tar.gz
luasocket-e5e1f3dc7a750595bb3fbe219c369c3950220986.tar.bz2
luasocket-e5e1f3dc7a750595bb3fbe219c369c3950220986.zip
Updated for LuaSocket 1.4
Prints a bunch of information during download.
Diffstat (limited to 'etc')
-rw-r--r--etc/get.lua151
1 files changed, 99 insertions, 52 deletions
diff --git a/etc/get.lua b/etc/get.lua
index 4a17cfc..13f983b 100644
--- a/etc/get.lua
+++ b/etc/get.lua
@@ -1,33 +1,73 @@
1assert(dofile("../lua/buffer.lua")) 1-- this examples needs it all
2assert(dofile("../lua/code.lua"))
2assert(dofile("../lua/ftp.lua")) 3assert(dofile("../lua/ftp.lua"))
3assert(dofile("../lua/base64.lua")) 4assert(dofile("../lua/concat.lua"))
5assert(dofile("../lua/url.lua"))
4assert(dofile("../lua/http.lua")) 6assert(dofile("../lua/http.lua"))
5 7
6-- format a number of bytes per second into a human readable form 8-- formats a number of seconds into human readable form
7function strbps(b) 9function nicetime(s)
8 local l = "B/s" 10 local l = "s"
11 if s > 60 then
12 s = s / 60
13 l = "m"
14 if s > 60 then
15 s = s / 60
16 l = "h"
17 if s > 24 then
18 s = s / 24
19 l = "d" -- hmmm
20 end
21 end
22 end
23 if l == "s" then return format("%2.0f%s", s, l)
24 else return format("%5.2f%s", s, l) end
25end
26
27-- formats a number of bytes into human readable form
28function nicesize(b)
29 local l = "B"
9 if b > 1024 then 30 if b > 1024 then
10 b = b / 1024 31 b = b / 1024
11 l = "KB/s" 32 l = "KB"
12 if b > 1024 then 33 if b > 1024 then
13 b = b / 1024 34 b = b / 1024
14 l = "MB/s" 35 l = "MB"
15 if b > 1024 then 36 if b > 1024 then
16 b = b / 1024 37 b = b / 1024
17 l = "GB/s" -- hmmm 38 l = "GB" -- hmmm
18 end 39 end
19 end 40 end
20 end 41 end
21 return format("%.2f%s ", b, l) 42 return format("%7.2f%2s", b, l)
43end
44
45-- returns a string with the current state of the download
46function gauge(got, dt, size)
47 local rate = got / dt
48 if size and size >= 1 then
49 return format("%s received, %s/s throughput, " ..
50 "%.0f%% done, %s remaining",
51 nicesize(got),
52 nicesize(rate),
53 100*got/size,
54 nicetime((size-got)/rate))
55 else
56 return format("%s received, %s/s throughput, %s elapsed",
57 nicesize(got),
58 nicesize(rate),
59 nicetime(dt))
60 end
22end 61end
23 62
24-- creates a new instance of a receive_cb that saves to disk 63-- creates a new instance of a receive_cb that saves to disk
25-- kind of copied from luasocket's manual callback examples 64-- kind of copied from luasocket's manual callback examples
26function receive2disk(file) 65function receive2disk(file, size)
27 local aux = { 66 local aux = {
28 start = _time(), 67 start = _time(),
29 got = 0, 68 got = 0,
30 file = openfile(file, "wb") 69 file = openfile(file, "wb"),
70 size = size
31 } 71 }
32 local receive_cb = function(chunk, err) 72 local receive_cb = function(chunk, err)
33 local dt = _time() - %aux.start -- elapsed time since start 73 local dt = _time() - %aux.start -- elapsed time since start
@@ -39,62 +79,69 @@ function receive2disk(file)
39 write(%aux.file, chunk) 79 write(%aux.file, chunk)
40 %aux.got = %aux.got + strlen(chunk) -- total bytes received 80 %aux.got = %aux.got + strlen(chunk) -- total bytes received
41 if dt < 0.1 then return 1 end -- not enough time for estimate 81 if dt < 0.1 then return 1 end -- not enough time for estimate
42 local rate = %aux.got / dt -- get download rate 82 write("\r", gauge(%aux.got, dt, %aux.size))
43 write("\r" .. strbps(rate)) -- print estimate
44 return 1 83 return 1
45 end 84 end
46 return receive_cb 85 return receive_cb
47end 86end
48 87
49-- stolen from http implementation 88-- downloads a file using the ftp protocol
50function split_url(url, default) 89function getbyftp(url, file)
51 -- initialize default parameters 90 local err = FTP.get_cb {
52 local parsed = default or {} 91 url = url,
53 -- get scheme 92 content_cb = receive2disk(file),
54 url = gsub(url, "^(.+)://", function (s) %parsed.scheme = s end) 93 type = "i"
55 -- get user name and password. both can be empty! 94 }
56 -- moreover, password can be ommited 95 print()
57 url = gsub(url, "^([^@:/]*)(:?)([^:@/]-)@", function (u, c, p) 96 if err then print(err) end
58 %parsed.user = u
59 -- there can be an empty password, but the ':' has to be there
60 -- or else there is no password
61 %parsed.pass = nil -- kill default password
62 if c == ":" then %parsed.pass = p end
63 end)
64 -- get host
65 url = gsub(url, "^([%w%.%-]+)", function (h) %parsed.host = h end)
66 -- get port if any
67 url = gsub(url, "^:(%d+)", function (p) %parsed.port = p end)
68 -- whatever is left is the path
69 if url ~= "" then parsed.path = url end
70 return parsed
71end 97end
72 98
73-- stolen from http implementation 99-- downloads a file using the http protocol
74function get_statuscode(line) 100function getbyhttp(url, file, size)
75 local _,_, code = strfind(line, " (%d%d%d) ") 101 local response = HTTP.request_cb(
76 return tonumber(code) 102 {url = url},
103 {body_cb = receive2disk(file, size)}
104 )
105 print()
106 if response.code ~= 200 then print(response.status or response.error) end
77end 107end
78 108
79function getbyftp(url, file) 109-- determines the size of a http file
80 local err = ftp_getindirect(url, receive2disk(file), "b") 110function gethttpsize(url)
81 if err then print(err) else print("done.") end 111 local response = HTTP.request {
112 method = "HEAD",
113 url = url
114 }
115 if response.code == 200 then
116 return tonumber(response.headers["content-length"])
117 end
82end 118end
83 119
84function getbyhttp(url, file) 120-- determines the scheme and the file name of a given url
85 local hdrs, line, err = http_getindirect(url, receive2disk(file)) 121function getschemeandname(url, name)
86 if line and get_statuscode(line) == 200 then print("done.") 122 -- this is an heuristic to solve a common invalid url poblem
87 elseif line then print(line) else print(err) end 123 if not strfind(url, "//") then url = "//" .. url end
124 local parsed = URL.parse_url(url, {scheme = "http"})
125 if name then return parsed.scheme, name end
126 local segment = URL.parse_path(parsed.path)
127 name = segment[getn(segment)]
128 if segment.is_directory then name = nil end
129 return parsed.scheme, name
88end 130end
89 131
90function get(url, file) 132-- gets a file either by http or url, saving as name
91 local parsed = split_url(url) 133function get(url, name)
92 if parsed.scheme == "ftp" then getbyftp(url, file) 134 local scheme
93 else getbyhttp(url, file) end 135 scheme, name = getschemeandname(url, name)
136 if not name then print("unknown file name")
137 elseif scheme == "ftp" then getbyftp(url, name)
138 elseif scheme == "http" then getbyhttp(url, name, gethttpsize(url))
139 else print("unknown scheme" .. scheme) end
94end 140end
95 141
142-- main program
96arg = arg or {} 143arg = arg or {}
97if getn(arg) < 2 then 144if getn(arg) < 1 then
98 write("Usage:\n luasocket -f get.lua <remote-url> <local-file>\n") 145 write("Usage:\n luasocket -f get.lua <remote-url> [<local-file>]\n")
99 exit(1) 146 exit(1)
100else get(arg[1], arg[2]) end 147else get(arg[1], arg[2]) end