Advertisement
Tatantyler

LeadLined-OS Installer

Nov 1st, 2013
673
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.36 KB | None | 0 0
  1. -- LeadLined-OS Install Utility v0.2 (as of last update)
  2. -- Development just keeps dragging on, doesn't it?
  3.  
  4. local args = {...}
  5.  
  6. local dirs = { -- Directories to make
  7.     "home",
  8.     "sys",
  9.     "bin",
  10.     "sys/apis",
  11.     "sys/svcs",
  12.     "sys/users",
  13.     "sys/drivers",
  14.     "home/root",
  15.     "old_files",
  16. }
  17.  
  18. local ignoreList = {
  19.     ".gitattributes",
  20.     ".gitignore",
  21.     "README.md",
  22.     "install",
  23.     "unused",
  24. }
  25.  
  26. local install_temp_dir = "LEADLINED_INSTALL_TEMP_DIR"
  27.  
  28. function github_getRequestsLeft()
  29.     local h = http.get("https://api.github.com/rate_limit")
  30.     if h then
  31.         local data = h.readAll()
  32.         h.close()
  33.         local s = string.match(data, "\"remaining\":(%d+)")
  34.         if s then
  35.             return tonumber(s) or 0
  36.         end
  37.     else
  38.         return 0
  39.     end
  40. end
  41.  
  42. function github_getRequestLimit()
  43.     local h = http.get("https://api.github.com/rate_limit")
  44.     if h then
  45.         local data = h.readAll()
  46.         h.close()
  47.         local s = string.match(data, "\"limit\":(%d+)")
  48.         if s then
  49.             return tonumber(s) or 0
  50.         end
  51.     else
  52.         return 0
  53.     end
  54. end
  55.  
  56. function parse_contentsRequest(response)
  57.     local tables = {}
  58.     local id = 0
  59.     for ident, data in string.gmatch(response, "\"(%a+)\":\"([^%\"]+)\",") do
  60.         --local line = string.match(lines[i], "%s+(%.+)")
  61.         --if line ~= "{" and line ~= "}" and line ~= "}," then
  62.         --  local ident, data = string.match(line, "\"(%a+)\": \"([^%\"]+)\"")
  63.         --print("["..ident.."] = "..data)
  64.         if ident == "name" then
  65.             id = id + 1
  66.             tables[id] = {}
  67.             tables[id]["name"] = data
  68.             tables[id]["links"] = {}
  69.         elseif ident == "self" or ident == "git" or ident == "html" then
  70.             tables[id]["links"][ident] = data
  71.         elseif ident ~= "_links" then
  72.             tables[id][ident] = data
  73.         end
  74.     end
  75.     return tables
  76. end
  77.  
  78. function github_getContents(user, repo, path, verbose, fileNameColor, normalTextColor)
  79.     if verbose then
  80.         fileNameColor = fileNameColor or colors.orange
  81.         normalTextColor = normalTextColor or colors.white
  82.         write("Listing: ")
  83.         term.setTextColor(fileNameColor)
  84.         write(path)
  85.         term.setTextColor(normalTextColor)
  86.         write("...")
  87.     end
  88.     path = path or ""
  89.     local url = "https://api.github.com/repos/"..user.."/"..repo.."/contents/"..path
  90.     --print("HTTP GET: "..url)
  91.     if github_getRequestsLeft() == 0 then
  92.         return false, {}
  93.     end
  94.     local handle = http.get(url)
  95.     if handle then
  96.         local data = handle.readAll()
  97.         --print("Retrieved "..#data.." bytes.")
  98.         handle.close()
  99.         --print(data)
  100.         if verbose then
  101.             print("Success.")
  102.         end
  103.         return true, parse_contentsRequest(data)
  104.     else
  105.         if verbose then
  106.             print("Failed.")
  107.         end
  108.         return false, {}
  109.     end
  110. end
  111.  
  112. function github_getFile(user, repo, file, branch, verbose, fileNameColor, normalTextColor)
  113.     if verbose then
  114.         fileNameColor = fileNameColor or colors.orange
  115.         normalTextColor = normalTextColor or colors.white
  116.         write("Retrieving: ")
  117.         term.setTextColor(fileNameColor)
  118.         write(file)
  119.         term.setTextColor(normalTextColor)
  120.         write("...")
  121.     end
  122.     local url = "https://raw.github.com/"..user.."/"..repo.."/"..branch.."/"..file
  123.     --print("HTTP GET: "..url)
  124.     local handle = http.get(url)
  125.     if handle then
  126.         local data = handle.readAll()
  127.         handle.close()
  128.         if verbose then
  129.             print("Success.")
  130.             print("Retrieved "..#data.." bytes.")
  131.         end
  132.         return true, data
  133.     else
  134.         if verbose then
  135.             print("Failed.")
  136.         end
  137.         return false
  138.     end
  139. end
  140.  
  141. function github_getAllFilesRecursive(user, repo, dir, branch, verbose, fileNameColor, normalTextColor)
  142.     dir = dir or ""
  143.     local files = {}
  144.     local status, contents = github_getContents(user, repo, dir, verbose, fileNameColor, normalTextColor)
  145.     if not status then
  146.         return false, {}, 1, 0, 1, 0
  147.     end
  148.     local totalFiles = 0
  149.     local totalDirs = 0
  150.     local failedFiles = 0
  151.     local failedDirs = 0
  152.     for i,v in ipairs(contents) do
  153.         local skip = false
  154.         for x=1, #ignoreList do
  155.             if ignoreList[x] == v["path"] then
  156.                 skip = true
  157.                 break
  158.             end
  159.         end
  160.         if not skip then
  161.             if v["type"] == "file" then
  162.                 totalFiles = totalFiles+1
  163.                 local status, data = github_getFile(user, repo, v["path"], branch, verbose, fileNameColor, normalTextColor)
  164.                 if status then
  165.                     files[v["path"]] = data
  166.                 else
  167.                     failedFiles = failedFiles+1
  168.                 end
  169.             elseif v["type"] == "dir" then
  170.                 totalDirs = totalDirs+1
  171.                 local status, files2, fDirs, fFiles, tDirs, tFiles = github_getAllFilesRecursive(user, repo, v["path"], branch, verbose, fileNameColor, normalTextColor)
  172.                 if status then
  173.                     for i,v in pairs(files2) do
  174.                         files[i] = v
  175.                     end
  176.                     failedDirs = failedDirs+fDirs
  177.                     failedFiles = failedFiles+fFiles
  178.                     totalFiles = totalFiles + tFiles
  179.                     totalDirs = totalDirs + tDirs
  180.                 else
  181.                     failedDirs = failedDirs+1
  182.                 end
  183.             end
  184.         end
  185.     end
  186.     return true, files, failedDirs, failedFiles, totalDirs, totalFiles
  187. end
  188.  
  189. term.clear()
  190. term.setCursorPos(1,1)
  191. local maxX, maxY = term.getSize()
  192. local inColor = term.isColor()
  193.  
  194. print("LeadLined-OS Install Utility")
  195. print(string.rep("=", maxX))
  196. print("Welcome to the LeadLined-OS Install Program.")
  197. if args[1] ~= "--auth-files-only" then
  198.     write("You have ")
  199.     if inColor then term.setTextColor(colors.yellow) end
  200.     write(github_getRequestsLeft())
  201.     term.setTextColor(colors.white)
  202.     write(" of ")
  203.     if inColor then term.setTextColor(colors.yellow) end
  204.     write(github_getRequestLimit())
  205.     term.setTextColor(colors.white)
  206.     print(" requests left.")
  207.     if github_getRequestsLeft() == 0 then
  208.         if inColor then term.setTextColor(colors.red) end
  209.         write("ERROR: ")
  210.         term.setTextColor(colors.white)
  211.         print("We can't make anymore requests to Github!")
  212.         print("Try installing again in an hour.")
  213.         return
  214.     end
  215.  
  216.     if github_getRequestsLeft() < 5 then
  217.         if inColor then term.setTextColor(colors.orange) end
  218.         write("WARNING: ")
  219.         term.setTextColor(colors.white)
  220.         print("We might not be able to download the entire OS!")
  221.         local x,y = term.getCursorPos()
  222.         while true do
  223.             term.setCursorPos(x, y)
  224.             term.clearLine()
  225.             write("Install anyways? Y/N> ")
  226.             term.setTextColor(colors.yellow)
  227.             local a = string.lower(string.sub(read(), 1, 1))
  228.             term.setTextColor(colors.white)
  229.             if a == "y" then
  230.                 break
  231.             elseif a == "n" then
  232.                 print("Try installing again in an hour.")
  233.                 return
  234.             end
  235.         end
  236.     else
  237.         print("Press ENTER to continue, and any other key to exit.")
  238.         local event, key = os.pullEvent("key")
  239.         if key ~= keys.enter then
  240.             return
  241.         end
  242.     end
  243.    
  244.     print("Downloading files...")
  245.     local status, files, fDirs, fFiles, tDirs, tFiles = github_getAllFilesRecursive("Tatantyler", "LeadLined-OS", "", "master", true, colors.yellow, colors.white)
  246.     if status and ((fDirs == 0) and (fFiles == 0)) then
  247.         print("Download completed successfully.")
  248.         write("Downloaded ")
  249.         if inColor then term.setTextColor(colors.yellow) end
  250.         write(tFiles)
  251.         term.setTextColor(colors.white)
  252.         write(" files and ")
  253.         if inColor then term.setTextColor(colors.yellow) end
  254.         write(tDirs)
  255.         term.setTextColor(colors.white)
  256.         print(" directories.")
  257.         if inColor then term.setTextColor(colors.lime) end
  258.         print("No failures reported.")
  259.         term.setTextColor(colors.white)
  260.     elseif status and (not((fDirs == 0) and (fFiles == 0))) then
  261.         print("Download was partially successful.")
  262.         write("Downloaded ")
  263.         if inColor then term.setTextColor(colors.yellow) end
  264.         write(tFiles)
  265.         term.setTextColor(colors.white)
  266.         write(" files and ")
  267.         if inColor then term.setTextColor(colors.yellow) end
  268.         write(tDirs)
  269.         term.setTextColor(colors.white)
  270.         print(" directories.")
  271.         write("Failed: ")
  272.         if inColor then term.setTextColor(colors.red) end
  273.         write(fFiles)
  274.         term.setTextColor(colors.white)
  275.         write(" files and ")
  276.         if inColor then term.setTextColor(colors.red) end
  277.         write(fDirs)
  278.         term.setTextColor(colors.white)
  279.         print(" directories.")
  280.     elseif not status then
  281.         if inColor then term.setTextColor(colors.red) end
  282.         print("Download failed; could not get base directory listing.")
  283.         term.setTextColor(colors.white)
  284.         return
  285.     end
  286.    
  287.     print("Moving old files to temp dir...")
  288.     if fs.exists(install_temp_dir) then
  289.         fs.delete(install_temp_dir)
  290.     end
  291.  
  292.     fs.makeDir(install_temp_dir)
  293.  
  294.     local userFiles = fs.list("")
  295.     for i=1, #userFiles do
  296.         if (not fs.isReadOnly(userFiles[i])) and userFiles[i] ~= install_temp_dir then
  297.             fs.move(userFiles[i], fs.combine(install_temp_dir, userFiles[i])) -- We'll be moving these files to the new user's home directory soon
  298.             print("Moved: "..userFiles[i])
  299.         end
  300.     end
  301.  
  302.     print("Creating directory structure...")
  303.     for i=1, #dirs do
  304.         if fs.exists(dirs[i]) then
  305.             fs.delete(dirs[i])
  306.         end
  307.         fs.makeDir(dirs[i])
  308.     end
  309.  
  310.     print("Writing OS files to disk...")
  311.     for path, data in pairs(files) do
  312.         write("Writing: "..path)
  313.         local base = string.sub(path, 1, #path-#fs.getName(path))
  314.         if not fs.exists(base) then
  315.             fs.makeDir(base)
  316.         end
  317.         local handle = fs.open(path, "w")
  318.         handle.write(data)
  319.         handle.close()
  320.         print(" ("..#data.." bytes)")
  321.     end
  322. else
  323.     for i=1, #dirs do
  324.         if not fs.exists(dirs[i]) then
  325.             fs.makeDir(dirs[i])
  326.         end
  327.     end
  328.     print("Authentication File Only mode enabled.")
  329.     os.pullEvent("key")
  330. end
  331.  
  332. if args[1] ~= "--auth-files-only" then
  333.     local tempFiles = fs.list(install_temp_dir)
  334.     for i=1, #tempFiles do
  335.         fs.move(fs.combine(install_temp_dir, tempFiles[i]), fs.combine("old_files", tempFiles[i]))
  336.     end
  337.     fs.delete(install_temp_dir)
  338. end
  339.  
  340. print("Installation complete!")
  341. print("Your computer will now restart.")
  342. os.sleep(1.5)
  343. os.reboot()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement