Advertisement
PaymentOption

GitHub Repository Mapper

Jul 8th, 2013
388
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.38 KB | None | 0 0
  1. --[[
  2.     Git API         Trystan Cannon
  3.                     8 June 2013
  4.                    
  5.     Contains a slew of local functions and two global functions
  6.     for mapping GitHub repositories into tables. Using these
  7.     tables, one could browse a GitHub repository or recursively
  8.     download an entire repository as a project. This is useful
  9.     for those who develop using GitHub rather than uploading
  10.     several files to pastebin and creating an installer script.
  11.    
  12.     The global functions which are useable outside of this file are:
  13.         - getRepository (author, repository, branch)
  14.             * Returns a table mapping of the repository with the given URL components.
  15.             * NOTE: The repository represented by the given URL components must be a valid repository on GitHub.
  16.             * NOTE: Repository table mappings have entries as follows: t[name] = fileName or branchTable
  17.         - printRepository (repository, sleepTime)
  18.             * Recursively prints out a repository and shows the different branches of the given repostory.
  19.             * NOTE: The repository table given can be any table; the function simply recursively prints out a table's contents.
  20. ]]
  21.  
  22. -- Variables ----------------------------------------------------
  23. local httpBase     = "https://github.com/"
  24. local httpFileBase = "https://raw.github.com/"
  25. -- Variables ----------------------------------------------------
  26.  
  27.  
  28.  
  29. -- Encodes the given string to work with the GitHub urls. Basically, all spaces
  30. -- are replaced with %20.
  31. local function urlEncode (_string)
  32.     return string.gsub (_string, "%s", "%%20")
  33. end
  34.  
  35. -- Compiles the given url components into one which will allow for the downloading
  36. -- of the file in the designated repository.
  37. local function compileFileUrl (author, repository, branch, path)
  38.     author     = urlEncode (author)
  39.     repository = urlEncode (repository)
  40.     path       = urlEncode (path)
  41.    
  42.     return httpFileBase .. author .. '/' .. repository .. '/' .. branch .. '/' .. path
  43. end
  44.  
  45. -- Compiles the given url components into one which will allow for the downloading
  46. -- of the url page for the given tree in a repository.
  47. local function compileTreeUrl (author, repository, branch, treePath)
  48.     author     = urlEncode (author)
  49.     repository = urlEncode (repository)
  50.     treePath   = urlEncode (treePath or "")
  51.    
  52.     return httpBase .. author .. '/' .. repository .. "/tree/" .. branch .. '/' .. treePath
  53. end
  54.  
  55. -- Requests a page and returns all relevant event data.
  56. local function requestPage (url)
  57.     local success, _error = pcall (http.request, url)
  58.    
  59.     if success then
  60.         local event, url, page = nil
  61.        
  62.         repeat
  63.             event, url, page = os.pullEvent()
  64.         until event == "http_success" or event == "http_failure"
  65.        
  66.         local pageContents = nil
  67.         if event == "http_success" then
  68.             pageContents = page.readAll()
  69.             page.close()
  70.         end
  71.        
  72.         return event == "http_success", url, pageContents
  73.     end
  74.    
  75.     return false
  76. end
  77.  
  78. -- Returns every file or folder/tree contained within in a folder/tree. This is not done recursively,
  79. -- so it is only surface level.
  80. local function parseTreePage (page)
  81.     local contents = {}
  82.     local pattern  = '<td class="content">\n%s*<a href="(.-)"'
  83.    
  84.     for match in string.gmatch (page, pattern) do
  85.         contents[#contents + 1] = string.gsub (match, "%%20", " ")
  86.     end
  87.    
  88.     return contents
  89. end
  90.  
  91. -- Takes a table of items in a tree in the repository and removes all extraneous text. This leaves
  92. -- all items in the table just as their paths in the branch.
  93. local function trimItemsInTree (itemsInTree, branch)
  94.     for index = 1, #itemsInTree do
  95.         itemsInTree[index] = itemsInTree[index]:match (branch .. "/(.+)")
  96.     end
  97. end
  98.  
  99. -- Returns all of the items in a given tree.
  100. local function getItemsInTree (author, repository, branch, treePath)
  101.     local success, url, pageContents = requestPage (compileTreeUrl (author, repository, branch, treePath))
  102.    
  103.     if success then
  104.         local items = parseTreePage (pageContents)
  105.        
  106.         trimItemsInTree (items, branch)
  107.         return items
  108.     end
  109.    
  110.     return {}
  111. end
  112.  
  113. -- Checks if the given path is a tree or not.
  114. -- NOTE: The given path must be a valid path in the repository.
  115. local function isPathTree (author, repository, branch, path)
  116.     local _, _, pageContents = requestPage (compileTreeUrl (author, repository, branch, path))
  117.     return #parseTreePage (pageContents) ~= 0
  118. end
  119.  
  120. -- Compiles the given url components into one which will allow for downloading
  121. -- of a raw file from github.
  122. local function compileFileUrl (author, repository, branch, filePath)
  123.     author     = urlEncode (author)
  124.     repository = urlEncode (repository)
  125.     filePath   = urlEncode (filePath)
  126.    
  127.     return httpFileBase .. author .. '/' .. repository .. '/' .. branch .. '/' .. filePath
  128. end
  129.  
  130. -- Returns the contents of the file at the path designated by the given url components in the repository.
  131. local function getFileContents (author, repository, branch, path)
  132.     local success, url, pageContents = requestPage (compileFileUrl (author, repository, branch, path))
  133.    
  134.     if success then
  135.         return pageContents
  136.     end
  137. end
  138.  
  139. -- Returns a table of all of the items in the given repository.
  140. -- When calling this from another script, use "" as the path.
  141. function getRepository (author, repository, branch, path, map)
  142.           path = path or ""
  143.     local map  = map or {}
  144.    
  145.     if isPathTree (author, repository, branch, path) then
  146.         map[fs.getName (path)] = {}
  147.        
  148.         local itemsInTree = getItemsInTree (author, repository, branch, path)
  149.         for _, itemPath in pairs (itemsInTree) do
  150.             getRepository (author, repository, branch, itemPath, map[fs.getName (path)])
  151.         end
  152.     else
  153.         map[fs.getName (path)] = fs.getName (path)
  154.     end
  155.    
  156.     return map
  157. end
  158.  
  159. -- Prints out the given repository table recursively with the designated number of seconds to sleep between each print.
  160. function printRepository (repository, sleepTime, indent)
  161.     indent = indent or ""
  162.    
  163.     for name, item in pairs (repository) do
  164.         sleep (sleepTime or 0)
  165.         print (indent .. name)
  166.        
  167.         if type (item) == "table" then
  168.             printRepository (item, sleepTime, indent .. ' ')
  169.         end
  170.     end
  171. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement