Milk_man_3000

github api 2

Apr 6th, 2016
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.54 KB | None | 0 0
  1. local JSON = dofile("apis/dkjson")
  2.  
  3. -- Build a github API url, trying to authenticate (not tested)
  4. local auth
  5. local function getAPI(path)
  6. local url
  7. if auth and auth.type == 'basic' then
  8. url = ('https://%s:%s@api.github.com/%s'):format(auth.user, auth.pass, path)
  9. else
  10. url = ('https://api.github.com/%s'):format(path)
  11. end
  12. local req = http.get(url)
  13. if req then
  14. return JSON.decode(req.readAll())
  15. else
  16. error('Could not get github API from ' ..path)
  17. end
  18. end
  19.  
  20. -- A class for a blob (aka a file)
  21. local Blob = {}
  22. Blob.__index = Blob
  23. Blob.new = function(repo, sha, path)
  24. return setmetatable({repo=repo, sha=sha, path=path}, Blob)
  25. end
  26. Blob.fullPath = function(self)
  27. if self.parent then
  28. return fs.combine(self.parent:fullPath(), self.path)
  29. else
  30. return self.path
  31. end
  32. end
  33.  
  34. -- A class for a tree (aka a folder)
  35. local Tree = {}
  36. Tree.__index = Tree
  37. Tree.new = function(repo, sha, path)
  38. local data = getAPI(
  39. ('repos/%s/%s/git/trees/%s'):format(repo.user, repo.name, sha)
  40. )
  41. if data.tree then
  42. local tree = setmetatable({
  43. repo=repo, sha=data.sha,
  44. path=path or '', size=0,
  45. contents={}
  46. }, Tree)
  47. for _, childdata in ipairs(data.tree) do
  48. childdata.fullPath = fs.combine(tree:fullPath(), childdata.path)
  49. local child
  50. if childdata.type == 'blob' then
  51. child = Blob.new(repo, childdata.sha, childdata.path)
  52. child.size = childdata.size
  53. elseif childdata.type == 'tree' then
  54. child = Tree.new(repo, childdata.sha, childdata.path)
  55. else
  56. error("uh oh", JSON.encode(childdata))
  57. child = childdata
  58. end
  59. tree.size = tree.size + child.size
  60. child.parent = tree
  61. table.insert(tree.contents, child)
  62. end
  63. return tree
  64. else
  65. error("uh oh", JSON.encode(data))
  66. end
  67. end
  68. local function walkTree(t, level)
  69. for _, item in ipairs(t.contents) do
  70. coroutine.yield(item, level)
  71. if getmetatable(item) == Tree then
  72. walkTree(item, level + 1)
  73. end
  74. end
  75. end
  76. Tree.iter = function(self)
  77. return coroutine.wrap(function()
  78. walkTree(self, 0)
  79. end)
  80. end
  81. Tree.fullPath = Blob.fullPath
  82.  
  83. -- A class for a repository
  84. local __repoPriv = setmetatable({}, {mode='k'})
  85. local Repository = {}
  86. Repository.__index = Repository
  87. Repository.new = function(user, name)
  88. local r = setmetatable({user=user, name=name}, Repository)
  89. __repoPriv[r] = {trees={}}
  90. return r
  91. end
  92. Repository.tree = function(self, sha)
  93. sha = sha or "master"
  94. if not __repoPriv[self].trees[sha] then
  95. __repoPriv[self].trees[sha] = Tree.new(self, sha)
  96. end
  97. return __repoPriv[self].trees[sha]
  98. end
  99. Repository.cloneTo = function(self, dest, onProgress)
  100. if not fs.exists(dest) then
  101. fs.makeDir(dest)
  102. elseif not fs.isDir(dest) then
  103. return error("Destination is a file!")
  104. end
  105.  
  106. for item in self:tree('master'):iter() do
  107. local gitpath = item:fullPath()
  108. local path = fs.combine(dest, gitpath)
  109. if getmetatable(item) == Tree then
  110. fs.makeDir(path)
  111. elseif getmetatable(item) == Blob then
  112. local data = http.get(
  113. ('https://raw.github.com/%s/%s/master/%s')
  114. :format(self.user, self.name, gitpath)
  115. )
  116. local h = fs.open(path, 'w')
  117. local text = data.readAll()
  118. h.write(text)
  119. h.close()
  120. end
  121. if onProgress then onProgress(item) end
  122. end
  123. end
  124. Repository.__tostring = function(self) return ("Repo@%s/%s"):format(self.user, self.name) end
  125.  
  126. -- Export members
  127. local github = {}
  128. github.basicAuth = function(user, pass)
  129. auth = {type='basic', user=user, pass=pass}
  130. end
  131. github.Repository = Repository
  132. github.Blob = Blob
  133. github.Tree = Tree
  134. github.repo = Repository.new
  135. return github
Add Comment
Please, Sign In to add comment