otouto 3.11
"things occurred" Added some utilities (id_from_username, id_from_message), removed some utilities (latcyr, others?). Removed cycle-wasting "shortcuts" -- no more automatic id_str or name; text_lower remains. Moved userdata (nicknames, lastfm, etc) to a different tree in the database (automatic migration will occur). /me now returns userdata. Speaking of migration, database now stores the latest version run to make future automigration easy. Database now saves hourly rather than minutely. Changed readme and some plugins to reflect above changes. Removed broken rockspec (Brayden, feel free to re-add once it's working). Added option to automatically block people (via drua) when blacklisted. Fixed about.lua trigger problems. administration 1.11 - Removed /kickme and /broadcast. Users should leave manually, and announcements should be made via channel rather than spam. /setqotd now handles forwarded messages correctly. /kick, /ban, /hammer, /mod, /admin now support multiple arguments. Added get_targets function. No migration is necessary.
This commit is contained in:
parent
69f0702365
commit
9ebdbd9d3c
66
README.md
66
README.md
@ -13,8 +13,9 @@ otouto is free software; you are free to redistribute it and/or modify it under
|
|||||||
|:----------------------------------------------|:------------------------------|
|
|:----------------------------------------------|:------------------------------|
|
||||||
| [Setup](#setup) | [Plugins](#plugins) |
|
| [Setup](#setup) | [Plugins](#plugins) |
|
||||||
| [Control plugins](#control-plugins) | [Bindings](#bindings) |
|
| [Control plugins](#control-plugins) | [Bindings](#bindings) |
|
||||||
| [Group Administration](#group-administration) | [Output style](#output-style) |
|
| [Group administration](#group-administration) | [Database](#database) |
|
||||||
| [List of plugins](#list-of-plugins) | [Contributors](#contributors) |
|
| [List of plugins](#list-of-plugins) | [Output style](#output-style) |
|
||||||
|
| | [Contributors](#contributors) |
|
||||||
|
|
||||||
* * *
|
* * *
|
||||||
|
|
||||||
@ -201,21 +202,22 @@ otouto uses a robust plugin system, similar to yagop's [Telegram-Bot](http://git
|
|||||||
|
|
||||||
Most plugins are intended for public use, but a few are for other purposes, like those for [use by the bot's owner](#control-plugins). See [here](#list-of-plugins) for a list of plugins.
|
Most plugins are intended for public use, but a few are for other purposes, like those for [use by the bot's owner](#control-plugins). See [here](#list-of-plugins) for a list of plugins.
|
||||||
|
|
||||||
A plugin can have five components, and two of them are required:
|
There are five standard plugin components.
|
||||||
|
|
||||||
| Component | Description | Required? |
|
| Component | Description |
|
||||||
|:------------------|:---------------------------------------------|:----------|
|
|:-----------|:-----------------------------------------------------|
|
||||||
| `plugin:action` | Main function. Expects `msg` table as an argument. | Y |
|
| `action` | Main function. Expects `msg` table as an argument. |
|
||||||
| `plugin.triggers` | Table of triggers for the plugin. Uses Lua patterns. | Y |
|
| `triggers` | Table of triggers for the plugin. Uses Lua patterns. |
|
||||||
| `plugin:init` | Optional function run when the plugin is loaded. | N |
|
| `init` | Optional function run when the plugin is loaded. |
|
||||||
| `plugin:cron` | Optional function to be called every minute. | N |
|
| `cron` | Optional function to be called every minute. |
|
||||||
| `plugin.command` | Basic command and syntax. Listed in the help text. | N |
|
| `command` | Basic command and syntax. Listed in the help text. |
|
||||||
| `plugin.doc` | Usage for the plugin. Returned by "/help $command". | N |
|
| `doc` | Usage for the plugin. Returned by "/help $command". |
|
||||||
| `plugin.error` | Plugin-specific error message; false for no message. | N |
|
| `error` | Plugin-specific error message; false for no message. |
|
||||||
|
|
||||||
The `bot:on_msg_receive` function adds a few variables to the `msg` table for your convenience. These are self-explanatory: `msg.from.id_str`, `msg.to.id_str`, `msg.chat.id_str`, `msg.text_lower`, `msg.from.name`.
|
|
||||||
|
|
||||||
Return values from `plugin:action` are optional, but they do effect the flow. If it returns a table, that table will become `msg`, and `on_msg_receive` will continue with that. If it returns `true`, it will continue with the current `msg`.
|
No component is required, but some depend on others. For example, `action` will never be run if there's no `triggers`, and `doc` will never be seen if there's no `command`.
|
||||||
|
|
||||||
|
Return values from `action` are optional, but they do affect the flow. If it returns a table, that table will become `msg`, and `on_msg_receive` will continue with that. If it returns `true`, it will continue with the current `msg`.
|
||||||
|
|
||||||
When an action or cron function fails, the exception is caught and passed to the `handle_exception` utilty and is either printed to the console or send to the chat/channel defined in `log_chat` in config.lua.
|
When an action or cron function fails, the exception is caught and passed to the `handle_exception` utilty and is either printed to the console or send to the chat/channel defined in `log_chat` in config.lua.
|
||||||
|
|
||||||
@ -266,7 +268,7 @@ utilities.send_message(self, 987654321, 'Quick brown fox.', false, 54321, true)
|
|||||||
Uploading a file for the `sendPhoto` method would look like this:
|
Uploading a file for the `sendPhoto` method would look like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
bindings.sendPhoto(self, { chat_id = 987654321 }, { photo = 'rarepepe.jpg' } )
|
bindings.sendPhoto(self, { chat_id = 987654321 }, { photo = 'dankmeme.jpg' } )
|
||||||
```
|
```
|
||||||
|
|
||||||
and using `sendPhoto` with a file ID would look like this:
|
and using `sendPhoto` with a file ID would look like this:
|
||||||
@ -279,6 +281,40 @@ Upon success, bindings will return the deserialized result from the API. Upon fa
|
|||||||
|
|
||||||
* * *
|
* * *
|
||||||
|
|
||||||
|
## Database
|
||||||
|
otouto doesn't use one. This isn't because of dedication to lightweightedness or some clever design choice. Interfacing with databases through Lua is never a simple, easy-to-learn process. As one of the goals of otouto is that it should be a bot which is easy to write plugins for, our approach to storing data is to treat our datastore like any ordinary Lua data structure. The "database" is a table accessible in the `database` value of the bot instance (usually `self.database`), and is saved as a JSON-encoded plaintext file each hour, or when the bot is told to halt. This way, keeping and interacting with persistent data is no different than interacting with a Lua table -- with one exception: Keys in tables used as associative arrays must not be numbers. If the index keys are too sparse, the JSON encoder/decoder will either change them to keys or throw an error.
|
||||||
|
|
||||||
|
Alone, the database will have this structure:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
users = {
|
||||||
|
["55994550"] = {
|
||||||
|
id = 55994550,
|
||||||
|
first_name = "Drew",
|
||||||
|
username = "topkecleon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
userdata = {
|
||||||
|
["55994550"] = {
|
||||||
|
nickname = "Worst coder ever",
|
||||||
|
lastfm = "topkecleon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
version = "3.11"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`database.users` will store user information (usernames, IDs, etc) when the bot sees the user. Each table's key is the user's ID as a string.
|
||||||
|
|
||||||
|
`database.userdata` is meant to store miscellanea from various plugins.
|
||||||
|
|
||||||
|
`database.version` stores the last bot version that used it. This is to simplify migration to the next version of the bot an easy, automatic process.
|
||||||
|
|
||||||
|
Data from other plugins is usually saved in a table with the same name of that plugin. For example, administration.lua stores data in `database.administration`.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
## Output style
|
## Output style
|
||||||
otouto plugins should maintain a consistent visual style in their output. This provides a recognizable and comfortable user experience.
|
otouto plugins should maintain a consistent visual style in their output. This provides a recognizable and comfortable user experience.
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ Send /help to get started.
|
|||||||
]],
|
]],
|
||||||
-- The symbol that starts a command. Usually noted as '/' in documentation.
|
-- The symbol that starts a command. Usually noted as '/' in documentation.
|
||||||
cmd_pat = '/',
|
cmd_pat = '/',
|
||||||
|
-- If drua is used, should a user be blocked when he's blacklisted? (and vice-versa)
|
||||||
|
drua_block_on_blacklist = false,
|
||||||
|
|
||||||
-- https://datamarket.azure.com/dataset/bing/search
|
-- https://datamarket.azure.com/dataset/bing/search
|
||||||
bing_api_key = '',
|
bing_api_key = '',
|
||||||
|
@ -151,4 +151,12 @@ drua.channel_set_about = function(chat, text)
|
|||||||
return drua.send(command)
|
return drua.send(command)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
drua.block = function(user)
|
||||||
|
return drua.send('block_user user#' .. user)
|
||||||
|
end
|
||||||
|
|
||||||
|
drua.unblock = function(user)
|
||||||
|
return drua.send('unblock_user user#' .. user)
|
||||||
|
end
|
||||||
|
|
||||||
return drua
|
return drua
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
package = 'otouto'
|
|
||||||
version = 'dev-1'
|
|
||||||
|
|
||||||
source = {
|
|
||||||
url = 'git://github.com/topkecleon/otouto.git'
|
|
||||||
}
|
|
||||||
|
|
||||||
description = {
|
|
||||||
summary = 'The plugin-wielding, multipurpose Telegram bot!',
|
|
||||||
detailed = 'A plugin-wielding, multipurpose bot for the Telegram API.',
|
|
||||||
homepage = 'http://otou.to',
|
|
||||||
maintainer = 'Drew <drew@otou.to>',
|
|
||||||
license = 'GPL-2'
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies = {
|
|
||||||
'lua >= 5.2',
|
|
||||||
'LuaSocket ~> 3.0',
|
|
||||||
'LuaSec ~> 0.6',
|
|
||||||
'dkjson ~> 2.5',
|
|
||||||
'LPeg ~> 1.0'
|
|
||||||
}
|
|
@ -4,7 +4,7 @@ local bot = {}
|
|||||||
local bindings -- Load Telegram bindings.
|
local bindings -- Load Telegram bindings.
|
||||||
local utilities -- Load miscellaneous and cross-plugin functions.
|
local utilities -- Load miscellaneous and cross-plugin functions.
|
||||||
|
|
||||||
bot.version = '3.10'
|
bot.version = '3.11'
|
||||||
|
|
||||||
function bot:init(config) -- The function run when the bot is started or reloaded.
|
function bot:init(config) -- The function run when the bot is started or reloaded.
|
||||||
|
|
||||||
@ -29,7 +29,28 @@ function bot:init(config) -- The function run when the bot is started or reloade
|
|||||||
self.database = utilities.load_data(self.info.username..'.db')
|
self.database = utilities.load_data(self.info.username..'.db')
|
||||||
end
|
end
|
||||||
|
|
||||||
self.database.users = self.database.users or {} -- Table to cache userdata.
|
-- MIGRATION CODE 3.10 -> 3.11
|
||||||
|
if self.database.users and self.database.version ~= '3.11' then
|
||||||
|
self.database.userdata = {}
|
||||||
|
for id, user in pairs(self.database.users) do
|
||||||
|
self.database.userdata[id] = {}
|
||||||
|
self.database.userdata[id].nickname = user.nickname
|
||||||
|
self.database.userdata[id].lastfm = user.lastfm
|
||||||
|
user.nickname = nil
|
||||||
|
user.lastfm = nil
|
||||||
|
user.id_str = nil
|
||||||
|
user.name = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- END MIGRATION CODE
|
||||||
|
|
||||||
|
-- Table to cache user info (usernames, IDs, etc).
|
||||||
|
self.database.users = self.database.users or {}
|
||||||
|
-- Table to store userdata (nicknames, lastfm usernames, etc).
|
||||||
|
self.database.userdata = self.database.userdata or {}
|
||||||
|
-- Save the bot's version in the database to make migration simpler.
|
||||||
|
self.database.version = bot.version
|
||||||
|
-- Add updated bot info to the user info cache.
|
||||||
self.database.users[tostring(self.info.id)] = self.info
|
self.database.users[tostring(self.info.id)] = self.info
|
||||||
|
|
||||||
self.plugins = {} -- Load plugins.
|
self.plugins = {} -- Load plugins.
|
||||||
@ -43,31 +64,38 @@ function bot:init(config) -- The function run when the bot is started or reloade
|
|||||||
|
|
||||||
self.last_update = self.last_update or 0 -- Set loop variables: Update offset,
|
self.last_update = self.last_update or 0 -- Set loop variables: Update offset,
|
||||||
self.last_cron = self.last_cron or os.date('%M') -- the time of the last cron job,
|
self.last_cron = self.last_cron or os.date('%M') -- the time of the last cron job,
|
||||||
|
self.last_database_save = self.last_database_save or os.date('%H') -- the time of the last database save,
|
||||||
self.is_started = true -- and whether or not the bot should be running.
|
self.is_started = true -- and whether or not the bot should be running.
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function bot:on_msg_receive(msg, config) -- The fn run whenever a message is received.
|
function bot:on_msg_receive(msg, config) -- The fn run whenever a message is received.
|
||||||
|
|
||||||
-- Cache user info for those involved.
|
|
||||||
utilities.create_user_entry(self, msg.from)
|
|
||||||
if msg.forward_from and msg.forward_from.id ~= msg.from.id then
|
|
||||||
utilities.create_user_entry(self, msg.forward_from)
|
|
||||||
elseif msg.reply_to_message and msg.reply_to_message.from.id ~= msg.from.id then
|
|
||||||
utilities.create_user_entry(self, msg.reply_to_message.from)
|
|
||||||
end
|
|
||||||
|
|
||||||
if msg.date < os.time() - 5 then return end -- Do not process old messages.
|
if msg.date < os.time() - 5 then return end -- Do not process old messages.
|
||||||
|
|
||||||
msg = utilities.enrich_message(msg)
|
-- Cache user info for those involved.
|
||||||
|
self.database.users[tostring(msg.from.id)] = msg.from
|
||||||
|
if msg.reply_to_message then
|
||||||
|
self.database.users[tostring(msg.reply_to_message.from.id)] = msg.reply_to_message.from
|
||||||
|
elseif msg.forward_from then
|
||||||
|
self.database.users[tostring(msg.forward_from.id)] = msg.forward_from
|
||||||
|
elseif msg.new_chat_member then
|
||||||
|
self.database.users[tostring(msg.new_chat_member.id)] = msg.new_chat_member
|
||||||
|
elseif msg.left_chat_member then
|
||||||
|
self.database.users[tostring(msg.left_chat_member.id)] = msg.left_chat_member
|
||||||
|
end
|
||||||
|
|
||||||
|
msg.text = msg.text or msg.caption or ''
|
||||||
|
msg.text_lower = msg.text:lower()
|
||||||
|
|
||||||
|
-- Support deep linking.
|
||||||
if msg.text:match('^'..config.cmd_pat..'start .+') then
|
if msg.text:match('^'..config.cmd_pat..'start .+') then
|
||||||
msg.text = config.cmd_pat .. utilities.input(msg.text)
|
msg.text = config.cmd_pat .. utilities.input(msg.text)
|
||||||
msg.text_lower = msg.text:lower()
|
msg.text_lower = msg.text:lower()
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, plugin in ipairs(self.plugins) do
|
for _, plugin in ipairs(self.plugins) do
|
||||||
for _, trigger in pairs(plugin.triggers) do
|
for _, trigger in pairs(plugin.triggers or {}) do
|
||||||
if string.match(msg.text_lower, trigger) then
|
if string.match(msg.text_lower, trigger) then
|
||||||
local success, result = pcall(function()
|
local success, result = pcall(function()
|
||||||
return plugin.action(self, msg, config)
|
return plugin.action(self, msg, config)
|
||||||
@ -116,7 +144,6 @@ function bot:run(config)
|
|||||||
|
|
||||||
if self.last_cron ~= os.date('%M') then -- Run cron jobs every minute.
|
if self.last_cron ~= os.date('%M') then -- Run cron jobs every minute.
|
||||||
self.last_cron = os.date('%M')
|
self.last_cron = os.date('%M')
|
||||||
utilities.save_data(self.info.username..'.db', self.database) -- Save the database.
|
|
||||||
for i,v in ipairs(self.plugins) do
|
for i,v in ipairs(self.plugins) do
|
||||||
if v.cron then -- Call each plugin's cron function, if it has one.
|
if v.cron then -- Call each plugin's cron function, if it has one.
|
||||||
local result, err = pcall(function() v.cron(self, config) end)
|
local result, err = pcall(function() v.cron(self, config) end)
|
||||||
@ -127,6 +154,11 @@ function bot:run(config)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.last_database_save ~= os.date('%H') then
|
||||||
|
utilities.save_data(self.info.username..'.db', self.database) -- Save the database.
|
||||||
|
self.last_database_save = os.date('%H')
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Save the database before exiting.
|
-- Save the database before exiting.
|
||||||
|
@ -19,10 +19,11 @@ function about:action(msg, config)
|
|||||||
local output = config.about_text .. '\nBased on [otouto](http://github.com/topkecleon/otouto) v'..bot.version..' by topkecleon.'
|
local output = config.about_text .. '\nBased on [otouto](http://github.com/topkecleon/otouto) v'..bot.version..' by topkecleon.'
|
||||||
|
|
||||||
if
|
if
|
||||||
(msg.new_chat_participant and msg.new_chat_participant.id == self.info.id)
|
(msg.new_chat_member and msg.new_chat_member.id == self.info.id)
|
||||||
or msg.text_lower:match('^'..config.cmd_pat..'about')
|
or msg.text_lower:match('^'..config.cmd_pat..'about$')
|
||||||
or msg.text_lower:match('^'..config.cmd_pat..'about@'..self.info.username:lower())
|
or msg.text_lower:match('^'..config.cmd_pat..'about@'..self.info.username:lower()..'$')
|
||||||
or msg.text_lower:match('^'..config.cmd_pat..'start')
|
or msg.text_lower:match('^'..config.cmd_pat..'start$')
|
||||||
|
or msg.text_lower:match('^'..config.cmd_pat..'start@'..self.info.username:lower()..'$')
|
||||||
then
|
then
|
||||||
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
||||||
return
|
return
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -17,8 +17,8 @@ blacklist.triggers = {
|
|||||||
|
|
||||||
function blacklist:action(msg, config)
|
function blacklist:action(msg, config)
|
||||||
|
|
||||||
if self.database.blacklist[msg.from.id_str] then return end
|
if self.database.blacklist[tostring(msg.from.id)] then return end
|
||||||
if self.database.blacklist[msg.chat.id_str] then return end
|
if self.database.blacklist[tostring(msg.chat.id)] then return end
|
||||||
if not msg.text:match('^'..config.cmd_pat..'blacklist') then return true end
|
if not msg.text:match('^'..config.cmd_pat..'blacklist') then return true end
|
||||||
if msg.from.id ~= config.admin then return end
|
if msg.from.id ~= config.admin then return end
|
||||||
|
|
||||||
@ -35,9 +35,15 @@ function blacklist:action(msg, config)
|
|||||||
if self.database.blacklist[tostring(target.id)] then
|
if self.database.blacklist[tostring(target.id)] then
|
||||||
self.database.blacklist[tostring(target.id)] = nil
|
self.database.blacklist[tostring(target.id)] = nil
|
||||||
utilities.send_reply(self, msg, target.name .. ' has been removed from the blacklist.')
|
utilities.send_reply(self, msg, target.name .. ' has been removed from the blacklist.')
|
||||||
|
if config.drua_block_on_blacklist then
|
||||||
|
require('drua-tg').unblock(target.id)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
self.database.blacklist[tostring(target.id)] = true
|
self.database.blacklist[tostring(target.id)] = true
|
||||||
utilities.send_reply(self, msg, target.name .. ' has been added to the blacklist.')
|
utilities.send_reply(self, msg, target.name .. ' has been added to the blacklist.')
|
||||||
|
if config.drua_block_on_blacklist then
|
||||||
|
require('drua-tg').block(target.id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -17,7 +17,7 @@ function control:action(msg, config)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if msg.date < os.time() - 1 then return end
|
if msg.date < os.time() - 2 then return end
|
||||||
|
|
||||||
if msg.text_lower:match('^'..cmd_pat..'reload') then
|
if msg.text_lower:match('^'..cmd_pat..'reload') then
|
||||||
for pac, _ in pairs(package.loaded) do
|
for pac, _ in pairs(package.loaded) do
|
||||||
|
@ -41,12 +41,16 @@ end
|
|||||||
|
|
||||||
function greetings:action(msg, config)
|
function greetings:action(msg, config)
|
||||||
|
|
||||||
local nick = self.database.users[msg.from.id_str].nickname or msg.from.first_name
|
local nick = utilities.build_name(msg.from.first_name, msg.from.last_name)
|
||||||
|
if self.database.userdata[tostring(msg.from.id)] then
|
||||||
|
nick = self.database.userdata[tostring(msg.from.id)].nickname or nick
|
||||||
|
end
|
||||||
|
|
||||||
for trigger,responses in pairs(config.greetings) do
|
for trigger,responses in pairs(config.greetings) do
|
||||||
for _,response in pairs(responses) do
|
for _,response in pairs(responses) do
|
||||||
if msg.text_lower:match(response..',? '..self.info.first_name:lower()) then
|
if msg.text_lower:match(response..',? '..self.info.first_name:lower()) then
|
||||||
utilities.send_message(self, msg.chat.id, utilities.latcyr(trigger:gsub('#NAME', nick)))
|
local output = utilities.char.zwnj .. trigger:gsub('#NAME', nick)
|
||||||
|
utilities.send_message(self, msg.chat.id, output)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -30,6 +30,8 @@ lastfm.command = 'lastfm'
|
|||||||
function lastfm:action(msg, config)
|
function lastfm:action(msg, config)
|
||||||
|
|
||||||
local input = utilities.input(msg.text)
|
local input = utilities.input(msg.text)
|
||||||
|
local from_id_str = tostring(msg.from.id)
|
||||||
|
self.database.userdata[from_id_str] = self.database.userdata[from_id_str] or {}
|
||||||
|
|
||||||
if string.match(msg.text, '^'..config.cmd_pat..'lastfm') then
|
if string.match(msg.text, '^'..config.cmd_pat..'lastfm') then
|
||||||
utilities.send_message(self, msg.chat.id, lastfm.doc, true, msg.message_id, true)
|
utilities.send_message(self, msg.chat.id, lastfm.doc, true, msg.message_id, true)
|
||||||
@ -38,10 +40,10 @@ function lastfm:action(msg, config)
|
|||||||
if not input then
|
if not input then
|
||||||
utilities.send_message(self, msg.chat.id, lastfm.doc, true, msg.message_id, true)
|
utilities.send_message(self, msg.chat.id, lastfm.doc, true, msg.message_id, true)
|
||||||
elseif input == '--' or input == utilities.char.em_dash then
|
elseif input == '--' or input == utilities.char.em_dash then
|
||||||
self.database.users[msg.from.id_str].lastfm = nil
|
self.database.userdata[from_id_str].lastfm = nil
|
||||||
utilities.send_reply(self, msg, 'Your last.fm username has been forgotten.')
|
utilities.send_reply(self, msg, 'Your last.fm username has been forgotten.')
|
||||||
else
|
else
|
||||||
self.database.users[msg.from.id_str].lastfm = input
|
self.database.userdata[from_id_str].lastfm = input
|
||||||
utilities.send_reply(self, msg, 'Your last.fm username has been set to "' .. input .. '".')
|
utilities.send_reply(self, msg, 'Your last.fm username has been set to "' .. input .. '".')
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
@ -53,12 +55,12 @@ function lastfm:action(msg, config)
|
|||||||
local alert = ''
|
local alert = ''
|
||||||
if input then
|
if input then
|
||||||
username = input
|
username = input
|
||||||
elseif self.database.users[msg.from.id_str].lastfm then
|
elseif self.database.userdata[from_id_str].lastfm then
|
||||||
username = self.database.users[msg.from.id_str].lastfm
|
username = self.database.userdata[from_id_str].lastfm
|
||||||
elseif msg.from.username then
|
elseif msg.from.username then
|
||||||
username = msg.from.username
|
username = msg.from.username
|
||||||
alert = '\n\nYour username has been set to ' .. username .. '.\nTo change it, use '..config.cmd_pat..'fmset <username>.'
|
alert = '\n\nYour username has been set to ' .. username .. '.\nTo change it, use '..config.cmd_pat..'fmset <username>.'
|
||||||
self.database.users[msg.from.id_str].lastfm = username
|
self.database.userdata[from_id_str].lastfm = username
|
||||||
else
|
else
|
||||||
utilities.send_reply(self, msg, 'Please specify your last.fm username or set it with '..config.cmd_pat..'fmset.')
|
utilities.send_reply(self, msg, 'Please specify your last.fm username or set it with '..config.cmd_pat..'fmset.')
|
||||||
return
|
return
|
||||||
|
@ -4,24 +4,37 @@ local utilities = require('otouto.utilities')
|
|||||||
|
|
||||||
function me:init(config)
|
function me:init(config)
|
||||||
me.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('me', true).table
|
me.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('me', true).table
|
||||||
|
me.command = 'me'
|
||||||
|
me.doc = '`Returns userdata stored by the bot.`'
|
||||||
end
|
end
|
||||||
|
|
||||||
function me:action(msg, config)
|
function me:action(msg, config)
|
||||||
|
|
||||||
local target = self.database.users[msg.from.id_str]
|
local userdata = self.database.userdata[tostring(msg.from.id)] or {}
|
||||||
|
|
||||||
if msg.from.id == config.admin and (msg.reply_to_message or utilities.input(msg.text)) then
|
if msg.from.id == config.admin then
|
||||||
target = utilities.user_from_message(self, msg, true)
|
if msg.reply_to_message then
|
||||||
if target.err then
|
userdata = self.database.userdata[tostring(msg.reply_to_message.from.id)]
|
||||||
utilities.send_reply(self, msg, target.err)
|
else
|
||||||
return
|
local input = utilities.input(msg.text)
|
||||||
|
if input then
|
||||||
|
local user_id = utilities.id_from_username(self, input)
|
||||||
|
if user_id then
|
||||||
|
userdata = self.database.userdata[tostring(user_id)] or {}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local output = ''
|
local output = ''
|
||||||
for k,v in pairs(target) do
|
for k,v in pairs(userdata) do
|
||||||
output = output .. '*' .. k .. ':* `' .. tostring(v) .. '`\n'
|
output = output .. '*' .. k .. ':* `' .. tostring(v) .. '`\n'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if output == '' then
|
||||||
|
output = 'There is no data stored for this user.'
|
||||||
|
end
|
||||||
|
|
||||||
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -14,34 +14,35 @@ end
|
|||||||
|
|
||||||
function nick:action(msg, config)
|
function nick:action(msg, config)
|
||||||
|
|
||||||
local target = msg.from
|
local id_str, name
|
||||||
|
|
||||||
if msg.from.id == config.admin and msg.reply_to_message then
|
if msg.from.id == config.admin and msg.reply_to_message then
|
||||||
target = msg.reply_to_message.from
|
id_str = tostring(msg.reply_to_message.from.id)
|
||||||
target.id_str = tostring(target.id)
|
name = utilities.build_name(msg.reply_to_message.from.first_name, msg.reply_to_message.from.last_name)
|
||||||
target.name = target.first_name
|
else
|
||||||
if target.last_name then
|
id_str = tostring(msg.from.id)
|
||||||
target.name = target.first_name .. ' ' .. target.last_name
|
name = utilities.build_name(msg.from.first_name, msg.from.last_name)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.database.userdata[id_str] = self.database.userdata[id_str] or {}
|
||||||
|
|
||||||
local output
|
local output
|
||||||
local input = utilities.input(msg.text)
|
local input = utilities.input(msg.text)
|
||||||
if not input then
|
if not input then
|
||||||
if self.database.users[target.id_str].nickname then
|
if self.database.userdata[id_str].nickname then
|
||||||
output = target.name .. '\'s nickname is "' .. self.database.users[target.id_str].nickname .. '".'
|
output = name .. '\'s nickname is "' .. self.database.userdata[id_str].nickname .. '".'
|
||||||
else
|
else
|
||||||
output = target.name .. ' currently has no nickname.'
|
output = name .. ' currently has no nickname.'
|
||||||
end
|
end
|
||||||
elseif utilities.utf8_len(input) > 32 then
|
elseif utilities.utf8_len(input) > 32 then
|
||||||
output = 'The character limit for nicknames is 32.'
|
output = 'The character limit for nicknames is 32.'
|
||||||
elseif input == '--' or input == utilities.char.em_dash then
|
elseif input == '--' or input == utilities.char.em_dash then
|
||||||
self.database.users[target.id_str].nickname = nil
|
self.database.userdata[id_str].nickname = nil
|
||||||
output = target.name .. '\'s nickname has been deleted.'
|
output = name .. '\'s nickname has been deleted.'
|
||||||
else
|
else
|
||||||
input = input:gsub('\n', ' ')
|
input = input:gsub('\n', ' ')
|
||||||
self.database.users[target.id_str].nickname = input
|
self.database.userdata[id_str].nickname = input
|
||||||
output = target.name .. '\'s nickname has been set to "' .. input .. '".'
|
output = name .. '\'s nickname has been set to "' .. input .. '".'
|
||||||
end
|
end
|
||||||
|
|
||||||
utilities.send_reply(self, msg, output)
|
utilities.send_reply(self, msg, output)
|
||||||
|
@ -40,13 +40,14 @@ function remind:action(msg)
|
|||||||
utilities.send_message(self, msg.chat.id, remind.doc, true, msg.message_id, true)
|
utilities.send_message(self, msg.chat.id, remind.doc, true, msg.message_id, true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
local chat_id_str = tostring(msg.chat.id)
|
||||||
-- Make a database entry for the group/user if one does not exist.
|
-- Make a database entry for the group/user if one does not exist.
|
||||||
self.database.reminders[msg.chat.id_str] = self.database.reminders[msg.chat.id_str] or {}
|
self.database.reminders[chat_id_str] = self.database.reminders[chat_id_str] or {}
|
||||||
-- Limit group reminders to 10 and private reminders to 50.
|
-- Limit group reminders to 10 and private reminders to 50.
|
||||||
if msg.chat.type ~= 'private' and utilities.table_size(self.database.reminders[msg.chat.id_str]) > 9 then
|
if msg.chat.type ~= 'private' and utilities.table_size(self.database.reminders[chat_id_str]) > 9 then
|
||||||
utilities.send_reply(self, msg, 'Sorry, this group already has ten reminders.')
|
utilities.send_reply(self, msg, 'Sorry, this group already has ten reminders.')
|
||||||
return
|
return
|
||||||
elseif msg.chat.type == 'private' and utilities.table_size(self.database.reminders[msg.chat.id_str]) > 49 then
|
elseif msg.chat.type == 'private' and utilities.table_size(self.database.reminders[chat_id_str]) > 49 then
|
||||||
utilities.send_reply(msg, 'Sorry, you already have fifty reminders.')
|
utilities.send_reply(msg, 'Sorry, you already have fifty reminders.')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -55,7 +56,7 @@ function remind:action(msg)
|
|||||||
time = os.time() + duration * 60,
|
time = os.time() + duration * 60,
|
||||||
message = message
|
message = message
|
||||||
}
|
}
|
||||||
table.insert(self.database.reminders[msg.chat.id_str], reminder)
|
table.insert(self.database.reminders[chat_id_str], reminder)
|
||||||
local output = 'I will remind you in ' .. duration
|
local output = 'I will remind you in ' .. duration
|
||||||
if duration == 1 then
|
if duration == 1 then
|
||||||
output = output .. ' minute!'
|
output = output .. ' minute!'
|
||||||
|
@ -17,8 +17,9 @@ setandget.command = 'set <name> <value>'
|
|||||||
|
|
||||||
function setandget:action(msg, config)
|
function setandget:action(msg, config)
|
||||||
|
|
||||||
|
local chat_id_str = tostring(msg.chat.id)
|
||||||
local input = utilities.input(msg.text)
|
local input = utilities.input(msg.text)
|
||||||
self.database.setandget[msg.chat.id_str] = self.database.setandget[msg.chat.id_str] or {}
|
self.database.setandget[chat_id_str] = self.database.setandget[chat_id_str] or {}
|
||||||
|
|
||||||
if msg.text_lower:match('^'..config.cmd_pat..'set') then
|
if msg.text_lower:match('^'..config.cmd_pat..'set') then
|
||||||
|
|
||||||
@ -33,10 +34,10 @@ function setandget:action(msg, config)
|
|||||||
if not name or not value then
|
if not name or not value then
|
||||||
utilities.send_message(self, msg.chat.id, setandget.doc, true, nil, true)
|
utilities.send_message(self, msg.chat.id, setandget.doc, true, nil, true)
|
||||||
elseif value == '--' or value == '—' then
|
elseif value == '--' or value == '—' then
|
||||||
self.database.setandget[msg.chat.id_str][name] = nil
|
self.database.setandget[chat_id_str][name] = nil
|
||||||
utilities.send_message(self, msg.chat.id, 'That value has been deleted.')
|
utilities.send_message(self, msg.chat.id, 'That value has been deleted.')
|
||||||
else
|
else
|
||||||
self.database.setandget[msg.chat.id_str][name] = value
|
self.database.setandget[chat_id_str][name] = value
|
||||||
utilities.send_message(self, msg.chat.id, '"' .. name .. '" has been set to "' .. value .. '".', true)
|
utilities.send_message(self, msg.chat.id, '"' .. name .. '" has been set to "' .. value .. '".', true)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -44,11 +45,11 @@ function setandget:action(msg, config)
|
|||||||
|
|
||||||
if not input then
|
if not input then
|
||||||
local output
|
local output
|
||||||
if utilities.table_size(self.database.setandget[msg.chat.id_str]) == 0 then
|
if utilities.table_size(self.database.setandget[chat_id_str]) == 0 then
|
||||||
output = 'No values have been stored here.'
|
output = 'No values have been stored here.'
|
||||||
else
|
else
|
||||||
output = '*List of stored values:*\n'
|
output = '*List of stored values:*\n'
|
||||||
for k,v in pairs(self.database.setandget[msg.chat.id_str]) do
|
for k,v in pairs(self.database.setandget[chat_id_str]) do
|
||||||
output = output .. '• ' .. k .. ': `' .. v .. '`\n'
|
output = output .. '• ' .. k .. ': `' .. v .. '`\n'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -57,8 +58,8 @@ function setandget:action(msg, config)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local output
|
local output
|
||||||
if self.database.setandget[msg.chat.id_str][input:lower()] then
|
if self.database.setandget[chat_id_str][input:lower()] then
|
||||||
output = '`' .. self.database.setandget[msg.chat.id_str][input:lower()] .. '`'
|
output = '`' .. self.database.setandget[chat_id_str][input:lower()] .. '`'
|
||||||
else
|
else
|
||||||
output = 'There is no value stored by that name.'
|
output = 'There is no value stored by that name.'
|
||||||
end
|
end
|
||||||
|
@ -61,7 +61,7 @@ local slaps = {
|
|||||||
'VICTIM died. I blame VICTOR.',
|
'VICTIM died. I blame VICTOR.',
|
||||||
'VICTIM was axe-murdered by VICTOR.',
|
'VICTIM was axe-murdered by VICTOR.',
|
||||||
'VICTIM\'s melon was split by VICTOR.',
|
'VICTIM\'s melon was split by VICTOR.',
|
||||||
'VICTIM was slice and diced by VICTOR.',
|
'VICTIM was sliced and diced by VICTOR.',
|
||||||
'VICTIM was split from crotch to sternum by VICTOR.',
|
'VICTIM was split from crotch to sternum by VICTOR.',
|
||||||
'VICTIM\'s death put another notch in VICTOR\'s axe.',
|
'VICTIM\'s death put another notch in VICTOR\'s axe.',
|
||||||
'VICTIM died impossibly!',
|
'VICTIM died impossibly!',
|
||||||
@ -102,29 +102,52 @@ local slaps = {
|
|||||||
'VICTIM was impeached.',
|
'VICTIM was impeached.',
|
||||||
'VICTIM was one-hit KO\'d by VICTOR.',
|
'VICTIM was one-hit KO\'d by VICTOR.',
|
||||||
'VICTOR sent VICTIM to /dev/null.',
|
'VICTOR sent VICTIM to /dev/null.',
|
||||||
'VICTOR sent VICTIM down the memory hole.'
|
'VICTOR sent VICTIM down the memory hole.',
|
||||||
|
'VICTIM was a mistake.',
|
||||||
|
'"VICTIM was a mistake." - VICTOR',
|
||||||
|
'VICTOR checkmated VICTIM in two moves.'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- optimize later
|
||||||
function slap:action(msg)
|
function slap:action(msg)
|
||||||
|
|
||||||
local victor = self.database.users[msg.from.id_str]
|
|
||||||
local victim = utilities.user_from_message(self, msg, true)
|
|
||||||
local input = utilities.input(msg.text)
|
local input = utilities.input(msg.text)
|
||||||
|
local victor_id = msg.from.id
|
||||||
local victim_name = victim.nickname or victim.first_name or input
|
local victim_id = utilities.id_from_message(self, msg)
|
||||||
local victor_name = victor.nickname or victor.first_name
|
-- IDs
|
||||||
if not victim_name or victim_name == victor_name then
|
if victim_id then
|
||||||
victim_name = victor_name
|
if victim_id == victor_id then
|
||||||
|
victor_id = self.info.id
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not input then
|
||||||
|
victor_id = self.info.id
|
||||||
|
victim_id = msg.from.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Names
|
||||||
|
local victor_name, victim_name
|
||||||
|
if input and not victim_id then
|
||||||
|
victim_name = input
|
||||||
|
else
|
||||||
|
local victim_id_str = tostring(victim_id)
|
||||||
|
if self.database.userdata[victim_id_str] and self.database.userdata[victim_id_str].nickname then
|
||||||
|
victim_name = self.database.userdata[victim_id_str].nickname
|
||||||
|
elseif self.database.users[victim_id_str] then
|
||||||
|
victim_name = utilities.build_name(self.database.users[victim_id_str].first_name, self.database.users[victim_id_str].last_name)
|
||||||
|
else
|
||||||
|
victim_name = victim_id_str
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local victor_id_str = tostring(victor_id)
|
||||||
|
if self.database.userdata[victor_id_str] and self.database.userdata[victor_id_str].nickname then
|
||||||
|
victor_name = self.database.userdata[victor_id_str].nickname
|
||||||
|
elseif self.database.users[victor_id_str] then
|
||||||
|
victor_name = utilities.build_name(self.database.users[victor_id_str].first_name, self.database.users[victor_id_str].last_name)
|
||||||
|
else
|
||||||
victor_name = self.info.first_name
|
victor_name = self.info.first_name
|
||||||
end
|
end
|
||||||
|
local output = utilities.char.zwnj .. slaps[math.random(#slaps)]:gsub('VICTIM', victim_name):gsub('VICTOR', victor_name)
|
||||||
local output = slaps[math.random(#slaps)]
|
|
||||||
output = output:gsub('VICTIM', victim_name)
|
|
||||||
output = output:gsub('VICTOR', victor_name)
|
|
||||||
output = utilities.char.zwnj .. output
|
|
||||||
|
|
||||||
utilities.send_message(self, msg.chat.id, output)
|
utilities.send_message(self, msg.chat.id, output)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return slap
|
return slap
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
local weather = {}
|
local weather = {}
|
||||||
|
|
||||||
local HTTP = require('socket.http')
|
local HTTP = require('socket.http')
|
||||||
|
HTTP.TIMEOUT = 2
|
||||||
local JSON = require('dkjson')
|
local JSON = require('dkjson')
|
||||||
local utilities = require('otouto.utilities')
|
local utilities = require('otouto.utilities')
|
||||||
|
|
||||||
|
@ -16,9 +16,10 @@ function whoami:action(msg)
|
|||||||
|
|
||||||
if msg.reply_to_message then
|
if msg.reply_to_message then
|
||||||
msg = msg.reply_to_message
|
msg = msg.reply_to_message
|
||||||
msg.from.name = utilities.build_name(msg.from.first_name, msg.from.last_name)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local from_name = utilities.build_name(msg.from.first_name, msg.from.last_name)
|
||||||
|
|
||||||
local chat_id = math.abs(msg.chat.id)
|
local chat_id = math.abs(msg.chat.id)
|
||||||
if chat_id > 1000000000000 then
|
if chat_id > 1000000000000 then
|
||||||
chat_id = chat_id - 1000000000000
|
chat_id = chat_id - 1000000000000
|
||||||
@ -26,10 +27,10 @@ function whoami:action(msg)
|
|||||||
|
|
||||||
local user = 'You are @%s, also known as *%s* `[%s]`'
|
local user = 'You are @%s, also known as *%s* `[%s]`'
|
||||||
if msg.from.username then
|
if msg.from.username then
|
||||||
user = user:format(utilities.markdown_escape(msg.from.username), msg.from.name, msg.from.id)
|
user = user:format(utilities.markdown_escape(msg.from.username), from_name, msg.from.id)
|
||||||
else
|
else
|
||||||
user = 'You are *%s* `[%s]`,'
|
user = 'You are *%s* `[%s]`,'
|
||||||
user = user:format(msg.from.name, msg.from.id)
|
user = user:format(from_name, msg.from.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
local group = '@%s, also known as *%s* `[%s]`.'
|
local group = '@%s, also known as *%s* `[%s]`.'
|
||||||
|
@ -73,49 +73,12 @@ function utilities.utf8_len(s)
|
|||||||
return chars
|
return chars
|
||||||
end
|
end
|
||||||
|
|
||||||
-- I swear, I copied this from PIL, not yago! :)
|
-- Trims whitespace from a string.
|
||||||
function utilities.trim(str) -- Trims whitespace from a string.
|
function utilities.trim(str)
|
||||||
local s = str:gsub('^%s*(.-)%s*$', '%1')
|
local s = str:gsub('^%s*(.-)%s*$', '%1')
|
||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
|
|
||||||
local lc_list = {
|
|
||||||
-- Latin = 'Cyrillic'
|
|
||||||
['A'] = 'А',
|
|
||||||
['B'] = 'В',
|
|
||||||
['C'] = 'С',
|
|
||||||
['E'] = 'Е',
|
|
||||||
['I'] = 'І',
|
|
||||||
['J'] = 'Ј',
|
|
||||||
['K'] = 'К',
|
|
||||||
['M'] = 'М',
|
|
||||||
['H'] = 'Н',
|
|
||||||
['O'] = 'О',
|
|
||||||
['P'] = 'Р',
|
|
||||||
['S'] = 'Ѕ',
|
|
||||||
['T'] = 'Т',
|
|
||||||
['X'] = 'Х',
|
|
||||||
['Y'] = 'Ү',
|
|
||||||
['a'] = 'а',
|
|
||||||
['c'] = 'с',
|
|
||||||
['e'] = 'е',
|
|
||||||
['i'] = 'і',
|
|
||||||
['j'] = 'ј',
|
|
||||||
['o'] = 'о',
|
|
||||||
['s'] = 'ѕ',
|
|
||||||
['x'] = 'х',
|
|
||||||
['y'] = 'у',
|
|
||||||
['!'] = 'ǃ'
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Replaces letters with corresponding Cyrillic characters.
|
|
||||||
function utilities.latcyr(str)
|
|
||||||
for k,v in pairs(lc_list) do
|
|
||||||
str = str:gsub(k, v)
|
|
||||||
end
|
|
||||||
return str
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Loads a JSON file as a table.
|
-- Loads a JSON file as a table.
|
||||||
function utilities.load_data(filename)
|
function utilities.load_data(filename)
|
||||||
local f = io.open(filename)
|
local f = io.open(filename)
|
||||||
@ -179,9 +142,41 @@ end
|
|||||||
|
|
||||||
function utilities:resolve_username(input)
|
function utilities:resolve_username(input)
|
||||||
input = input:gsub('^@', '')
|
input = input:gsub('^@', '')
|
||||||
for _,v in pairs(self.database.users) do
|
for _, user in pairs(self.database.users) do
|
||||||
if v.username and v.username:lower() == input:lower() then
|
if user.username and user.username:lower() == input:lower() then
|
||||||
return v
|
local t = {}
|
||||||
|
for key, val in pairs(user) do
|
||||||
|
t[key] = val
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Simpler than above function; only returns an ID.
|
||||||
|
-- Returns nil if no ID is available.
|
||||||
|
function utilities:id_from_username(input)
|
||||||
|
input = input:gsub('^@', '')
|
||||||
|
for _, user in pairs(self.database.users) do
|
||||||
|
if user.username and user.username:lower() == input:lower() then
|
||||||
|
return user.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Simpler than below function; only returns an ID.
|
||||||
|
-- Returns nil if no ID is available.
|
||||||
|
function utilities:id_from_message(msg)
|
||||||
|
if msg.reply_to_message then
|
||||||
|
return msg.reply_to_message.from.id
|
||||||
|
else
|
||||||
|
local input = utilities.input(msg.text)
|
||||||
|
if input then
|
||||||
|
if tonumber(input) then
|
||||||
|
return tonumber(input)
|
||||||
|
elseif input:match('^@') then
|
||||||
|
return utilities.id_from_username(self, input)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -309,37 +304,6 @@ function utilities.with_http_timeout(timeout, fun)
|
|||||||
HTTP.TIMEOUT = original
|
HTTP.TIMEOUT = original
|
||||||
end
|
end
|
||||||
|
|
||||||
function utilities.enrich_user(user)
|
|
||||||
user.id_str = tostring(user.id)
|
|
||||||
user.name = utilities.build_name(user.first_name, user.last_name)
|
|
||||||
return user
|
|
||||||
end
|
|
||||||
|
|
||||||
function utilities.enrich_message(msg)
|
|
||||||
if not msg.text then msg.text = msg.caption or '' end
|
|
||||||
msg.text_lower = msg.text:lower()
|
|
||||||
msg.from = utilities.enrich_user(msg.from)
|
|
||||||
msg.chat.id_str = tostring(msg.chat.id)
|
|
||||||
if msg.reply_to_message then
|
|
||||||
if not msg.reply_to_message.text then
|
|
||||||
msg.reply_to_message.text = msg.reply_to_message.caption or ''
|
|
||||||
end
|
|
||||||
msg.reply_to_message.text_lower = msg.reply_to_message.text:lower()
|
|
||||||
msg.reply_to_message.from = utilities.enrich_user(msg.reply_to_message.from)
|
|
||||||
msg.reply_to_message.chat.id_str = tostring(msg.reply_to_message.chat.id)
|
|
||||||
end
|
|
||||||
if msg.forward_from then
|
|
||||||
msg.forward_from = utilities.enrich_user(msg.forward_from)
|
|
||||||
end
|
|
||||||
if msg.new_chat_participant then
|
|
||||||
msg.new_chat_participant = utilities.enrich_user(msg.new_chat_participant)
|
|
||||||
end
|
|
||||||
if msg.left_chat_participant then
|
|
||||||
msg.left_chat_participant = utilities.enrich_user(msg.left_chat_participant)
|
|
||||||
end
|
|
||||||
return msg
|
|
||||||
end
|
|
||||||
|
|
||||||
function utilities.pretty_float(x)
|
function utilities.pretty_float(x)
|
||||||
if x % 1 == 0 then
|
if x % 1 == 0 then
|
||||||
return tostring(math.floor(x))
|
return tostring(math.floor(x))
|
||||||
@ -348,21 +312,6 @@ function utilities.pretty_float(x)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function utilities:create_user_entry(user)
|
|
||||||
local id = tostring(user.id)
|
|
||||||
-- Clear things that may no longer exist, or create a user entry.
|
|
||||||
if self.database.users[id] then
|
|
||||||
self.database.users[id].username = nil
|
|
||||||
self.database.users[id].last_name = nil
|
|
||||||
else
|
|
||||||
self.database.users[id] = {}
|
|
||||||
end
|
|
||||||
-- Add all the user info to the entry.
|
|
||||||
for k,v in pairs(user) do
|
|
||||||
self.database.users[id][k] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- This table will store unsavory characters that are not properly displayed,
|
-- This table will store unsavory characters that are not properly displayed,
|
||||||
-- or are just not fun to type.
|
-- or are just not fun to type.
|
||||||
utilities.char = {
|
utilities.char = {
|
||||||
|
Reference in New Issue
Block a user