slipers

Minecraft. OpenComputers. Gitrepo.

Sep 1st, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.39 KB | None | 0 0
  1. --[[
  2. git repo downloader
  3.  
  4. downloads the full contents of a git repo to a directory on the computer.
  5. --]]
  6.  
  7.  
  8. local internet=require("internet")
  9. local text=require("text")
  10. local filesystem=require("filesystem")
  11. local unicode=require("unicode")
  12. local term=require("term")
  13. local event=require("event")
  14. local keyboard=require("keyboard")
  15.  
  16.  
  17. local repo,target
  18.  
  19. local args={...}
  20.  
  21. if #args<1 or #args>2 then
  22.   print("Usage: gitrepo <repo> [<targetdir>]]\nrepo should be the owner/repo, ex, \"OpenPrograms/Gopher-Programs\"\ntargetdir is an optional local path to download to, default will be /tmp/<repo>/")
  23.   return
  24. end
  25.  
  26. repo=args[1]
  27. if not repo:match("^[%w-.]*/[%w-.]*$") then
  28.   print('"'..args[1]..'" does not look like a valid repo identifier.\nShould be <owner>/<reponame>')
  29.   return
  30. end
  31.  
  32. target=args[2]
  33. target=target and ("/"..target:match("^/?(.-)/?$").."/") or "/tmp/"..repo
  34. if filesystem.exists(target) then
  35.   if not filesystem.isDirectory(target) then
  36.     print("target directory already exists and is not a directory.")
  37.     return
  38.   end
  39.   if filesystem.get(target).isReadOnly() then
  40.     print("target directory is read-only.")
  41.     return
  42.   end
  43. else
  44.   if not filesystem.makeDirectory(target) then
  45.     print("target directory is read-only")
  46.     return
  47.   end
  48. end
  49.  
  50.  
  51.  
  52. -- this isn't acually used, but it is tested and works on decoding the base64 encoded data that github
  53. --sends for some queries, leaving it in here for possible future/related use, might be able to pull
  54. --and display difs and things like that?
  55. local symb="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  56.  
  57. function decode64(text)
  58.   local val,bits=0,0
  59.   local output=""
  60.   for ch in text:gmatch(".") do
  61.     if symb:find(ch) then
  62.       --print("ch "..ch.."-> "..(symb:find(ch)-1))
  63.       val=bit32.lshift(val,6)+symb:find(ch)-1
  64.     else
  65.       print(ch.."?")
  66.       return
  67.     end
  68.     bits=bits+6
  69.     --print("bits : "..bits)
  70.     --print(string.format("val : 0x%04x",val))
  71.     if bits>=8 then
  72.       local och=unicode.char(bit32.rshift(val,bits-8))
  73.       --print("os<<"..och)
  74.       --print("& with "..(2^(bits-8)-1))
  75.       val=bit32.band(val,2^(bits-8)-1)
  76.       bits=bits-8
  77.       --print(string.format("val : 0x%04x",val))
  78.       output=output..och
  79.     end
  80.   end
  81.   return output
  82. end
  83.  
  84.  
  85.  
  86. local function gitContents(repo,dir)
  87.   print("fetching contents for "..repo..dir)
  88.   local url="https://api.github.com/repos/"..repo.."/contents"..dir
  89.   local result,response=pcall(internet.request,url)
  90.   local raw=""
  91.   local files={}
  92.   local directories={}
  93.  
  94.   if result then
  95.     for chunk in response do
  96.       raw=raw..chunk
  97.     end
  98.   else
  99.     error("you've been cut off. Serves you right.")
  100.   end
  101.  
  102.   response=nil
  103.   raw=raw:gsub("%[","{"):gsub("%]","}"):gsub("(\".-\"):(.-[,{}])",function(a,b) return "["..a.."]="..b end)
  104.   local t=load("return "..raw)()
  105.  
  106.   for i=1,#t do
  107.     if t[i].type=="dir" then
  108.       table.insert(directories,dir.."/"..t[i].name)
  109.  
  110.       local subfiles,subdirs=gitContents(repo,dir.."/"..t[i].name)
  111.       for i=1,#subfiles do
  112.         table.insert(files,subfiles[i])
  113.       end
  114.       for i=1,#subdirs do
  115.         table.insert(directories,subdirs[i])
  116.       end
  117.     else
  118.       files[#files+1]=dir.."/"..t[i].name
  119.     end
  120.   end
  121.  
  122.   return files, directories
  123. end
  124.  
  125. local files,dirs=gitContents(repo,"")
  126.  
  127. for i=1,#dirs do
  128.   print("making dir "..target..dirs[i])
  129.   if filesystem.exists(target..dirs[i]) then
  130.     if not filesystem.isDirectory(target..dirs[i]) then
  131.       print("error: directory "..target..dirs[i].." blocked by file with the same name")
  132.       return
  133.     end
  134.   else
  135.     filesystem.makeDirectory(target..dirs[i])
  136.   end
  137. end
  138.  
  139. local replaceMode="ask"
  140. for i=1,#files do
  141.   local replace=nil
  142.   if filesystem.exists(target..files[i]) then
  143.     if filesystem.isDirectory(target..files[i]) then
  144.       print("Error: file "..target..files[i].." blocked by directory with same name!")
  145.       return
  146.     end
  147.     if replaceMode=="always" then
  148.       replace=true
  149.     elseif replaceMode=="never" then
  150.       replace=false
  151.     else
  152.       print("\nFile "..target..files[i].." already exists.\nReplace with new version?")
  153.       local response=""
  154.       while replace==nil do
  155.         term.write("yes,no,always,skip all[ynAS]: ")
  156.         local char
  157.         repeat
  158.           _,_,char=event.pull("key_down")
  159.         until not keyboard.isControl(char)
  160.         char=unicode.char(char)
  161.         print(char)
  162.         if char=="A" then
  163.           replaceMode="always"
  164.           replace=true
  165.           char="y"
  166.         elseif char=="S" then
  167.           replaceMode="never"
  168.           replace=false
  169.           char="n"
  170.         elseif char:lower()=="y" then
  171.           replace=true
  172.         elseif char:lower()=="n" then
  173.           replace=false
  174.         else
  175.           print("invalid response.")
  176.         end
  177.       end
  178.     end
  179.     if replace then
  180.       filesystem.remove(target..files[i])
  181.     end
  182.   end
  183.   if replace~=false then
  184.     print("downloading "..files[i])
  185.     local url="https://raw.github.com/"..repo.."/master"..files[i]
  186.     local result,response=pcall(internet.request,url)
  187.     if result then
  188.       local raw=""
  189.       for chunk in response do
  190.         raw=raw..chunk
  191.       end
  192.       print("writing to "..target..files[i])
  193.       local file=io.open(target..files[i],"w")
  194.       file:write(raw)
  195.       file:close()
  196.  
  197.     else
  198.       print("failed, skipping")
  199.     end
  200.   end
  201. end
Add Comment
Please, Sign In to add comment