Yevano

SEE Installer

Aug 17th, 2013
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.77 KB | None | 0 0
  1. --JSON functions
  2.  
  3. --Credit goes to http://www.computercraft.info/forums2/index.php?/topic/5854-json-api-v201-for-computercraft/
  4. ------------------------------------------------------------------ utils
  5. local controls = {["\n"]="\\n", ["\r"]="\\r", ["\t"]="\\t", ["\b"]="\\b", ["\f"]="\\f", ["\""]="\\\"", ["\\"]="\\\\"}
  6.  
  7.  
  8. local whites = {['\n']=true; ['r']=true; ['\t']=true; [' ']=true; [',']=true; [':']=true}
  9. function removeWhite(str)
  10.     while whites[str:sub(1, 1)] do
  11.         str = str:sub(2)
  12.     end
  13.     return str
  14. end
  15.  
  16. ------------------------------------------------------------------ decoding
  17.  
  18. function jsonParseBoolean(str)
  19.     if str:sub(1, 4) == "true" then
  20.         return true, removeWhite(str:sub(5))
  21.     else
  22.         return false, removeWhite(str:sub(6))
  23.     end
  24. end
  25.  
  26. function jsonParseNull(str)
  27.     return nil, removeWhite(str:sub(5))
  28. end
  29.  
  30. local numChars = {['e']=true; ['E']=true; ['+']=true; ['-']=true; ['.']=true}
  31. function jsonParseNumber(str)
  32.     local i = 1
  33.     while numChars[str:sub(i, i)] or tonumber(str:sub(i, i)) do
  34.         i = i + 1
  35.     end
  36.     local val = tonumber(str:sub(1, i - 1))
  37.     str = removeWhite(str:sub(i))
  38.     return val, str
  39. end
  40.  
  41. function jsonParseString(str)
  42.     local i,j = str:find('^".-[^\\]"')
  43.     local s = str:sub(i + 1,j - 1)
  44.  
  45.     for k,v in pairs(controls) do
  46.         s = s:gsub(v, k)
  47.     end
  48.     str = removeWhite(str:sub(j + 1))
  49.     return s, str
  50. end
  51.  
  52. function jsonParseArray(str)
  53.     str = removeWhite(str:sub(2))
  54.    
  55.     local val = {}
  56.     local i = 1
  57.     while str:sub(1, 1) ~= "]" do
  58.         local v = nil
  59.         v, str = jsonParseValue(str)
  60.         val[i] = v
  61.         i = i + 1
  62.         str = removeWhite(str)
  63.     end
  64.     str = removeWhite(str:sub(2))
  65.     return val, str
  66. end
  67.  
  68. function jsonParseObject(str)
  69.     str = removeWhite(str:sub(2))
  70.    
  71.     local val = {}
  72.     while str:sub(1, 1) ~= "}" do
  73.         local k, v = nil, nil
  74.         k, v, str = jsonParseMember(str)
  75.         val[k] = v
  76.         str = removeWhite(str)
  77.     end
  78.     str = removeWhite(str:sub(2))
  79.     return val, str
  80. end
  81.  
  82. function jsonParseMember(str)
  83.     local k = nil
  84.     k, str = jsonParseValue(str)
  85.     local val = nil
  86.     val, str = jsonParseValue(str)
  87.     return k, val, str
  88. end
  89.  
  90. function jsonParseValue(str)
  91.     local fchar = str:sub(1, 1)
  92.     if fchar == "{" then
  93.         return jsonParseObject(str)
  94.     elseif fchar == "[" then
  95.         return jsonParseArray(str)
  96.     elseif tonumber(fchar) ~= nil or numChars[fchar] then
  97.         return jsonParseNumber(str)
  98.     elseif str:sub(1, 4) == "true" or str:sub(1, 5) == "false" then
  99.         return jsonParseBoolean(str)
  100.     elseif fchar == "\"" then
  101.         return jsonParseString(str)
  102.     elseif str:sub(1, 4) == "null" then
  103.         return jsonParseNull(str)
  104.     end
  105.     return nil
  106. end
  107.  
  108. function jsonDecode(str)
  109.     str = removeWhite(str)
  110.     t = jsonParseValue(str)
  111.     return t
  112. end
  113.  
  114. function downloadJson(url)
  115.     local file = http.get(url)
  116.     if not file then
  117.         return nil
  118.     end
  119.     return jsonDecode(file.readAll())
  120. end
  121.  
  122. local GitHubRepo = "Yevano/see" -- Change to user/repo
  123. local GitHubBranch = "master"   -- Change to needed branch
  124. local installPath = "/see/"
  125.  
  126.  
  127. local GitHubRef = "refs/heads/"..GitHubBranch
  128. local GitHubRaw = 'https://raw.github.com/'..GitHubRepo..'/'..GitHubBranch..'/'
  129. local args = {...}
  130.  
  131. local blacklist = {
  132.     '.gitignore',
  133.     'README.md'
  134. }
  135.  
  136. function isBlacklisted(path)
  137.     for i, item in ipairs(blacklist) do
  138.         if item == path then
  139.             return true
  140.         end
  141.     end
  142.     return false
  143. end
  144.  
  145. local failed = {}
  146.  
  147. function downloadBlob(v)
  148.     if isBlacklisted(v.path) then
  149.             return
  150.     end
  151.     --Make dir if needed
  152.     if v.type == 'tree' then
  153.         fs.makeDir(installPath..v.path)
  154.     else
  155.         --Start download
  156.         local url = (GitHubRaw..v.path):gsub(' ','%%20')
  157.         local f = http.get(url)
  158.  
  159.         --If couldn't download then add to failed
  160.         if not f then
  161.             table.insert(failed,v)
  162.             return
  163.         end
  164.  
  165.         --Write file
  166.         local h = fs.open(installPath..v.path, 'w')
  167.         h.write(f.readAll())
  168.         h.close()
  169.     end
  170. end
  171.  
  172. local function fail(err)
  173.     printError(err)
  174.  
  175.     while true do
  176.         write("Retry installation? (y/n): ")
  177.         local response = read()
  178.         if string.lower(response):gsub("%s", "") == "y" then
  179.             return true
  180.         elseif string.lower(response):gsub("%s", "") == "n" then
  181.             return false
  182.         end
  183.         print("Invalid input.")
  184.     end
  185. end
  186.  
  187. --Get install directory
  188. while true do
  189.     if #args == 1 then
  190.         installPath = args[1]
  191.     else
  192.         write("Choose an install path: ")
  193.         installPath = "/" .. shell.resolve(read())
  194.     end
  195.  
  196.     local configHandle = fs.open("/.see", "w")
  197.     configHandle.write('install_dir = "' .. installPath .. '/see"')
  198.     configHandle.close()
  199.  
  200.     local suc, err = pcall(fs.makeDir, installPath)
  201.     if not suc then
  202.         if not fail("Could not create installation directory.") then error("Exiting") end
  203.     else
  204.         break
  205.     end
  206. end
  207.  
  208. installPath = installPath .. '/'
  209. local tree = {}
  210. local latestSha = ''
  211.  
  212. --Get latest commit
  213. while true do
  214.     --Get sha for specific branch
  215.     local refs = downloadJson('https://api.github.com/repos/'..GitHubRepo..'/git/refs')
  216.  
  217.     if refs == nil then
  218.         if not fail("Could not fetch branches") then error("Exiting") end
  219.     else
  220.         for i, v in ipairs(refs) do
  221.             if v.ref == GitHubRef then
  222.                 latestSha = v.object.sha
  223.                 break
  224.             end
  225.         end
  226.         break
  227.     end
  228. end
  229. --Get tree
  230. while true do
  231.     --Download file list
  232.     tree = downloadJson('https://api.github.com/repos/'..GitHubRepo..'/git/trees/'..latestSha..'?recursive=1').tree
  233.  
  234.     if tree == nil then
  235.         if not fail("Could not fetch tree") then error("Exiting") end
  236.     else
  237.         break
  238.     end
  239. end
  240.  
  241. --Prepare file download
  242. local downloads = {}
  243. for i, v in ipairs(tree) do
  244.     table.insert(downloads, function()downloadBlob(v)end)
  245. end
  246.  
  247. while true do
  248.     parallel.waitForAll(unpack(downloads))
  249.  
  250.     if #failed > 0 then
  251.         if not fail("Not all files downloaded. Retry?") then error("Exiting") end
  252.  
  253.         downloads = {}
  254.         for i, v in ipairs(failed) do
  255.             print("Retrying "..v.path)
  256.             table.insert(downloads, function()downloadBlob(v)end)
  257.         end
  258.         failed = {}
  259.     else
  260.         break
  261.     end
  262. end
Add Comment
Please, Sign In to add comment