tg-api-lua/tools.lua

155 lines
3.3 KiB
Lua

--[[ Additional tools
-- (c) Er2 2021 <er2@dismail.de>
-- Zlib license
--]]
local tools = {
json = require 'json',
}
local json = tools.json
local https = require 'ssl.https'
local ltn12 = require 'ltn12'
local mp = require 'api.multipart'
function tools.fetchCmd(text)
return
text:match '/([%w_]+)', -- cmd
text:match '/[%w_]+@([%w_]+)' -- to
end
function tools.parseArgs(text)
-- inside quotes, buffer and final args
local iq, buf, args = false, '', {}
local qt, esc = nil, false -- quote type and escape, addition
-- helper function, add args and clear buffer
local function psh()
if #buf > 0 then table.insert(args, buf) end
buf, qt = '', nil
end
for i = 1, #text + 1 do
local v = text:sub(i, i)
-- if space and inside quotes, or end of string
if ((v == ' ' or v == '\n' or v == '\t') and not iq)
or v == ''
then psh()
elseif esc then esc, buf = false, buf.. v
elseif v == '\\' then esc = true
-- if (no current quote or same quote) and quote is supported
elseif (not qt or qt == v)
and (v == '"' or v == "'")
then psh()
qt, iq = v, not iq -- quote type, inside quote
else buf = buf.. v -- append buffer
end
end
return args
end
function tools.unparseArgs(args)
-- args to string
local text = ''
for i = 1, #args do
local v = args[i]
if type(v) == 'string' then
if v:match '%s'
then text = text.. '"'.. v ..'" '
else text = text.. v ..' '
end
end
end
return text
end
function tools._req(url, meth, data, ctype)
assert(url, 'Provide URL!')
assert(meth, 'Provide method!')
local resp = {}
local head = {
url = url,
method = meth,
headers = {
['Content-Type'] = ctype,
['Content-Length'] = #(data or ''),
},
source = ltn12.source.string(data),
sink = ltn12.sink.table(resp),
}
local succ, res = https.request(head)
if not succ then
print('Connection error [' .. res .. ']')
return nil, false
end
return resp[1], true
end
function tools.preq(url, par)
par = par or {}
local body, bound = mp.encode(par)
return tools._req(
url,
'POST',
body,
'multipart/form-data; boundary=' .. bound
)
end
function tools.greq(url, par, f)
par = json.encode(par)
return tools._req(url, 'GET', par, 'application/json')
end
function tools.req(url, par, f, dbg)
local res, succ
par = par or {}
-- files
if f and next(f) ~= nil then
par = par or {}
for k, v in pairs(par) do par[k] = tostring(v) end
local ft, fn = next(f)
local fr = io.open(fn, 'r')
if fr then
par[ft] = {
filename = fn,
data = fr:read '*a'
}
fr:close()
else par[ft] = fn end
res, succ = tools.preq(url, par)
else -- text
res, succ = tools.greq(url, par)
end
if dbg then print(url, succ, res, par)
-- dump(par))
end
local s, res = pcall(json.decode, res or '{}')
if not s or not succ or not res then return {}, false end
return res, true
end
function tools.request(token, endpoint, param, f)
assert(token, 'Provide token!')
assert(endpoint, 'Provide endpoint!')
local url = 'https://api.telegram.org/bot' ..token.. '/' ..endpoint
--dbg = true
local resp = tools.req(url, param, f, dbg)
return resp, resp.ok or false
end
return tools