Skip to content

Instantly share code, notes, and snippets.

@ochaton
Last active December 27, 2022 17:23
Show Gist options
  • Save ochaton/22094b6c1b2f39403fe9d0a4df9d84cf to your computer and use it in GitHub Desktop.
Save ochaton/22094b6c1b2f39403fe9d0a4df9d84cf to your computer and use it in GitHub Desktop.
Github gist loader
#!/usr/bin/tarantool
--[[
gists = assert(loadstring(require"json".decode(require"http.client".get("https://api.github.com/gists/22094b6c1b2f39403fe9d0a4df9d84cf",{headers={["User-Agent"]="curl/7.86.0"}}).body).files["gist.lua"].content))()
]]
local M = {}
local fio = require 'fio'
local fun = require 'fun'
local uri = require 'uri'
local json = require 'json'
local httpc = require 'http.client'.new({})
package.loaders[9] = function(path)
return M.load(path)
end
local http_opts = { timeout = 3, headers = { ['User-Agent'] = 'curl/7.86.0' } }
local api_url = {scheme='https',service='api.github.com'}
local gist_url = setmetatable({path='/gists/{{gist_id}}'},{__index=api_url})
function M.search(path)
local paths = path:split("/")
local gist_id, libname
if #paths == 1 then
gist_id = paths[1]
elseif #paths == 2 then
gist_id, libname = paths[1], paths[2]
else
return false, ("malformed path %s should be <gist-id>[/<filename>]")
end
local url = uri.format(gist_url):gsub("{{(.+)}}", {gist_id = gist_id})
local res = httpc:get(url, http_opts)
if res.status ~= 200 then
return false, ("httpc to %s failed: http not 200: %s %s"):format(url, res.status, res.body)
end
local response = json.decode(res.body)
libname = libname or 'init'
local _, file = fun.iter(response.files)
:grep(function(_, file)
return fio.basename(file.filename, '%.lua') == libname
end)
:nth(1)
if not file then
return false, ("no library %q found in gist %q"):format(libname, gist_id)
end
return file.raw_url
end
function M.load(path)
local url, err = M.search(path)
if not url then
return url, err
end
local res = httpc:get(url, http_opts)
if res.status ~= 200 then
return false, ("given url %q for %q responded with not-200 %s %s"):format(url, path, res.status, res.body)
end
local func = assert(loadstring(res.body))
return function(...)
return func(...)
end
end
local list_url = setmetatable({ path = '/users/{{username}}/gists' },{__index=api_url})
function M.list(username)
assert(username, "username is required")
local url = uri.format(list_url):gsub("{{(.+)}}", { username = username })
local res = httpc:get(url, http_opts)
if res.status ~= 200 then
return false, ("httpc to %s failed: http not 200: %s %s"):format(url, res.status, res.body)
end
local ret = json.decode(res.body)
return fun.iter(ret)
:map(function(gist)
return {
id = gist.id,
updated_at = gist.updated_at,
created_at = gist.created_at,
description = gist.description,
files = fun.iter(gist.files)
:map(function(key, file)
return key, {
filename = file.filename,
size = file.size,
type = file.type,
raw_url = file.raw_url,
language = file.language,
}
end)
:tomap()
}
end)
:totable()
end
return M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment