diff --git a/.gitignore b/.gitignore index cb32b3d..41c51bc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,3 @@ *~ \#*# -src/*/*.lua diff --git a/readme.org b/readme.org index 20b62f1..3e429ac 100644 --- a/readme.org +++ b/readme.org @@ -15,8 +15,6 @@ and use it or fallback to English. Bot uses an OOP-style of Lua as [[https://is.gd/f0Vadk][described on Wikipedia]]. -For more readability bot's userland written in MoonScript. - Maybe I will rewrite bot's core to C but here already so many Lua code. * Installation @@ -29,8 +27,6 @@ Maybe I will rewrite bot's core to C but here already so many Lua code. + Install LuaSec for https requests: ~luarocks-5.3 install luasec~ - + Install MoonScript: ~luarocks-5.1 install moonscript~ - + Create user: ~adduser user~ setup it (add to doas) and login to this user @@ -41,8 +37,6 @@ Maybe I will rewrite bot's core to C but here already so many Lua code. + Change token and owner in *config.lua* - + Compile bot: ~moonc src/~ - + Add service ~doas cp bot.rc /etc/init.d/mybot && doas chmod +x /etc/init.d/mybot~ + Configure it ~doas vi /etc/init.d/mybot~ (change user) diff --git a/src/cmds/eval.lua b/src/cmds/eval.lua new file mode 100644 index 0000000..e2dec1b --- /dev/null +++ b/src/cmds/eval.lua @@ -0,0 +1,51 @@ +local function prind(...) + local t = {...} + local s = '' + for i = 1, #t do + if i > 1 then s = s..'\t' end + s = s .. tostring(t[i] or 'nil') + end + return s .. '\n' +end + +local env = { + assert = assert, + error = error, + ipairs = ipairs, + pairs = pairs, + next = next, + tonumber = tonumber, + tostring = tostring, + type = type, + pcall = pcall, + xpcall = xpcall, + + math = math, + string = string, + table = table, + + dump = dump, +} + +return { + private = true, + run = function(C, msg, owner) + local s = '' + local t = { + msg = msg, + print = function(...) s = s .. prind(...) end, + + C = owner and C or nil, + api = owner and C.api or nil, + } + for k,v in pairs(env) do t[k] = v end + local e, err = load(C.api.unparseArgs(msg.args), 'eval', 'bt', t) + xpcall(function() + if err then error(err) end + e = tostring(e() or '...') + end, function(err) e = err end) + s = s ..'\n'.. e + s = s:gsub(C.api.token:escp(), '') + C.api:reply(msg, s) + end +} diff --git a/src/cmds/eval.moon b/src/cmds/eval.moon deleted file mode 100644 index cd89cc4..0000000 --- a/src/cmds/eval.moon +++ /dev/null @@ -1,54 +0,0 @@ -prind = (...) -> - t = {...} - s = '' - for i = 1, #t - if i > 1 - s ..= '\t' - s ..= tostring t[i] or 'nil' - s .. '\n' - -env = - assert: assert - error: error - ipairs: ipairs - pairs: pairs - next: next - tonumber: tonumber - tostring: tostring - type: type - pcall: pcall - xpcall: xpcall - - math: math - string: string - table: table - - dump: dump - -{ - private: true - run: (msg, owner) => - s = '' - t = - msg: msg - print: (...) -> s ..= prind ... - - C: owner and @ or nil - api: owner and @api or nil - - for k, v in pairs env - t[k] = v - - e, err = load @api.unparseArgs(msg.args), 'eval', 'bt', t - - xpcall (-> - error err if err - e = tostring e! or '...' - ), (err) -> e = err - - s ..= '\n'.. e - s = s\gsub @api.token\escp!, '' - - @api\reply msg, s - return -} diff --git a/src/cmds/ping.lua b/src/cmds/ping.lua new file mode 100644 index 0000000..78e0726 --- /dev/null +++ b/src/cmds/ping.lua @@ -0,0 +1,11 @@ +return { + run = function(C, msg) + local t = os.time() + local ps, ls, lm, lh, ld + ps, ls = t - msg.date, t - C.loaded + lm = ls / 60 + lh = lm / 60 + ld = lh / 24 + C.api:send(msg, msg.loc.pat:format(ps, ld, lh, lm, ls)) + end +} diff --git a/src/cmds/ping.moon b/src/cmds/ping.moon deleted file mode 100644 index ba17429..0000000 --- a/src/cmds/ping.moon +++ /dev/null @@ -1,10 +0,0 @@ -{ - run: (msg) => - t = os.time! - ps, ls = t - msg.date, t - @loaded - lm = ls / 60 - lh = lm / 60 - ld = lh / 24 - @api\send msg, msg.loc.pat\format ps, ld, lh, lm, ls - return -} diff --git a/src/cmds/reload.lua b/src/cmds/reload.lua new file mode 100644 index 0000000..26b0665 --- /dev/null +++ b/src/cmds/reload.lua @@ -0,0 +1,22 @@ +return { + private = true, + run = function(C, msg) + local cat, sub = table.unpack(msg.args) + if not (cat and sub) then + return C.api:reply(msg, '/reload cmds ping') + end + + local path = 'src.'..cat..'.'..sub + C.api:off(package.loaded[path]) + package.loaded[path] = nil + local suc, m = pcall(require, path) + + if not suc then return C.api:reply(msg, 'Reload failed. ' .. m) + elseif cat == 'events' then C.api:on(sub, m) + elseif cat == 'cmds' then C.cmds[sub] = m + elseif cat == 'parts' then m(C) + end + + C.api:reply(msg, 'Reloaded. ' .. tostring(m)) + end +} diff --git a/src/cmds/reload.moon b/src/cmds/reload.moon deleted file mode 100644 index 74dc69a..0000000 --- a/src/cmds/reload.moon +++ /dev/null @@ -1,23 +0,0 @@ -{ - private: true - run: (msg) => - cat, sub = table.unpack msg.args - if not (cat and sub) - return @api\reply msg, '/reload cmds ping' - - path = "src.#{cat}.#{sub}" - - @api\off package.loaded[path] - package.loaded[path] = nil - - suc, m = pcall require, path - - if not suc then return @api\reply msg, 'Reload failed. '.. m - else switch cat - when 'events' then @api\on sub, m - when 'cmds' then @cmds[sub] = m - when 'parts' then m @ - - @api\reply msg, "Reloaded. #{m}" - return -} diff --git a/src/cmds/rub.lua b/src/cmds/rub.lua new file mode 100644 index 0000000..d0a02ec --- /dev/null +++ b/src/cmds/rub.lua @@ -0,0 +1,79 @@ +-- It uses data from central bank of Russia +--- and external service to get json from xml +-- Privacy and security is unknown + +local rub = { + url = 'https://api.factmaven.com/xml-to-json/?xml=' + .. 'https://www.cbr.ru/scripts/XML_daily.asp', + + tools = require 'etc.api.tools', +} + +function rub:course(wants) + local resp, succ = self.tools._req(self.url, 'GET') + if not succ then return 'err' end + resp = self.tools.json.decode(resp or '{}') + + resp = resp.ValCurs + table.insert(resp.Valute, { + ID = 'R01000', + NumCode = '001', + CharCode = 'RUB', + Nominal = 1, + Name = 'Российский рубль', + Value = '1' + }) + local uah = table.findV(resp.Valute, {CharCode = 'UAH'}) + table.insert(resp.Valute, { + ID = 'R02000', + NumCode = '200', + CharCode = 'SHT', + Nominal = 1, + Name = 'Штаны', + Value = ('%f'):format(tonumber(uah.Value:gsub(',', '.'), nil) / uah.Nominal * 40) + }) + + wants = type(wants) == 'table' and wants or {} + local r, founds = {}, {} + + if table.find(wants, 'HELP') + or table.find(wants, 'ALL') + then + for _, v in pairs(resp.Valute) do + table.insert(r, ('%d %s (%s) = %f Руб.'):format(v.Nominal, v.Name, v.CharCode, v.Value:gsub(',', '.'))) + end + return r, resp.Date, wants + end + + 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, ('%d %s (%s) - %f ₽'):format(v.Nominal, v.Name, v.CharCode, v.Value:gsub(',', '.'))) + end + end + + return r, resp.Date, founds +end + +return { + 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', msg.l)) + 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 +} diff --git a/src/cmds/rub.moon b/src/cmds/rub.moon deleted file mode 100644 index 83af9b6..0000000 --- a/src/cmds/rub.moon +++ /dev/null @@ -1,74 +0,0 @@ --- It uses data from central bank of Russia ---- and external service to get json from xml --- Privacy and security is unknown - -rub = - url: 'https://api.factmaven.com/xml-to-json/?xml=https://www.cbr.ru/scripts/XML_daily.asp' - - tools: require 'etc.api.tools' - - pat: '%d %s (%s) - %f ₽' - - getPat: (val) => - @pat\format val.Nominal, val.Name, val.CharCode, val.Value\gsub ',', '.' - - course: (wants) => - res, suc = @tools._req @url, 'GET' - return 'err' if not suc - res = @tools.json.decode res or '{}' - - res = res.ValCurs - table.insert res.Valute, { - ID: 'R01000' - NumCode: '001' - CharCode: 'RUB' - Nominal: 1 - Name: 'Российский рубль', - Value: '1' - } - uah = table.findV res.Valute, CharCode: 'UAH' - table.insert res.Valute, { - ID: 'R02000' - NumCode: '200' - CharCode: 'SHT' - Nominal: 1 - Name: 'Штаны' - Value: ('%f')\format tonumber(uah.Value\gsub(',', '.'), nil) / uah.Nominal * 40 - } - - wants = type(wants) == 'table' and wants or {} - r, founds = {}, {} - - if table.find wants, 'ALL' - for _, v in pairs res.Valute - table.insert r, @getPat v - return r, res.Date, wants - - for _, v in pairs res.Valute - if table.find wants, v.CharCode - table.insert founds, v.CharCode - table.insert r, @getPat v - - return r, res.Date, founds - -{ - run: (msg) => - wants = {'USD', 'EUR', table.unpack msg.args} - for i = 1, #wants - wants[i] = wants[i]\upper! - - v, d, f = rub\course wants - if v == 'error' - return @api\reply msg, @locale\get 'error', 'req_err', msg.l - - nf = {} - for _, i in pairs wants - table.insert nf, i if not table.find f, i - - s = msg.loc.cur\format d, table.concat v, '\n' - if #nf > 0 - s = s .. msg.loc.notf.. table.concat nf, ',' - - @api\reply msg, s.. msg.loc.prov - return -} diff --git a/src/cmds/start.lua b/src/cmds/start.lua new file mode 100644 index 0000000..4dd620e --- /dev/null +++ b/src/cmds/start.lua @@ -0,0 +1,6 @@ +return { + hide = true, + run = function(C, msg) + C.api:reply(msg, msg.loc.msg) + end +} diff --git a/src/cmds/start.moon b/src/cmds/start.moon deleted file mode 100644 index d65f196..0000000 --- a/src/cmds/start.moon +++ /dev/null @@ -1,6 +0,0 @@ -{ - hide: true - run: (msg) => - @api\reply msg, msg.loc.msg - return -} diff --git a/src/events/command.lua b/src/events/command.lua new file mode 100644 index 0000000..70f0dfd --- /dev/null +++ b/src/events/command.lua @@ -0,0 +1,29 @@ +return function(C, api, msg) + local cmd = C.cmds[msg.cmd] + local owner = msg.from.id == C.config.owner + local l = msg.from.language_code + + msg.l = l + + if cmd == nil then + api:send(msg, C.locale:get('error', 'inv_cmd', l)) + + elseif type(cmd.run) ~= 'function' then + api:send(msg, C.locale:get('error', 'cmd_run', l)) + + elseif cmd.private and not owner then + api:send(msg, C.locale:get('error', 'adm_cmd', l)) + + else + if cmd.useQArgs then msg.args = api.parseArgs(api.unparseArgs(msg.args)) end + msg.loc = C.locale:get('cmds', msg.cmd, l) + local succ, err = pcall(cmd.run, C, msg, owner) + if not succ then + print(err) + local cid = C.config.owner + api:forward(cid, msg.chat.id, msg.message_id, false) + api:send(cid, err) + api:reply(msg, C.locale:get('error', 'not_suc', l)) + end + end +end diff --git a/src/events/command.moon b/src/events/command.moon deleted file mode 100644 index cc0fcf9..0000000 --- a/src/events/command.moon +++ /dev/null @@ -1,28 +0,0 @@ -(api, msg) => - l = msg.from.language_code - owner = msg.from.id == @config.owner - cmd = @cmds[msg.cmd] - - msg.l = l - - if not cmd - api\send msg, @locale\get 'error', 'inv_cmd', l - - elseif type(cmd.run) ~= 'function' - api\send msg, @locale\get 'error', 'cmd_run', l - - elseif cmd.private and not owner - api\send msg, @locale\get 'error', 'adm_cmd', l - - else - msg.args = api.parseArgs api.unparseArgs msg.args if cmd.useQArgs - msg.loc = @locale\get 'cmds', msg.cmd, l - - suc, err = pcall cmd.run, @, msg, owner - if not suc - -- whoops - print err - api\forward @config.owner, msg.chat.id, msg.message_id, false - api\send @config.owner, err - api\reply msg, @locale\get 'error', 'not_suc', l - return diff --git a/src/events/inlineQuery.lua b/src/events/inlineQuery.lua new file mode 100644 index 0000000..b521fa6 --- /dev/null +++ b/src/events/inlineQuery.lua @@ -0,0 +1,8 @@ +return function(C, api, q) + api.inline + :answer(q.id, api.inline.result( + 'photo', '1', + 'https://cdn.discordapp.com/attachments/871474214270554124/876506659311202395/unknown.png' + ):thumb 'https://cdn.discordapp.com/attachments/871474214270554124/876506659311202395/unknown.png' + ) +end diff --git a/src/events/inlineQuery.moon b/src/events/inlineQuery.moon deleted file mode 100644 index eeba63d..0000000 --- a/src/events/inlineQuery.moon +++ /dev/null @@ -1,6 +0,0 @@ -(api, q) => - api.inline\answer q.id, api.inline.result( - 'photo', '1', - 'https://cdn.discordapp.com/attachments/871474214270554124/876506659311202395/unknown.png' - )\thumb 'https://cdn.discordapp.com/attachments/871474214270554124/876506659311202395/unknown.png' - return diff --git a/src/events/message.lua b/src/events/message.lua new file mode 100644 index 0000000..7a58c92 --- /dev/null +++ b/src/events/message.lua @@ -0,0 +1,25 @@ +local reg = { + {'эх', 'хуех'}, -- надоели эхать + {'мета', 'хуета'}, + {'meta', 'xueta'}, + {'цукерберг', 'цукерхуй'}, + {'zuckerberg', 'zuckerhui'}, + {'whatsapp', 'вадзад'}, + {'tiktok', 'деградация'}, + {'.*че%?*$', 'пиши ё, грамотей'}, + {'.*чё%?*$', 'ничё'} +} + +return function(C, api, msg) + if msg.text then + msg.text = utf8.lower(msg.text) + local t = '' + for _, v in pairs(reg) do + if msg.text:match(v[1]) + then t = t.. v[2] ..' ' + end + end + if t ~= '' + then api:reply(msg, t) end + end +end diff --git a/src/events/message.moon b/src/events/message.moon deleted file mode 100644 index 3cf078e..0000000 --- a/src/events/message.moon +++ /dev/null @@ -1,22 +0,0 @@ -reg = { - {'эх', 'хуех'} -- надоели эхать - {'мета', 'хуета'} - {'meta', 'xueta'} - {'цукерберг', 'цукерхуй'} - {'zuckerberg', 'zuckerhui'} - {'whatsapp', 'вадзад'} - {'tiktok', 'деградация'} - {'.*че%?*$', 'пиши ё, грамотей'} - {'.*чё%?*$', 'ничё'} -} - -(api, msg) => - if msg.text - msg.text = utf8.lower msg.text - t = '' - for _, v in pairs reg - if msg.text\match v[1] - t ..= "#{v[2]} " - - api\reply msg, t if t ~= '' - return diff --git a/src/events/ready.lua b/src/events/ready.lua new file mode 100644 index 0000000..0455b87 --- /dev/null +++ b/src/events/ready.lua @@ -0,0 +1,61 @@ +function table.indexOf(t, w) + local i = {} + for k,v in pairs(t) do i[v] = k end + return i[w] +end + +function table.find(t, w) + for _,v in pairs(t) do + if v == w then return v end + end +end + +function table.findV(t, w) + local b + for _,v in pairs(t) do + for k,x in pairs(w) do + if x ~= v[k] then b=1; break end + end + if b then b = nil + else return v end + end +end + +function string.escp(s) + return s:gsub('[%^%$%%%(%)%.%[%]%*%+%-%?]', '%%%0') +end + +function dump(t, d) + if not tonumber(d) or d < 0 then d = 0 end + local c = '' + for k,v in pairs(t) do + if type(v) == 'table' then v = '\n' .. dump(v, d + 1) end + c = c .. string.format('%s%s = %s\n', (' '):rep(d), k, v) + end + return c +end + +return function(C, api) + C:load 'cmds' + local a + for _, lang in pairs(C.locale.list) do + a = {} + for k, v in pairs(C.cmds) do + if not (v.private or v.hide) then + local cmd = C.locale:get('cmds', k, lang) or {} + table.insert(a, { + command = k, + description = (cmd.args and cmd.args .. ' - ' or '') .. (cmd.desc or C.locale:get('cmds', 'not_des')) + }) + end + end + api:setMyCommands(a, lang) + end + +--[[ + a = {'levels', } + for i = 1, #a do + if not C.db[a[i] ] then C.db[a[i] ] = {} end + end +--]] +end diff --git a/src/events/ready.moon b/src/events/ready.moon deleted file mode 100644 index e0e1551..0000000 --- a/src/events/ready.moon +++ /dev/null @@ -1,50 +0,0 @@ - -table.indexOf = (t, w) -> - i = {} - for k, v in pairs t - i[v] = k - i[w] - -table.find = (t, w) -> - for _, v in pairs t - return v if v == w - -table.findV = (t, w) -> - b = nil - for _, v in pairs t - for k, x in pairs w - if x ~= v[k] - b = 1 - break - if b then b = nil -- continue - else return v - -string.escp = (s) -> - s\gsub '[%^%$%%%(%)%.%[%]%*%+%-%?]', '%%%0' - -export dump = (t, d) -> - d = 0 if not tonumber(d) or d < 0 - c = '' - for k, v in pairs t - if type(v) == 'table' - v = '\n'.. dump v, d + 1 - - elseif type(v) == 'userdata' - v = '' - - c ..= ('%s%s = %s\n')\format (' ')\rep d, k, v - c - -(api) => - @\load 'cmds' - - for _, lang in pairs @locale.list - a = {} - for k, v in pairs @cmds - if not (v.private or v.hide) - cmd = @locale\get 'cmds', k, lang or {} - table.insert a, {command: k, - description: (cmd.args and cmd.args .. ' - ' or '') .. (cmd.desc or @locale\get 'cmds', 'not_des') - } - api\setMyCommands a, lang - return diff --git a/src/parts/client.lua b/src/parts/client.lua new file mode 100644 index 0000000..d544e89 --- /dev/null +++ b/src/parts/client.lua @@ -0,0 +1,35 @@ +local tg = require 'etc.api' + +return function(Core) + local self = Core + + self.api = tg { norun = true } + self.cmds = {} + + print 'Client initialization...' + + function Core._ev(ev, ...) self:ev(...) end + function self.api._ev(_, t, i, n, ...) + self._ev(_, t, i, n, self.api, ...) + end + + self:load 'events' + + self.api:login(self.config.token, function() + print('Logged on as @' .. self.api.info.username) + self.config.token = nil + self.api:emit 'ready' + end) + + local offs, o = 0 + self.api.runs = true + self:on('ready', function() + while self.api.runs do + self:emit 'tick' + + o = self.api:_getUpd(1, offs, 0) + offs = o and o or offs + end + self.api:getUpdates(1, offs, 0) + end) +end diff --git a/src/parts/client.moon b/src/parts/client.moon deleted file mode 100644 index 19f3c2e..0000000 --- a/src/parts/client.moon +++ /dev/null @@ -1,32 +0,0 @@ -tg = require 'etc.api' - -=> - @api = tg { norun: true } - @cmds = {} - - print 'Client initialization...' - - @_ev = (ev, ...) -> @\ev ... - @api._ev = (_, t, i, n, ...) -> - @._ev _, t, i, n, @api, ... - - @\load 'events' - - @api\login @config.token, -> - print "Logged on as @#{@api.info.username}" - @config.token = nil - @api\emit 'ready' - return - - offs, o = 0 - @api.runs = true - @\on 'ready', -> - while @api.runs - @\emit 'tick' - - o = @api\_getUpd 1, offs, 0 - offs = o and o or offs - - @api\getUpdates 1, offs, 0 - return - return diff --git a/src/parts/core.lua b/src/parts/core.lua new file mode 100644 index 0000000..fa3523f --- /dev/null +++ b/src/parts/core.lua @@ -0,0 +1,57 @@ +local config = require 'config' + +local Core = { + config = config, + loaded = 0, +} +(require 'etc.events')(Core) -- add events + +function Core:load(what) + local c = config[what] + local s = #c + for i = 1, s do + local v = c[i] + + print(('Loading %s (%d / %d) %s...'):format(what:sub(0, -2), i, s, v)) + -- Lint + local e, a = pcall(require, 'src.'.. what ..'.'.. v) + print(e, a) + if e then + if what == 'events' then self.api:on(v, a) + elseif what == 'cmds' then self.cmds[v] = a + elseif what == 'parts' then a(self) + end + else print 'fail' end + end + print(('Loaded %d %s'):format(s, what)) + self.loaded = os.time() +end + +function Core:ev(t, i, name, ...) + local v = t[i] + if v.name == name then + 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 + +function Core:init() + self:load 'parts' + + utf8 = require 'etc.utf8' + + print 'Done!' + self:emit 'ready' +end + +function Core:stop() + self.api:destroy() + print 'Stopped' + print('Uptime: '.. os.time() - self.loaded.. ' seconds') +end + +Core:init() diff --git a/src/parts/core.moon b/src/parts/core.moon deleted file mode 100644 index 95c084f..0000000 --- a/src/parts/core.moon +++ /dev/null @@ -1,52 +0,0 @@ -config = require 'config' - -Core = - config: config - loaded: 0 - - load: (what) => - c = config[what] - - for i = 1, #c - v = c[i] - - print "Loading #{what\sub 0, -2} (#{i} / #{#c}) #{v}..." - -- Lint - e, a = pcall require, "src.#{what}.#{v}" - print e, a - if e - switch what - when 'events' then @api\on v, a - when 'cmds' then @cmds[v] = a - when 'parts' then a @ - else print 'fail' - print "Loaded #{#c} #{what}" - @loaded = os.time! - - ev: (t, i, name, ...) => - v = t[i] - if v.name == name - suc, err = pcall v.fn, @, ... - if not suc - print "event \"#{name}\" was failed" - print err - table.remove t, i if v.type == 'once' - - init: => - @\load 'parts' - - export utf8 = require 'etc.utf8' - - print 'Done!' - @\emit 'ready' - return - - stop: => - @api\destroy! - print 'Stopped' - print "Uptime: #{os.time! - @loaded} seconds" - return - -require('etc.events')(Core) -- add events -Core\init! -return diff --git a/src/parts/locale.lua b/src/parts/locale.lua new file mode 100644 index 0000000..dce7141 --- /dev/null +++ b/src/parts/locale.lua @@ -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] or {})[cat] + if not v then + return self[self.main][cat][k] + else return v[k] 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 diff --git a/src/parts/locale.moon b/src/parts/locale.moon deleted file mode 100644 index c345055..0000000 --- a/src/parts/locale.moon +++ /dev/null @@ -1,30 +0,0 @@ -Locale = - __newindex: -> -- ro - - list: { - 'en' - 'ru' - } - main: 'en' - - get: (cat, k, lang) => - assert cat, 'Give category' - assert k, 'Give key' - lang or= @main - - v = (@[lang] or {})[cat] - if not v - @[@main][cat][k] or {} - else v[k] or {} - -Locale.__index = Locale - -(C) -> - json = require 'etc.json' - - for i = 1, #Locale.list - n = Locale.list[i] - f = io.open "src/locales/#{n}.json" - Locale[n] = json.decode f\read 'a' - - C.locale = setmetatable {}, Locale