cc-stuff/gitea-clone.lua

76 lines
1.9 KiB
Lua

local pretty = require("cc.pretty")
local args = { ... }
local instance, user, repo = args[1]:match("https?://([^/]+)/([^/]+)/([^/]+)")
local function getContents(path)
local url = "https://" .. instance .. "/api/v1/repos/" .. user .. "/" .. repo .. "/contents" .. (path and ("/" .. path) or "")
local res, err = http.get(url)
if not res then
printError(err)
return nil, err
end
return textutils.unserializeJSON(res:readAll())
end
local function walkRepository(basedir, callback)
local res, err = getContents(basedir)
if not res then
return nil, err
end
for _, elem in ipairs(res) do
if elem.type == "file" then
callback(elem.path, elem)
elseif elem.type == "dir" then
walkRepository(elem.path, callback)
else
printError("unknown type: " .. elem.type)
end
end
end
local function downloadFile(url, path)
local fp, err = io.open(path, "wb")
if not fp then
return nil, err
end
local rq
rq, err = http.get(url, nil, true)
if not rq then
return nil, err
end
local headers = rq.getResponseHeaders()
local length = tonumber(headers["Content-Length"]) or 1
local written = 0
local i = 0
local _, y = term.getCursorPos()
while true do
local chunk = rq.read(100)
if not chunk then break end
fp:write(chunk)
written = written + #chunk
term.setCursorPos(1, y)
term.clearLine()
local w = math.min(25, math.floor(written * 25 / length))
term.write("["..string.rep("=", w)..string.rep(" ", 25-w).."] ")
term.write(string.format("%7.3f%% %s", 100 * written / length, path))
i = i + 1
if (i % 20) == 0 then
sleep(0.1)
end
end
fp:close()
print()
end
walkRepository(nil, function(path, file)
downloadFile(file.download_url, repo.."-clone/"..path)
end)