apemanzilla

gitget2

Mar 26th, 2015
6,621
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[ /gitget
  2. GitHub downloading utility for CC.
  3. Developed by apemanzilla.
  4.  
  5. This requires ElvishJerricco's JSON parsing API.
  6. Direct link: http://pastebin.com/raw.php?i=4nRg9CHU
  7. ]]--
  8.  
  9. -- Edit these variables to use preset mode.
  10. -- Whether to download the files asynchronously (huge speed benefits, will also retry failed files)
  11. -- If false will download the files one by one and use the old output (List each file name as it's downloaded) instead of the progress bar
  12. local async = true
  13.  
  14. -- Whether to write to the terminal as files are downloaded
  15. -- Note that unless checked for this will not affect pre-set start/done code below
  16. local silent = false
  17.  
  18. local preset = {
  19.     -- The GitHub account name
  20.     user = nil,
  21.     -- The GitHub repository name
  22.     repo = nil,
  23.    
  24.     -- The branch or commit tree to download (defaults to 'master')
  25.     branch = nil,
  26.    
  27.     -- The local folder to save all the files to (defaults to '/')
  28.     path = nil,
  29.    
  30.     -- Function to run before starting the download
  31.     start = function()
  32.         if not silent then print("Downloading files from GitHub...") end
  33.     end,
  34.    
  35.     -- Function to run when the download completes
  36.     done = function()
  37.         if not silent then print("Done") end
  38.     end
  39. }
  40.  
  41. -- Leave the rest of the program alone.
  42. local args = {...}
  43.  
  44. args[1] = preset.user or args[1]
  45. args[2] = preset.repo or args[2]
  46. args[3] = preset.branch or args[3] or "master"
  47. args[4] = preset.path or args[4] or ""
  48.  
  49. if #args < 2 then
  50.         print("Usage:\n"..((shell and shell.getRunningProgram()) or "gitget").." <user> <repo> [branch/tree] [path]") error()
  51. end
  52.  
  53. local function save(data,file)
  54.     local file = shell.resolve(file:gsub("%%20"," "))
  55.     if not (fs.exists(string.sub(file,1,#file - #fs.getName(file))) and fs.isDir(string.sub(file,1,#file - #fs.getName(file)))) then
  56.         if fs.exists(string.sub(file,1,#file - #fs.getName(file))) then fs.delete(string.sub(file,1,#file - #fs.getName(file))) end
  57.         fs.makeDir(string.sub(file,1,#file - #fs.getName(file)))
  58.     end
  59.     local f = fs.open(file,"w")
  60.     f.write(data)
  61.     f.close()
  62. end
  63.  
  64. local function download(url, file)
  65.     save(http.get(url).readAll(),file)
  66. end
  67.  
  68. if not json then
  69.     download("http://pastebin.com/raw.php?i=4nRg9CHU","json")
  70.     os.loadAPI("json")
  71. end
  72.  
  73. preset.start()
  74. local data = json.decode(http.get("https://api.github.com/repos/"..args[1].."/"..args[2].."/git/trees/"..args[3].."?recursive=1").readAll())
  75. if data.message and data.message:find("API rate limit exceeded") then error("Out of API calls, try again later") end
  76. if data.message and data.message == "Not found" then error("Invalid repository",2) else
  77.     for k,v in pairs(data.tree) do
  78.         -- Make directories
  79.         if v.type == "tree" then
  80.             fs.makeDir(fs.combine(args[4],v.path))
  81.             if not hide_progress then
  82.             end
  83.         end
  84.     end
  85.     local drawProgress
  86.     if async and not silent then
  87.         local _, y = term.getCursorPos()
  88.         local wide, _ = term.getSize()
  89.         term.setCursorPos(1, y)
  90.         term.write("[")
  91.         term.setCursorPos(wide - 6, y)
  92.         term.write("]")
  93.         drawProgress = function(done, max)
  94.             local value = done / max
  95.             term.setCursorPos(2,y)
  96.             term.write(("="):rep(math.floor(value * (wide - 8))))
  97.             local percent = math.floor(value * 100) .. "%"
  98.             term.setCursorPos(wide - percent:len(),y)
  99.             term.write(percent)
  100.         end
  101.     end
  102.     local filecount = 0
  103.     local downloaded = 0
  104.     local paths = {}
  105.     local failed = {}
  106.     for k,v in pairs(data.tree) do
  107.         -- Send all HTTP requests (async)
  108.         if v.type == "blob" then
  109.             v.path = v.path:gsub("%s","%%20")
  110.             local url = "https://raw.github.com/"..args[1].."/"..args[2].."/"..args[3].."/"..v.path,fs.combine(args[4],v.path)
  111.             if async then
  112.                 http.request(url)
  113.                 paths[url] = fs.combine(args[4],v.path)
  114.                 filecount = filecount + 1
  115.             else
  116.                 download(url, fs.combine(args[4], v.path))
  117.                 if not silent then print(fs.combine(args[4], v.path)) end
  118.             end
  119.         end
  120.     end
  121.     while downloaded < filecount do
  122.         local e, a, b = os.pullEvent()
  123.         if e == "http_success" then
  124.             save(b.readAll(),paths[a])
  125.             downloaded = downloaded + 1
  126.             if not silent then drawProgress(downloaded,filecount) end
  127.         elseif e == "http_failure" then
  128.             -- Retry in 3 seconds
  129.             failed[os.startTimer(3)] = a
  130.         elseif e == "timer" and failed[a] then
  131.             http.request(failed[a])
  132.         end
  133.     end
  134. end
  135. preset.done()
RAW Paste Data