LDDestroier

Gitget (CC)

Feb 22nd, 2018
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.67 KB | None | 0 0
  1. --[[
  2.   Gitget for ComputerCraft
  3.  A simple GitHub repo downloader!
  4.  
  5.    pastebin get TZd5PYgz gitget
  6.                               --]]
  7. local verbose = true
  8.  
  9. local tArg = {...}
  10. local reponame = tArg[1]
  11. local repopath = tArg[2]
  12. local outpath = tArg[3]
  13.  
  14. if outpath:sub(1,1) ~= "/" then
  15.     outpath = fs.combine(shell.dir(),outpath)
  16. end
  17.  
  18. --thank you ElvishJerricco
  19. local controls = {["\n"]="\\n", ["\r"]="\\r", ["\t"]="\\t", ["\b"]="\\b", ["\f"]="\\f", ["\""]="\\\"", ["\\"]="\\\\"}
  20. local function isArray(t)
  21.     local max = 0
  22.     for k,v in pairs(t) do
  23.         if type(k) ~= "number" then
  24.             return false
  25.         elseif k > max then
  26.             max = k
  27.         end
  28.     end
  29.     return max == #t
  30. end
  31. local whites = {['\n']=true; ['\r']=true; ['\t']=true; [' ']=true; [',']=true; [':']=true}
  32. function removeWhite(str)
  33.     while whites[str:sub(1, 1)] do str = str:sub(2) end return str
  34. end
  35. local function encodeCommon(val, pretty, tabLevel, tTracking)
  36.     local str = ""
  37.     local function tab(s)
  38.         str = str .. ("\t"):rep(tabLevel) .. s
  39.     end
  40.     local function arrEncoding(val, bracket, closeBracket, iterator, loopFunc)
  41.         str = str .. bracket
  42.         if pretty then
  43.             str = str .. "\n"
  44.             tabLevel = tabLevel + 1
  45.         end
  46.         for k,v in iterator(val) do
  47.             tab("")
  48.             loopFunc(k,v)
  49.             str = str .. ","
  50.             if pretty then str = str .. "\n" end
  51.         end
  52.         if pretty then tabLevel = tabLevel - 1 end
  53.         if str:sub(-2) == ",\n" then str = str:sub(1, -3) .. "\n"
  54.         elseif str:sub(-1) == "," then str = str:sub(1, -2) end
  55.         tab(closeBracket)
  56.     end
  57.     if type(val) == "table" then
  58.         assert(not tTracking[val], "Cannot encode a table holding itself recursively")
  59.         tTracking[val] = true
  60.         if isArray(val) then
  61.             arrEncoding(val, "[", "]", ipairs, function(k,v)
  62.                 str = str .. encodeCommon(v, pretty, tabLevel, tTracking)
  63.             end)
  64.         else
  65.             arrEncoding(val, "{", "}", pairs, function(k,v)
  66.                 assert(type(k) == "string", "JSON object keys must be strings", 2)
  67.                 str = str .. encodeCommon(k, pretty, tabLevel, tTracking)
  68.                 str = str .. (pretty and ": " or ":") .. encodeCommon(v, pretty, tabLevel, tTracking)
  69.             end)
  70.         end
  71.     elseif type(val) == "string" then str = '"' .. val:gsub("[%c\"\\]", controls) .. '"'
  72.     elseif type(val) == "number" or type(val) == "boolean" then str = tostring(val)
  73.     else error("JSON only supports arrays, objects, numbers, booleans, and strings", 2) end
  74.     return str
  75. end
  76. local function encode(val)
  77.     return encodeCommon(val, false, 0, {})
  78. end
  79. local function encodePretty(val)
  80.     return encodeCommon(val, true, 0, {})
  81. end
  82. local decodeControls = {}
  83. for k,v in pairs(controls) do
  84.     decodeControls[v] = k
  85. end
  86. local function parseBoolean(str)
  87.     if str:sub(1, 4) == "true" then
  88.         return true, removeWhite(str:sub(5))
  89.     else
  90.         return false, removeWhite(str:sub(6))
  91.     end
  92. end
  93. local function parseNull(str)
  94.     return nil, removeWhite(str:sub(5))
  95. end
  96. local numChars = {['e']=true; ['E']=true; ['+']=true; ['-']=true; ['.']=true}
  97. local function parseNumber(str)
  98.     local i = 1
  99.     while numChars[str:sub(i, i)] or tonumber(str:sub(i, i)) do
  100.         i = i + 1
  101.     end
  102.     local val = tonumber(str:sub(1, i - 1))
  103.     str = removeWhite(str:sub(i))
  104.     return val, str
  105. end
  106. local function parseString(str)
  107.     str = str:sub(2)
  108.     local s = ""
  109.     while str:sub(1,1) ~= "\"" do
  110.         local next = str:sub(1,1)
  111.         str = str:sub(2)
  112.         assert(next ~= "\n", "Unclosed string")
  113.  
  114.         if next == "\\" then
  115.             local escape = str:sub(1,1)
  116.             str = str:sub(2)
  117.  
  118.             next = assert(decodeControls[next..escape], "Invalid escape character")
  119.         end
  120.  
  121.         s = s .. next
  122.     end
  123.     return s, removeWhite(str:sub(2))
  124. end
  125. local parseValue, parseMember
  126. local function parseArray(str)
  127.     str = removeWhite(str:sub(2))
  128.     local val = {}
  129.     local i = 1
  130.     while str:sub(1, 1) ~= "]" do
  131.         local v = nil
  132.         v, str = parseValue(str)
  133.         val[i] = v
  134.         i = i + 1
  135.         str = removeWhite(str)
  136.     end
  137.     str = removeWhite(str:sub(2))
  138.     return val, str
  139. end
  140. local function parseObject(str)
  141.     str = removeWhite(str:sub(2))
  142.     local val = {}
  143.     while str:sub(1, 1) ~= "}" do
  144.         local k, v = nil, nil
  145.         k, v, str = parseMember(str)
  146.         val[k] = v
  147.         str = removeWhite(str)
  148.     end
  149.     str = removeWhite(str:sub(2))
  150.     return val, str
  151. end
  152. function parseMember(str)
  153.     local k = nil
  154.     k, str = parseValue(str)
  155.     local val = nil
  156.     val, str = parseValue(str)
  157.     return k, val, str
  158. end
  159. function parseValue(str)
  160.     local fchar = str:sub(1, 1)
  161.     if fchar == "{" then
  162.         return parseObject(str)
  163.     elseif fchar == "[" then
  164.         return parseArray(str)
  165.     elseif tonumber(fchar) ~= nil or numChars[fchar] then
  166.         return parseNumber(str)
  167.     elseif str:sub(1, 4) == "true" or str:sub(1, 5) == "false" then
  168.         return parseBoolean(str)
  169.     elseif fchar == "\"" then
  170.         return parseString(str)
  171.     elseif str:sub(1, 4) == "null" then
  172.         return parseNull(str)
  173.     end
  174.     return nil
  175. end
  176. local function decode(str)
  177.     str = removeWhite(str)
  178.     t = parseValue(str)
  179.     return t
  180. end
  181.  
  182. local writeToFile = function(filename,contents)
  183.     local file = fs.open(filename,"w")
  184.     file.write(contents)
  185.     file.close()
  186. end
  187.  
  188. local getFromGitHub
  189. getFromGitHub = function(reponame,repopath,filepath,verbose)
  190.     local jason = http.get("https://api.github.com/repos/"..reponame.."/contents/"..(repopath or ""))
  191.     if not jason then return false end
  192.     local repo = decode(jason.readAll())
  193.     for k,v in pairs(repo) do
  194.         if v.message then
  195.             return false
  196.         else
  197.             if v.type == "file" then
  198.                 if verbose then print("'"..fs.combine(filepath,v.name).."'") end
  199.                 writeToFile(fs.combine(filepath,v.name),http.get(v.download_url).readAll())
  200.             elseif v.type == "dir" then
  201.                 if verbose then print("'"..fs.combine(filepath,v.name).."'") end
  202.                 fs.makeDir(fs.combine(filepath,v.name))
  203.                 getFromGitHub(reponame,fs.combine(repopath,v.name),fs.combine(filepath,v.name),verbose)
  204.             end
  205.         end
  206.     end
  207. end
  208.  
  209. local displayHelp = function()
  210.     local progname = fs.getName(shell.getRunningProgram())
  211.     print(progname.." [owner/repo] [repopath] [output dir]")
  212. end
  213.  
  214. if not (reponame and repopath and outpath) then
  215.     return displayHelp()
  216. else
  217.     if fs.exists(outpath) then
  218.         write("'"..outpath.."' already exists!")
  219.         if fs.isDir(outpath) then write(" Merge?") else write("Overwrite?") end
  220.         print(" (Y/N)")
  221.         local evt,key
  222.         while true do
  223.             evt,key = os.pullEvent("key")
  224.             if key == keys.y then
  225.                 if (not fs.isDir(outpath)) then fs.delete(outpath) end
  226.                 break
  227.             elseif key == keys.n then
  228.                 print("Abort.")
  229.                 coroutine.yield()
  230.                 return
  231.             end
  232.         end
  233.     end
  234.     if repopath == "*" then repopath = "" end
  235.     local oldtxt = (term.getTextColor and term.getTextColor()) or colors.white
  236.     print("Downloading...")
  237.     term.setTextColor(term.isColor() and colors.green or colors.lightGray)
  238.     getFromGitHub(reponame,repopath,outpath,verbose)
  239.     term.setTextColor(oldtxt)
  240.     print("Downloaded to /"..fs.combine("",outpath))
  241. end
Add Comment
Please, Sign In to add comment