add locales, need @ in groups

This commit is contained in:
Er2 2021-07-26 16:12:03 +03:00
parent e8fc2791e0
commit 2c660c0a09
14 changed files with 172 additions and 68 deletions

View file

@ -6,6 +6,8 @@ but on Telegram.
Bot uses an OOP-style of lua
as [described on Wikipedia](https://is.gd/f0Vadk)
Also, bot automatically detects language installed in the client.
TODO: Rewrite core to C, [lua have C API](https://www.lua.org/manual/5.3/manual.html#4)
and C is faster.

View file

@ -3,12 +3,17 @@ return {
owner = 935626920 , -- hehe
cmds = {
'eval',
'rub',
'ping',
'rub',
'start',
},
events = {
'command',
'message',
'ready',
},
}
parts = {
'locale',
'db',
'client',
},
}

View file

@ -30,20 +30,24 @@ local function receiveUpdate(self, update)
if update then self:emit('update', update) end
if update.message then
local txt = update.message.text
local cmd, to = tools.fetchCmd(txt)
local msg = update.message
local cmd, to = tools.fetchCmd(msg.text or '')
if cmd and (not to or to == self.info.username) then
-- need /cmd@bot in groups
if (msg.chat.type == 'group' or msg.chat.type == 'supergroup')
and not to then return end
local args = {}
txt = txt:sub(#cmd + #(to or {}) + 3)
for s in txt:gmatch '%S+' do table.insert(args, s) end
txt = msg.text:sub(#cmd + #(to or {}) + 3)
for s in msg.text:gmatch '%S+' do table.insert(args, s) end
update.message.cmd = cmd
update.message.args = args
msg.cmd = cmd
msg.args = args
return self:emit('command', update.message)
return self:emit('command', msg)
elseif cmd then return end
self:emit('message', update.message)
self:emit('message', msg)
elseif update.edited_message then
self:emit('messageEdit', update.edited_message)

View file

@ -29,8 +29,6 @@ local env = {
return {
private = true,
args = '<code>',
desc = 'evaluates code',
run = function(C, msg, owner)
local s = ''
local t = {

View file

@ -1,6 +1,5 @@
return {
desc = 'ping pong',
run = function(C, msg)
C.api:send(msg, 'Pong! ' .. (os.time() - msg.date) .. 's')
C.api:send(msg, msg.loc.pat:format(os.time() - msg.date))
end
}

View file

@ -5,64 +5,56 @@
local rub = {
url = 'https://api.factmaven.com/xml-to-json/?xml='
.. 'https://www.cbr.ru/scripts/XML_daily.asp',
fmt = function(v, fmt)
fmt = type(fmt) == 'string' and fmt or '%d %s = %f'
return fmt:format(v.Nominal, v.Name, v.Value:gsub(',', '.'))
end
tools = require 'etc.api.tools',
}
function rub:course(wants, fmt)
local resp, succ = (require 'etc.api.tools').requ(self.url)
if not succ then
return {}, '[ошибка]', {}
end
function rub:course(wants)
local resp, succ = self.tools.requ(self.url)
if not succ then return 'err' end
resp = resp.ValCurs
table.insert(resp.Valute, {
ID = 'R01000',
NumCode = '001',
CharCode = 'RUB',
Nominal = 1,
Name = 'Российский рубль',
Value = '1'
})
wants = type(wants) == 'table' and wants or {}
local r, founds = {}, {}
for i = 1, #resp.Valute do
local v = resp.Valute[i]
if table.find(wants, v.CharCode) then
table.insert(founds, v.CharCode)
table.insert(r, self.fmt(v, fmt))
table.insert(r, ('%d %s (%s) - %f ₽'):format(v.Nominal, v.Name, v.CharCode, v.Value:gsub(',', '.')))
end
end
local i = table.find(wants, 'RUB')
if i then
table.insert(founds, 'RUB')
table.insert(r, i, self.fmt({
Nominal = 1,
Name = 'Российский рубль',
Value = '1'
}, fmt) .. ' :D')
end
return r, resp.Date, founds
end
function rub.msg(C, msg)
local wants = {'USD', 'EUR', table.unpack(msg.args)}
for i = 1, #wants do wants[i] = wants[i]:upper() end
local v, d, f = rub:course(wants, '%d %s - %f ₽')
local nf = {}
for i = 1, #wants do
if not table.find(f, wants[i]) then
table.insert(nf, wants[i])
end
end
local s = 'Курс на ' .. d .. ':\n' .. table.concat(v, '\n')
if #nf > 0 then s = s .. '\n\n' .. 'Не нашлось: ' .. table.concat(nf, ', ') end
C.api:reply(msg, s .. '\nДанные от Центробанка России')
end
return {
args = '[valute]...',
desc = 'ruble course',
run = rub.msg
run = function(C, msg)
local wants = {'USD', 'EUR', table.unpack(msg.args)}
for i = 1, #wants do wants[i] = wants[i]:upper() end -- uppercase
local v, d, f = rub:course(wants)
if v == 'error' then
return C.api:reply(msg, C.locale:get('error', 'req_err'))
end
local nf = {}
for _, i in pairs(wants) do
if not table.find(f, i) then table.insert(nf, i) end
end
local s = msg.loc.cur:format(d, table.concat(v, '\n'))
if #nf > 0 then s = s .. msg.loc.notf .. table.concat(nf, ',') end
C.api:reply(msg, s .. msg.loc.prov)
end
}

6
src/cmds/start.lua Normal file
View file

@ -0,0 +1,6 @@
return {
hide = true,
run = function(C, msg)
C.api:reply(msg, 'TODO!')
end
}

View file

@ -1,23 +1,25 @@
return function(C, api, msg)
local cmd = C.cmds[msg.cmd]
local owner = msg.from.id == C.config.owner
if cmd == nil then
api:send(msg, 'Invaid command provided.')
api:send(msg, C.locale:get('error', 'inv_cmd'))
elseif type(cmd.run) ~= 'function' then
api:send(msg, 'Command cannot be executed.')
api:send(msg, C.locale:get('error', 'cmd_run'))
elseif cmd.private and not owner then
api:send(msg, 'You can\'t execute private commands!')
api:send(msg, C.locale:get('error', 'adm_cmd'))
else
msg.loc = C.locale:get('cmds', msg.cmd)
local succ, err = pcall(cmd.run, C, msg, owner)
if not succ then
api:reply(msg, 'Произошла ошибочка, которая была отправлена создателю')
print(err)
local cid = C.config.owner
api:forward(cid, msg.chat.id, msg.message_id, false)
api:send(cid, err)
api:reply(msg, msg.locale.error.not_suc)
end
end
end

View file

@ -1,3 +0,0 @@
return function(C, api, msg)
-- api:reply(msg, 'хай!')
end

View file

@ -29,10 +29,11 @@ return function(C, api)
C:load 'cmds'
local a = {}
for k, v in pairs(C.cmds) do
if not v.private then
if not (v.private or v.hide) then
local cmd = C.locale:get('cmds', k) or {}
table.insert(a, {
command = k,
description = (v.args and v.args .. ' - ' or '') .. v.desc or 'no description'
description = (cmd.args and cmd.args .. ' - ' or '') .. (cmd.desc or C.locale:get('cmds', 'not_des'))
})
end
end

31
src/locales/en.json Normal file
View file

@ -0,0 +1,31 @@
{
"error": {
"inv_cmd": "Invalid command provided.",
"adm_cmd": "You can't execute admin commands!",
"cmd_run": "This command cannot be executed now.",
"not_suc": "An error was occured which already sent to creator.",
"unk_err": "Unknown error.",
"req_err": "Request error."
},
"cmds": {
"not_des": "no description",
"eval": {
"args": "<code>",
"desc": "executes code"
},
"ping": {
"desc": "ping pong",
"pat": "Pong! %ds"
},
"rub": {
"args": "[valute]...",
"desc": "ruble course",
"cur": "Currency at %s:\n%s",
"notf": "\nNot found: ",
"prov": "\nData provided from central bank of Russia."
}
}
}

31
src/locales/ru.json Normal file
View file

@ -0,0 +1,31 @@
{
"error": {
"inv_cmd": "Указана неизвестная команда.",
"adm_cmd": "Вы не можете исполнять админские команды!",
"cmd_run": "Это команда не мжет быть выполнена сейчас.",
"not_suc": "Произошла ошибка, которая уже отправлена создателю.",
"unk_err": "Неизвестная ошибка.",
"req_err": "Ошибка запроса."
},
"cmds": {
"not_des": "нет описания",
"eval": {
"args": "<код>",
"desc": "исполняет код"
},
"ping": {
"desc": "пинг-понг",
"pat": "Понг! %d секунд"
},
"rub": {
"args": "[валюта]...",
"desc": "курс рубля",
"cur": "Курс на %s:\n%s",
"notf": "\nНе нашлось: ",
"prov": "\nДанные предоставлены центральным банком России."
}
}
}

View file

@ -28,8 +28,11 @@ end
function Core:ev(t, i, name, ...)
local v = t[i]
if v.name == name then
local succ = pcall(v.fn, self, ...)
if not succ then print('event "' .. name .. '" was failed') end
local succ, err = pcall(v.fn, self, ...)
if not succ then
print('event "' .. name .. '" was failed')
print(err)
end
if v.type == 'once' then table.remove(t, i) end
end
end

33
src/parts/locale.lua Normal file
View file

@ -0,0 +1,33 @@
local Locale = {
list = {
'en',
'ru'
},
main = 'en',
__newindex = function()end -- ro
}
Locale.__index = Locale
function Locale:get(cat, k, lang)
assert(cat, 'Give category')
assert(k, 'Give key')
lang = lang or self.main
local v = self[lang][cat][k]
if not v then
return self[self.main][cat][k]
else return v end
end
return function(C)
local json = require 'etc.json'
for i = 1, #Locale.list do
local n = Locale.list[i]
local f = io.open(('src/locales/%s.json'):format(n))
Locale[n] = json.decode(f:read 'a')
end
C.locale = setmetatable({}, Locale)
end