Refactor git module to support Gitea and improve error handling
This commit is contained in:
@@ -1,67 +1,90 @@
|
|||||||
local json = require('opus.json')
|
local json = require('opus.json')
|
||||||
local Util = require('opus.util')
|
local Util = require('opus.util')
|
||||||
|
|
||||||
local TREE_URL = 'https://api.github.com/repos/%s/%s/git/trees/%s?recursive=1'
|
local GITHUB_TREE_URL = 'https://api.github.com/repos/%s/%s/git/trees/%s?recursive=1'
|
||||||
local FILE_URL = 'https://raw.githubusercontent.com/%s/%s/%s/%s'
|
local GITHUB_FILE_URL = 'https://raw.githubusercontent.com/%s/%s/%s/%s'
|
||||||
|
local GITEA_TREE_URL = 'https://%s/api/v1/repos/%s/%s/git/trees/%s?recursive=1'
|
||||||
|
local GITEA_FILE_URL = 'https://%s/%s/%s/raw/branch/%s/%s'
|
||||||
local TREE_HEADERS = {}
|
local TREE_HEADERS = {}
|
||||||
local git = { }
|
local git = { }
|
||||||
|
|
||||||
if _G._GIT_API_KEY then
|
if _G._GIT_API_KEY then
|
||||||
TREE_HEADERS.Authorization = 'token ' .. _G._GIT_API_KEY
|
TREE_HEADERS.Authorization = 'token ' .. _G._GIT_API_KEY
|
||||||
end
|
end
|
||||||
|
|
||||||
function git.list(repository)
|
local function parseTree(data, path, fileUrlFn)
|
||||||
local t = Util.split(repository, '(.-)/')
|
if data.message then
|
||||||
|
if data.message:find("API rate limit exceeded") then
|
||||||
local user = table.remove(t, 1)
|
error("Out of API calls, try again later")
|
||||||
local repo = table.remove(t, 1)
|
end
|
||||||
local branch = table.remove(t, 1) or 'main'
|
if data.message == "Not found" or data.message == "Not Found" then
|
||||||
local path
|
error("Invalid repository")
|
||||||
|
|
||||||
if not Util.empty(t) then
|
|
||||||
path = table.concat(t, '/') .. '/'
|
|
||||||
end
|
|
||||||
|
|
||||||
local function getContents()
|
|
||||||
local dataUrl = string.format(TREE_URL, user, repo, branch)
|
|
||||||
local contents, msg = Util.httpGet(dataUrl, TREE_HEADERS)
|
|
||||||
if not contents then
|
|
||||||
error(string.format('Failed to download %s\n%s', dataUrl, msg), 2)
|
|
||||||
else
|
|
||||||
return json.decode(contents)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local data = getContents() or error('Invalid repository')
|
|
||||||
|
|
||||||
if data.message and data.message:find("API rate limit exceeded") then
|
|
||||||
error("Out of API calls, try again later")
|
|
||||||
end
|
|
||||||
|
|
||||||
if data.message and data.message == "Not found" then
|
|
||||||
error("Invalid repository")
|
|
||||||
end
|
|
||||||
|
|
||||||
local list = { }
|
local list = { }
|
||||||
for _,v in pairs(data.tree) do
|
for _, v in pairs(data.tree) do
|
||||||
if v.type == "blob" then
|
if v.type == "blob" then
|
||||||
v.path = v.path:gsub("%s","%%20")
|
v.path = v.path:gsub("%s", "%%20")
|
||||||
if not path then
|
if not path then
|
||||||
list[v.path] = {
|
list[v.path] = {
|
||||||
url = string.format(FILE_URL, user, repo, branch, v.path),
|
url = fileUrlFn(v.path),
|
||||||
size = v.size,
|
size = v.size,
|
||||||
}
|
}
|
||||||
elseif Util.startsWith(v.path, path) then
|
elseif Util.startsWith(v.path, path) then
|
||||||
local p = string.sub(v.path, #path)
|
local p = string.sub(v.path, #path)
|
||||||
list[p] = {
|
list[p] = {
|
||||||
url = string.format(FILE_URL, user, repo, branch, path .. p),
|
url = fileUrlFn(path .. p),
|
||||||
size = v.size,
|
size = v.size,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return list
|
return list
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function fetchTree(url)
|
||||||
|
local contents, msg = Util.httpGet(url, TREE_HEADERS)
|
||||||
|
if not contents then
|
||||||
|
error(string.format('Failed to download %s\n%s', url, msg), 2)
|
||||||
|
end
|
||||||
|
return json.decode(contents) or error('Invalid repository')
|
||||||
|
end
|
||||||
|
|
||||||
|
-- GitHub: user/repo/branch/subdir/
|
||||||
|
local function listGithub(repository)
|
||||||
|
local t = Util.split(repository, '(.-)/')
|
||||||
|
local user = table.remove(t, 1)
|
||||||
|
local repo = table.remove(t, 1)
|
||||||
|
local branch = table.remove(t, 1) or 'main'
|
||||||
|
local path = not Util.empty(t) and (table.concat(t, '/') .. '/') or nil
|
||||||
|
|
||||||
|
local data = fetchTree(string.format(GITHUB_TREE_URL, user, repo, branch))
|
||||||
|
return parseTree(data, path, function(p)
|
||||||
|
return string.format(GITHUB_FILE_URL, user, repo, branch, p)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Gitea: gitea://host/user/repo/branch/subdir/
|
||||||
|
local function listGitea(host, remainder)
|
||||||
|
local t = Util.split(remainder, '(.-)/')
|
||||||
|
local user = table.remove(t, 1)
|
||||||
|
local repo = table.remove(t, 1)
|
||||||
|
local branch = table.remove(t, 1) or 'main'
|
||||||
|
local path = not Util.empty(t) and (table.concat(t, '/') .. '/') or nil
|
||||||
|
|
||||||
|
local data = fetchTree(string.format(GITEA_TREE_URL, host, user, repo, branch))
|
||||||
|
return parseTree(data, path, function(p)
|
||||||
|
return string.format(GITEA_FILE_URL, host, user, repo, branch, p)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function git.list(repository)
|
||||||
|
local host_type, host, rest = repository:match('^(%w+)://(.-)/(.*)')
|
||||||
|
if host_type == 'gitea' then
|
||||||
|
return listGitea(host, rest)
|
||||||
|
end
|
||||||
|
return listGithub(repository)
|
||||||
|
end
|
||||||
|
|
||||||
return git
|
return git
|
||||||
|
|||||||
Reference in New Issue
Block a user