Skip to content

Instantly share code, notes, and snippets.

@SammyForReal
Created March 27, 2023 15:46
Show Gist options
  • Save SammyForReal/01030352dc530dee82416900678523c1 to your computer and use it in GitHub Desktop.
Save SammyForReal/01030352dc530dee82416900678523c1 to your computer and use it in GitHub Desktop.
download GitHub Repos in CraftOS
--[[
Title: downloadGitHubRepo
Author: Kristify Team
Licence: MIT Licence (for more details: https://mit-license.org/)
Version: 1.0
]]
--Configuration------------------------------------
local bSilent = false
local sDestination = "kristify"
local bClearDestination = false -- Removes the content of the selected folder
local tURLs = {}
tURLs.owner = "Kristify"
tURLs.repo = "kristify"
tURLs.branch = "main"
-- Files that should not be downloaded, determined by the name
local tFilter = {
{"start", "."},
{"end", ".md"},
{"exact", "installer.lua"},
{"exact", "docs"},
{"any", "basalt"}
}
--[[Dont-change!---------------------------------]]
local authenticate = _G._GIT_API_KEY and {Authorization = "Bearer ".._G._GIT_API_KEY} -- Some servers provide a git api key
tURLs.tree = "https://api.github.com/repos/"..tURLs.owner.."/"..tURLs.repo.."/contents/?ref="..tURLs.branch
tURLs.infos = "https://api.github.com/repos/"..tURLs.owner.."/"..tURLs.repo
--[[Printing-Stuff-------------------------------]]
local function addLine(str)
if bSilent then return end
term.clearLine()
print(str)
end
--[[Actual-Download-Code-------------------------]]
local function httpError(response,err,errResponse)
if not response then
addLine("Request to GitHub denied; Reason: \'.."..err.."..\' (code "..errResponse.getResponseCode()..").")
return false
end
return true
end
local function getJSON(response)
if not response then return {} end
local tData = response.readAll()
response.close()
return textutils.unserialiseJSON(tData) -- I hate the textutils API but its the best we have without additional steps
end
local function checkFilter(sName, filter)
if filter[1] == "any"
and sName:find(filter[2]) then
return true
elseif filter[1] == "start"
and sName:sub(1, #filter[2]) == filter[2] then
return true
elseif filter[1] == "end"
and sName:sub(-#filter[2]) == filter[2] then
return true
elseif filter[1] == "eact"
and sName == filter[2] then
return true
end
return false
end
local function generateTree(sURL)
sURL = sURL or tURLs.tree
local function convertItem(item)
if item.type == "file" then
return item.name, item.download_url
elseif item.type == "dir" then
return item.name, generateTree(item.url)
end
end
local response,sErr,errResponse = http.get(sURL, authenticate)
httpError(response,sErr,errResponse)
local tData = getJSON(response)
local tTree = { }
for _,v in pairs(tData) do
local sName,tItem = convertItem(v)
-- Filter stuff that is not needed
local bAllowed = true
for _,filter in ipairs(tFilter) do
if not checkFilter(sName, filter) then
bAllowed = false
break
end
end
if bAllowed then
tTree[sName] = tItem
end
end
return tTree
end
local function downloadBlob(sURL, sPath)
local response,sErr,errResponse = http.get(sURL, authenticate)
if not httpError(response,sErr,errResponse) then
return false
end
local sData = response.readAll()
response.close()
local file = fs.open(sPath, 'w')
file.write(sData)
file.close()
return true
end
local function downloadItems(tree, sPath)
for name, item in pairs(tree) do
local nextPath = fs.combine(sPath, name)
if type(item) == "table" then
downloadItems(item, nextPath)
else
if downloadBlob(item, nextPath) then
addLine("\025 "..name.." -> "..sPath)
end
end
end
end
---Downloads a whole GitHub repository into a given destination location.
---@return boolean result Whenever it was successfull or not.
local function downloadGitHubRepo()
addLine("Create folder..")
if bClearDestination and not fs.isReadOnly(sDestination) then
fs.delete(sDestination)
end
if not fs.exists(sDestination) then
fs.makeDir(sDestination)
end
addLine("Generating tree..")
local tree = generateTree()
local function listItems(tree, depth)
local size = 0
for _, _ in pairs(tree) do size = size + 1 end
local index = 1
for name, item in pairs(tree) do
local begin = " " .. ("\149 "):rep(depth - 1) .. (index >= size and '\141' or '\157'):rep(depth - (depth - 1)) ..
' '
addLine(begin .. name)
if type(item) == "table" then
listItems(item, depth + 1)
end
index = index + 1
end
end
listItems(tree, 1)
addLine("Download files..")
downloadItems(tree, sDestination)
return true
end
print( "Success: "..(downloadGitHubRepo() and "TRUE" or "FALSE") )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment