Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --JSON functions
- --Credit goes to http://www.computercraft.info/forums2/index.php?/topic/5854-json-api-v201-for-computercraft/
- ------------------------------------------------------------------ utils
- local controls = {["\n"]="\\n", ["\r"]="\\r", ["\t"]="\\t", ["\b"]="\\b", ["\f"]="\\f", ["\""]="\\\"", ["\\"]="\\\\"}
- local whites = {['\n']=true; ['r']=true; ['\t']=true; [' ']=true; [',']=true; [':']=true}
- function removeWhite(str)
- while whites[str:sub(1, 1)] do
- str = str:sub(2)
- end
- return str
- end
- ------------------------------------------------------------------ decoding
- function jsonParseBoolean(str)
- if str:sub(1, 4) == "true" then
- return true, removeWhite(str:sub(5))
- else
- return false, removeWhite(str:sub(6))
- end
- end
- function jsonParseNull(str)
- return nil, removeWhite(str:sub(5))
- end
- local numChars = {['e']=true; ['E']=true; ['+']=true; ['-']=true; ['.']=true}
- function jsonParseNumber(str)
- local i = 1
- while numChars[str:sub(i, i)] or tonumber(str:sub(i, i)) do
- i = i + 1
- end
- local val = tonumber(str:sub(1, i - 1))
- str = removeWhite(str:sub(i))
- return val, str
- end
- function jsonParseString(str)
- local i,j = str:find('^".-[^\\]"')
- local s = str:sub(i + 1,j - 1)
- for k,v in pairs(controls) do
- s = s:gsub(v, k)
- end
- str = removeWhite(str:sub(j + 1))
- return s, str
- end
- function jsonParseArray(str)
- str = removeWhite(str:sub(2))
- local val = {}
- local i = 1
- while str:sub(1, 1) ~= "]" do
- local v = nil
- v, str = jsonParseValue(str)
- val[i] = v
- i = i + 1
- str = removeWhite(str)
- end
- str = removeWhite(str:sub(2))
- return val, str
- end
- function jsonParseObject(str)
- str = removeWhite(str:sub(2))
- local val = {}
- while str:sub(1, 1) ~= "}" do
- local k, v = nil, nil
- k, v, str = jsonParseMember(str)
- val[k] = v
- str = removeWhite(str)
- end
- str = removeWhite(str:sub(2))
- return val, str
- end
- function jsonParseMember(str)
- local k = nil
- k, str = jsonParseValue(str)
- local val = nil
- val, str = jsonParseValue(str)
- return k, val, str
- end
- function jsonParseValue(str)
- local fchar = str:sub(1, 1)
- if fchar == "{" then
- return jsonParseObject(str)
- elseif fchar == "[" then
- return jsonParseArray(str)
- elseif tonumber(fchar) ~= nil or numChars[fchar] then
- return jsonParseNumber(str)
- elseif str:sub(1, 4) == "true" or str:sub(1, 5) == "false" then
- return jsonParseBoolean(str)
- elseif fchar == "\"" then
- return jsonParseString(str)
- elseif str:sub(1, 4) == "null" then
- return jsonParseNull(str)
- end
- return nil
- end
- function jsonDecode(str)
- str = removeWhite(str)
- t = jsonParseValue(str)
- return t
- end
- function downloadJson(url)
- local file = http.get(url)
- if not file then
- return nil
- end
- return jsonDecode(file.readAll())
- end
- local GitHubRepo = "Yevano/see" -- Change to user/repo
- local GitHubBranch = "master" -- Change to needed branch
- local installPath = "/see/"
- local GitHubRef = "refs/heads/"..GitHubBranch
- local GitHubRaw = 'https://raw.github.com/'..GitHubRepo..'/'..GitHubBranch..'/'
- local args = {...}
- local blacklist = {
- '.gitignore',
- 'README.md'
- }
- function isBlacklisted(path)
- for i, item in ipairs(blacklist) do
- if item == path then
- return true
- end
- end
- return false
- end
- local failed = {}
- function downloadBlob(v)
- if isBlacklisted(v.path) then
- return
- end
- --Make dir if needed
- if v.type == 'tree' then
- fs.makeDir(installPath..v.path)
- else
- --Start download
- local url = (GitHubRaw..v.path):gsub(' ','%%20')
- local f = http.get(url)
- --If couldn't download then add to failed
- if not f then
- table.insert(failed,v)
- return
- end
- --Write file
- local h = fs.open(installPath..v.path, 'w')
- h.write(f.readAll())
- h.close()
- end
- end
- local function fail(err)
- printError(err)
- while true do
- write("Retry installation? (y/n): ")
- local response = read()
- if string.lower(response):gsub("%s", "") == "y" then
- return true
- elseif string.lower(response):gsub("%s", "") == "n" then
- return false
- end
- print("Invalid input.")
- end
- end
- --Get install directory
- while true do
- if #args == 1 then
- installPath = args[1]
- else
- write("Choose an install path: ")
- installPath = "/" .. shell.resolve(read())
- end
- local configHandle = fs.open("/.see", "w")
- configHandle.write('install_dir = "' .. installPath .. '/see"')
- configHandle.close()
- local suc, err = pcall(fs.makeDir, installPath)
- if not suc then
- if not fail("Could not create installation directory.") then error("Exiting") end
- else
- break
- end
- end
- installPath = installPath .. '/'
- local tree = {}
- local latestSha = ''
- --Get latest commit
- while true do
- --Get sha for specific branch
- local refs = downloadJson('https://api.github.com/repos/'..GitHubRepo..'/git/refs')
- if refs == nil then
- if not fail("Could not fetch branches") then error("Exiting") end
- else
- for i, v in ipairs(refs) do
- if v.ref == GitHubRef then
- latestSha = v.object.sha
- break
- end
- end
- break
- end
- end
- --Get tree
- while true do
- --Download file list
- tree = downloadJson('https://api.github.com/repos/'..GitHubRepo..'/git/trees/'..latestSha..'?recursive=1').tree
- if tree == nil then
- if not fail("Could not fetch tree") then error("Exiting") end
- else
- break
- end
- end
- --Prepare file download
- local downloads = {}
- for i, v in ipairs(tree) do
- table.insert(downloads, function()downloadBlob(v)end)
- end
- while true do
- parallel.waitForAll(unpack(downloads))
- if #failed > 0 then
- if not fail("Not all files downloaded. Retry?") then error("Exiting") end
- downloads = {}
- for i, v in ipairs(failed) do
- print("Retrying "..v.path)
- table.insert(downloads, function()downloadBlob(v)end)
- end
- failed = {}
- else
- break
- end
- end
Add Comment
Please, Sign In to add comment