mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
This is an important refactor of the way documentation generation works
* Installs luarocks WITH it's executable (easy to install other rocks if necessary) * Use Lua supplied with luarocks * Create Utils/luadocumentor.bat, which works with RELATIVE PATH ! -> Everybody can generate the doc * Updated launch files accordingly
This commit is contained in:
284
Utils/luarocks/lua/luarocks/upload/api.lua
Normal file
284
Utils/luarocks/lua/luarocks/upload/api.lua
Normal file
@@ -0,0 +1,284 @@
|
||||
|
||||
local api = {}
|
||||
|
||||
local cfg = require("luarocks.cfg")
|
||||
local fs = require("luarocks.fs")
|
||||
local util = require("luarocks.util")
|
||||
local persist = require("luarocks.persist")
|
||||
local multipart = require("luarocks.upload.multipart")
|
||||
|
||||
local Api = {}
|
||||
|
||||
local function upload_config_file()
|
||||
local conf = cfg.which_config()
|
||||
if not conf.user.file then
|
||||
return nil
|
||||
end
|
||||
return (conf.user.file:gsub("/[^/]+$", "/upload_config.lua"))
|
||||
end
|
||||
|
||||
function Api:load_config()
|
||||
local upload_conf = upload_config_file()
|
||||
if not upload_conf then return nil end
|
||||
local cfg, err = persist.load_into_table(upload_conf)
|
||||
return cfg
|
||||
end
|
||||
|
||||
function Api:save_config()
|
||||
-- Test configuration before saving it.
|
||||
local res, err = self:raw_method("status")
|
||||
if not res then
|
||||
return nil, err
|
||||
end
|
||||
if res.errors then
|
||||
util.printerr("Server says: " .. tostring(res.errors[1]))
|
||||
return
|
||||
end
|
||||
local upload_conf = upload_config_file()
|
||||
if not upload_conf then return nil end
|
||||
persist.save_from_table(upload_conf, self.config)
|
||||
fs.chmod(upload_conf, "0600")
|
||||
end
|
||||
|
||||
function Api:check_version()
|
||||
if not self._server_tool_version then
|
||||
local tool_version = cfg.upload.tool_version
|
||||
local res, err = self:request(tostring(self.config.server) .. "/api/tool_version", {
|
||||
current = tool_version
|
||||
})
|
||||
if not res then
|
||||
return nil, err
|
||||
end
|
||||
if not res.version then
|
||||
return nil, "failed to fetch tool version"
|
||||
end
|
||||
self._server_tool_version = res.version
|
||||
if res.force_update then
|
||||
return nil, "Your upload client is too out of date to continue, please upgrade LuaRocks."
|
||||
end
|
||||
if res.version ~= tool_version then
|
||||
util.printerr("Warning: Your LuaRocks is out of date, consider upgrading.")
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Api:method(...)
|
||||
local res, err = self:raw_method(...)
|
||||
if not res then
|
||||
return nil, err
|
||||
end
|
||||
if res.errors then
|
||||
if res.errors[1] == "Invalid key" then
|
||||
return nil, res.errors[1] .. " (use the --api-key flag to change)"
|
||||
end
|
||||
local msg = table.concat(res.errors, ", ")
|
||||
return nil, "API Failed: " .. msg
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function Api:raw_method(path, ...)
|
||||
self:check_version()
|
||||
local url = tostring(self.config.server) .. "/api/" .. tostring(cfg.upload.api_version) .. "/" .. tostring(self.config.key) .. "/" .. tostring(path)
|
||||
return self:request(url, ...)
|
||||
end
|
||||
|
||||
local function encode_query_string(t, sep)
|
||||
if sep == nil then
|
||||
sep = "&"
|
||||
end
|
||||
local i = 0
|
||||
local buf = { }
|
||||
for k, v in pairs(t) do
|
||||
if type(k) == "number" and type(v) == "table" then
|
||||
k, v = v[1], v[2]
|
||||
end
|
||||
buf[i + 1] = multipart.url_escape(k)
|
||||
buf[i + 2] = "="
|
||||
buf[i + 3] = multipart.url_escape(v)
|
||||
buf[i + 4] = sep
|
||||
i = i + 4
|
||||
end
|
||||
buf[i] = nil
|
||||
return table.concat(buf)
|
||||
end
|
||||
|
||||
-- An ode to the multitude of JSON libraries out there...
|
||||
local function require_json()
|
||||
local list = { "cjson", "dkjson", "json" }
|
||||
for _, lib in ipairs(list) do
|
||||
local json_ok, json = pcall(require, lib)
|
||||
if json_ok then
|
||||
pcall(json.use_lpeg) -- optional feature in dkjson
|
||||
return json_ok, json
|
||||
end
|
||||
end
|
||||
local errmsg = "Failed loading "
|
||||
for i, name in ipairs(list) do
|
||||
if i == #list then
|
||||
errmsg = errmsg .."and '"..name.."'. Use 'luarocks search <partial-name>' to search for a library and 'luarocks install <name>' to install one."
|
||||
else
|
||||
errmsg = errmsg .."'"..name.."', "
|
||||
end
|
||||
end
|
||||
return nil, errmsg
|
||||
end
|
||||
|
||||
local function redact_api_url(url)
|
||||
url = tostring(url)
|
||||
return (url:gsub(".*/api/[^/]+/[^/]+", "")) or ""
|
||||
end
|
||||
|
||||
local ltn12_ok, ltn12 = pcall(require, "ltn12")
|
||||
if not ltn12_ok then -- If not using LuaSocket and/or LuaSec...
|
||||
|
||||
function Api:request(url, params, post_params)
|
||||
local vars = cfg.variables
|
||||
local json_ok, json = require_json()
|
||||
if not json_ok then return nil, "A JSON library is required for this command. "..json end
|
||||
|
||||
if cfg.downloader == "wget" then
|
||||
local curl_ok, err = fs.is_tool_available(vars.CURL, "curl")
|
||||
if not curl_ok then
|
||||
return nil, err
|
||||
end
|
||||
end
|
||||
|
||||
if not self.config.key then
|
||||
return nil, "Must have API key before performing any actions."
|
||||
end
|
||||
if params and next(params) then
|
||||
url = url .. ("?" .. encode_query_string(params))
|
||||
end
|
||||
local method = "GET"
|
||||
local out
|
||||
local tmpfile = fs.tmpname()
|
||||
if post_params then
|
||||
method = "POST"
|
||||
local curl_cmd = fs.Q(vars.CURL).." -f -k -L --silent --user-agent \""..cfg.user_agent.." via curl\" "
|
||||
for k,v in pairs(post_params) do
|
||||
local var = v
|
||||
if type(v) == "table" then
|
||||
var = "@"..v.fname
|
||||
end
|
||||
curl_cmd = curl_cmd .. "--form \""..k.."="..var.."\" "
|
||||
end
|
||||
if cfg.connection_timeout and cfg.connection_timeout > 0 then
|
||||
curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." "
|
||||
end
|
||||
local ok = fs.execute_string(curl_cmd..fs.Q(url).." -o "..fs.Q(tmpfile))
|
||||
if not ok then
|
||||
return nil, "API failure: " .. redact_api_url(url)
|
||||
end
|
||||
else
|
||||
local ok, err = fs.download(url, tmpfile)
|
||||
if not ok then
|
||||
return nil, "API failure: " .. tostring(err) .. " - " .. redact_api_url(url)
|
||||
end
|
||||
end
|
||||
|
||||
local tmpfd = io.open(tmpfile)
|
||||
if not tmpfd then
|
||||
os.remove(tmpfile)
|
||||
return nil, "API failure reading temporary file - " .. redact_api_url(url)
|
||||
end
|
||||
out = tmpfd:read("*a")
|
||||
tmpfd:close()
|
||||
os.remove(tmpfile)
|
||||
|
||||
if self.debug then
|
||||
util.printout("[" .. tostring(method) .. " via curl] " .. redact_api_url(url) .. " ... ")
|
||||
end
|
||||
|
||||
return json.decode(out)
|
||||
end
|
||||
|
||||
else -- use LuaSocket and LuaSec
|
||||
|
||||
local warned_luasec = false
|
||||
|
||||
function Api:request(url, params, post_params)
|
||||
local json_ok, json = require_json()
|
||||
if not json_ok then return nil, "A JSON library is required for this command. "..json end
|
||||
local server = tostring(self.config.server)
|
||||
local http_ok, http
|
||||
local via = "luasocket"
|
||||
if server:match("^https://") then
|
||||
http_ok, http = pcall(require, "ssl.https")
|
||||
if http_ok then
|
||||
via = "luasec"
|
||||
else
|
||||
if not warned_luasec then
|
||||
util.printerr("LuaSec is not available; using plain HTTP. Install 'luasec' to enable HTTPS.")
|
||||
warned_luasec = true
|
||||
end
|
||||
http_ok, http = pcall(require, "socket.http")
|
||||
url = url:gsub("^https", "http")
|
||||
via = "luasocket"
|
||||
end
|
||||
else
|
||||
http_ok, http = pcall(require, "socket.http")
|
||||
end
|
||||
if not http_ok then
|
||||
return nil, "Failed loading socket library!"
|
||||
end
|
||||
|
||||
if not self.config.key then
|
||||
return nil, "Must have API key before performing any actions."
|
||||
end
|
||||
local body
|
||||
local headers = {}
|
||||
if params and next(params) then
|
||||
url = url .. ("?" .. encode_query_string(params))
|
||||
end
|
||||
if post_params then
|
||||
local boundary
|
||||
body, boundary = multipart.encode(post_params)
|
||||
headers["Content-length"] = #body
|
||||
headers["Content-type"] = "multipart/form-data; boundary=" .. tostring(boundary)
|
||||
end
|
||||
local method = post_params and "POST" or "GET"
|
||||
if self.debug then
|
||||
util.printout("[" .. tostring(method) .. " via "..via.."] " .. redact_api_url(url) .. " ... ")
|
||||
end
|
||||
local out = {}
|
||||
local _, status = http.request({
|
||||
url = url,
|
||||
headers = headers,
|
||||
method = method,
|
||||
sink = ltn12.sink.table(out),
|
||||
source = body and ltn12.source.string(body)
|
||||
})
|
||||
if self.debug then
|
||||
util.printout(tostring(status))
|
||||
end
|
||||
if status ~= 200 then
|
||||
return nil, "API returned " .. tostring(status) .. " - " .. redact_api_url(url)
|
||||
end
|
||||
return json.decode(table.concat(out))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function api.new(flags)
|
||||
local self = {}
|
||||
setmetatable(self, { __index = Api })
|
||||
self.config = self:load_config() or {}
|
||||
self.config.server = flags["server"] or self.config.server or cfg.upload.server
|
||||
self.config.version = self.config.version or cfg.upload.version
|
||||
self.config.key = flags["api-key"] or self.config.key
|
||||
self.debug = flags["debug"]
|
||||
if not self.config.key then
|
||||
return nil, "You need an API key to upload rocks.\n" ..
|
||||
"Navigate to "..self.config.server.."/settings to get a key\n" ..
|
||||
"and then pass it through the --api-key=<key> flag."
|
||||
end
|
||||
if flags["api-key"] then
|
||||
self:save_config()
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
return api
|
||||
|
||||
111
Utils/luarocks/lua/luarocks/upload/multipart.lua
Normal file
111
Utils/luarocks/lua/luarocks/upload/multipart.lua
Normal file
@@ -0,0 +1,111 @@
|
||||
|
||||
local multipart = {}
|
||||
|
||||
local File = {}
|
||||
|
||||
local unpack = unpack or table.unpack
|
||||
|
||||
math.randomseed(os.time())
|
||||
|
||||
-- socket.url.escape(s) from LuaSocket 3.0rc1
|
||||
function multipart.url_escape(s)
|
||||
return (string.gsub(s, "([^A-Za-z0-9_])", function(c)
|
||||
return string.format("%%%02x", string.byte(c))
|
||||
end))
|
||||
end
|
||||
|
||||
function File:mime()
|
||||
if not self.mimetype then
|
||||
local mimetypes_ok, mimetypes = pcall(require, "mimetypes")
|
||||
if mimetypes_ok then
|
||||
self.mimetype = mimetypes.guess(self.fname)
|
||||
end
|
||||
self.mimetype = self.mimetype or "application/octet-stream"
|
||||
end
|
||||
return self.mimetype
|
||||
end
|
||||
|
||||
function File:content()
|
||||
local fd = io.open(self.fname, "rb")
|
||||
if not fd then
|
||||
return nil, "Failed to open file: "..self.fname
|
||||
end
|
||||
local data = fd:read("*a")
|
||||
fd:close()
|
||||
return data
|
||||
end
|
||||
|
||||
local function rand_string(len)
|
||||
local shuffled = {}
|
||||
for i = 1, len do
|
||||
local r = math.random(97, 122)
|
||||
if math.random() >= 0.5 then
|
||||
r = r - 32
|
||||
end
|
||||
shuffled[i] = r
|
||||
end
|
||||
return string.char(unpack(shuffled))
|
||||
end
|
||||
|
||||
-- multipart encodes params
|
||||
-- returns encoded string,boundary
|
||||
-- params is an a table of tuple tables:
|
||||
-- params = {
|
||||
-- {key1, value2},
|
||||
-- {key2, value2},
|
||||
-- key3: value3
|
||||
-- }
|
||||
function multipart.encode(params)
|
||||
local tuples = { }
|
||||
for i = 1, #params do
|
||||
tuples[i] = params[i]
|
||||
end
|
||||
for k,v in pairs(params) do
|
||||
if type(k) == "string" then
|
||||
table.insert(tuples, {k, v})
|
||||
end
|
||||
end
|
||||
local chunks = {}
|
||||
for _, tuple in ipairs(tuples) do
|
||||
local k,v = unpack(tuple)
|
||||
k = multipart.url_escape(k)
|
||||
local buffer = { 'Content-Disposition: form-data; name="' .. k .. '"' }
|
||||
local content
|
||||
if type(v) == "table" and v.__class == File then
|
||||
buffer[1] = buffer[1] .. ('; filename="' .. v.fname:gsub(".*/", "") .. '"')
|
||||
table.insert(buffer, "Content-type: " .. v:mime())
|
||||
content = v:content()
|
||||
else
|
||||
content = v
|
||||
end
|
||||
table.insert(buffer, "")
|
||||
table.insert(buffer, content)
|
||||
table.insert(chunks, table.concat(buffer, "\r\n"))
|
||||
end
|
||||
local boundary
|
||||
while not boundary do
|
||||
boundary = "Boundary" .. rand_string(16)
|
||||
for _, chunk in ipairs(chunks) do
|
||||
if chunk:find(boundary) then
|
||||
boundary = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
local inner = "\r\n--" .. boundary .. "\r\n"
|
||||
return table.concat({ "--", boundary, "\r\n",
|
||||
table.concat(chunks, inner),
|
||||
"\r\n", "--", boundary, "--", "\r\n" }), boundary
|
||||
end
|
||||
|
||||
function multipart.new_file(fname, mime)
|
||||
local self = {}
|
||||
setmetatable(self, { __index = File })
|
||||
self.__class = File
|
||||
self.fname = fname
|
||||
self.mimetype = mime
|
||||
return self
|
||||
end
|
||||
|
||||
return multipart
|
||||
|
||||
Reference in New Issue
Block a user