-
Notifications
You must be signed in to change notification settings - Fork 2
/
gitget.lua
135 lines (120 loc) · 5.23 KB
/
gitget.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
--[[ /gitget
GitHub downloading utility for CC.
Developed by apemanzilla.
This requires ElvishJerricco's JSON parsing API.
Direct link: http://pastebin.com/raw.php?i=4nRg9CHU
]]--
-- Edit these variables to use preset mode.
-- Whether to download the files asynchronously (huge speed benefits, will also retry failed files)
-- If false will download the files one by one and use the old output (List each file name as it's downloaded) instead of the progress bar
local async = true
-- Whether to write to the terminal as files are downloaded
-- Note that unless checked for this will not affect pre-set start/done code below
local silent = false
local preset = {
-- The GitHub account name
user = nil,
-- The GitHub repository name
repo = nil,
-- The branch or commit tree to download (defaults to 'master')
branch = nil,
-- The local folder to save all the files to (defaults to '/')
path = nil,
-- Function to run before starting the download
start = function()
if not silent then print("Downloading files from GitHub...") end
end,
-- Function to run when the download completes
done = function()
if not silent then print("Done") end
end
}
-- Leave the rest of the program alone.
local args = {...}
args[1] = preset.user or args[1]
args[2] = preset.repo or args[2]
args[3] = preset.branch or args[3] or "master"
args[4] = preset.path or args[4] or ""
if #args < 2 then
print("Usage:\n"..((shell and shell.getRunningProgram()) or "gitget").." <user> <repo> [branch/tree] [path]") error()
end
local function save(data,file)
local file = shell.resolve(file:gsub("%%20"," "))
if not (fs.exists(string.sub(file,1,#file - #fs.getName(file))) and fs.isDir(string.sub(file,1,#file - #fs.getName(file)))) then
if fs.exists(string.sub(file,1,#file - #fs.getName(file))) then fs.delete(string.sub(file,1,#file - #fs.getName(file))) end
fs.makeDir(string.sub(file,1,#file - #fs.getName(file)))
end
local f = fs.open(file,"w")
f.write(data)
f.close()
end
local function download(url, file)
save(http.get(url).readAll(),file)
end
if not json then
download("http://pastebin.com/raw.php?i=4nRg9CHU","json")
os.loadAPI("json")
end
preset.start()
local data = json.decode(http.get("https://api.github.com/repos/"..args[1].."/"..args[2].."/git/trees/"..args[3].."?recursive=1").readAll())
if data.message and data.message:find("API rate limit exceeded") then error("Out of API calls, try again later") end
if data.message and data.message == "Not found" then error("Invalid repository",2) else
for k,v in pairs(data.tree) do
-- Make directories
if v.type == "tree" then
fs.makeDir(fs.combine(args[4],v.path))
if not hide_progress then
end
end
end
local drawProgress
if async and not silent then
local _, y = term.getCursorPos()
local wide, _ = term.getSize()
term.setCursorPos(1, y)
term.write("[")
term.setCursorPos(wide - 6, y)
term.write("]")
drawProgress = function(done, max)
local value = done / max
term.setCursorPos(2,y)
term.write(("="):rep(math.floor(value * (wide - 8))))
local percent = math.floor(value * 100) .. "%"
term.setCursorPos(wide - percent:len(),y)
term.write(percent)
end
end
local filecount = 0
local downloaded = 0
local paths = {}
local failed = {}
for k,v in pairs(data.tree) do
-- Send all HTTP requests (async)
if v.type == "blob" then
v.path = v.path:gsub("%s","%%20")
local url = "https://raw.github.com/"..args[1].."/"..args[2].."/"..args[3].."/"..v.path,fs.combine(args[4],v.path)
if async then
http.request(url)
paths[url] = fs.combine(args[4],v.path)
filecount = filecount + 1
else
download(url, fs.combine(args[4], v.path))
if not silent then print(fs.combine(args[4], v.path)) end
end
end
end
while downloaded < filecount do
local e, a, b = os.pullEvent()
if e == "http_success" then
save(b.readAll(),paths[a])
downloaded = downloaded + 1
if not silent then drawProgress(downloaded,filecount) end
elseif e == "http_failure" then
-- Retry in 3 seconds
failed[os.startTimer(3)] = a
elseif e == "timer" and failed[a] then
http.request(failed[a])
end
end
end
preset.done()