administration.lua:

1.7 update.
  /alist for governors+ to get list of admins.
  /glist for owner to get list of groups.
  Single-governor groups. Auto-migration through 1.8.
whoami.lua:
  Fixed markdown support.
utilities.lua:
  Added build_name() to concatenate first and last names easily.
This commit is contained in:
topkecleon 2016-04-01 13:29:00 -04:00
parent 381a363346
commit 0f453b7bdc
3 changed files with 125 additions and 66 deletions

View File

@ -1,6 +1,6 @@
--[[ --[[
administration.lua administration.lua
Version 1.6.1 Version 1.7
Part of the otouto project. Part of the otouto project.
© 2016 topkecleon <drew@otou.to> © 2016 topkecleon <drew@otou.to>
GNU General Public License, version 2 GNU General Public License, version 2
@ -13,12 +13,11 @@
Important notices about updates will be here! Important notices about updates will be here!
Rules lists always exist, empty if there are no rules. Group arrays are now 1.7 - Added antiflood (flag 5). Fixed security flaw. Renamed flag 3
stored in a "groups" array rather than at the top level. Global data is now ("antisquig Strict" -> "antisquig++"). Added /alist for governors to list
stored at the top level rather than in a "global" array. Automatic migration administrators. Back to single-governor groups as originally intended. Auto-
will occur in versions 1.5 and 1.6. matic migration through 1.8.
/groups will now list groups according to activity.
]]-- ]]--
-- Build the administration db if nonexistent. -- Build the administration db if nonexistent.
@ -35,29 +34,6 @@ admin_temp = {
flood = {} flood = {}
} }
-- Migration code: Remove this in v1.7.
-- Group data is now stored in a "groups" array.
if not database.administration.groups then
database.administration.groups = {}
for k,v in pairs(database.administration) do
if tonumber(k) then
database.administration.groups[k] = v
database.administration[k] = nil
end
end
end
-- Global data is stored at the top level.
if database.administration.global then
for k,v in pairs(database.administration.global) do
database.administration[k] = v
end
database.administration.global = nil
end
-- Rule lists remain empty, rather than nil, when there are no rules.
for k,v in pairs(database.administration.groups) do
v.rules = v.rules or {}
end
-- Migration code: Remove this in v1.8. -- Migration code: Remove this in v1.8.
-- Most recent group activity is now cached for group listings. -- Most recent group activity is now cached for group listings.
if not database.administration.activity then if not database.administration.activity then
@ -67,6 +43,18 @@ if not database.administration.activity then
end end
end end
-- Migration code: Remove this in v1.9.
-- Groups have single governors now.
for k,v in pairs(database.administration.groups) do
if v.govs and table_size(v.govs) > 0 then
for key, val in pairs(v.govs) do
v.governor = key
break
end
end
v.govs = nil
end
drua = dofile('drua-tg/drua-tg.lua') drua = dofile('drua-tg/drua-tg.lua')
drua.PORT = config.cli_port or 4567 drua.PORT = config.cli_port or 4567
@ -148,7 +136,7 @@ local get_rank = function(target, chat)
end end
if chat and database.administration.groups[chat] then if chat and database.administration.groups[chat] then
if database.administration.groups[chat].govs[target] then if database.administration.groups[chat].governor == tonumber(target) then
return 3 return 3
elseif database.administration.groups[chat].mods[target] then elseif database.administration.groups[chat].mods[target] then
return 2 return 2
@ -220,12 +208,10 @@ local get_desc = function(chat_id)
if modstring ~= '' then if modstring ~= '' then
table.insert(t, '*Moderators:*\n' .. modstring:trim()) table.insert(t, '*Moderators:*\n' .. modstring:trim())
end end
local govstring = '' if group.governor then
for k,v in pairs(group.govs) do local gov = database.users[tostring(group.governor)]
govstring = govstring .. mod_format(k) local s = build_name(gov.first_name, gov.last_name):md_escape() .. ' `[' .. gov.id .. ']`'
end table.insert(t, '*Governor:* ' .. s)
if govstring ~= '' then
table.insert(t, '*Governors:*\n' .. govstring:trim())
end end
return table.concat(t, '\n\n') return table.concat(t, '\n\n')
@ -451,7 +437,7 @@ local commands = {
command = 'ahelp', command = 'ahelp',
privilege = 1, privilege = 1,
interior = true, interior = false,
action = function(msg) action = function(msg)
local rank = get_rank(msg.from.id, msg.chat.id) local rank = get_rank(msg.from.id, msg.chat.id)
@ -462,7 +448,9 @@ local commands = {
end end
end end
if sendMessage(msg.from.id, output, true, nil, true) then if sendMessage(msg.from.id, output, true, nil, true) then
if msg.from.id ~= msg.chat.id then
sendReply(msg, 'I have sent you the requested information in a private message.') sendReply(msg, 'I have sent you the requested information in a private message.')
end
else else
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
end end
@ -490,14 +478,12 @@ local commands = {
modstring = '*Moderators for* _' .. msg.chat.title .. '_ *:*\n' .. modstring modstring = '*Moderators for* _' .. msg.chat.title .. '_ *:*\n' .. modstring
end end
local govstring = '' local govstring = ''
for k,v in pairs(group.govs) do if group.governor then
govstring = govstring .. mod_format(k) local gov = database.users[tostring(group.governor)]
govstring = '*Governor:* ' .. build_name(gov.first_name, gov.last_name):md_escape() .. ' `[' .. gov.id .. ']`'
end end
if govstring ~= '' then local output = modstring:trim() ..'\n\n' .. govstring:trim()
govstring = '*Governors for* _' .. msg.chat.title .. '_ *:*\n' .. govstring if output == '\n\n' then
end
local output = modstring .. govstring
if output == '' then
output = 'There are currently no moderators for this group.' output = 'There are currently no moderators for this group.'
end end
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
@ -518,7 +504,9 @@ local commands = {
action = function(msg) action = function(msg)
local output = get_desc(msg.chat.id) local output = get_desc(msg.chat.id)
if sendMessage(msg.from.id, output, true, nil, true) then if sendMessage(msg.from.id, output, true, nil, true) then
if msg.from.id ~= msg.chat.id then
sendReply(msg, 'I have sent you the requested information in a private message.') sendReply(msg, 'I have sent you the requested information in a private message.')
end
else else
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
end end
@ -802,9 +790,29 @@ local commands = {
end end
}, },
{ -- alist
triggers = {
'^/alist$',
'^/alist@'..bot.username
},
command = 'alist',
privilege = 3,
interior = true,
action = function(msg)
local output = '*Administrators:*\n'
output = output .. mod_format(config.admin):gsub('\n', '\n')
for k,v in pairs(database.administration.admins) do
output = output .. mod_format(k)
end
sendMessage(msg.chat.id, output, true, nil, true)
end
},
{ -- flags { -- flags
triggers = { triggers = {
'^/flags?[@'..bot.username..']*' '^/flags?'
}, },
command = 'flag <i>', command = 'flag <i>',
@ -840,8 +848,7 @@ local commands = {
{ -- antiflood { -- antiflood
triggers = { triggers = {
'^/antiflood', '^/antiflood'
'^/antiflood@'..bot.username
}, },
command = 'antiflood <type> <i>', command = 'antiflood <type> <i>',
@ -864,7 +871,7 @@ local commands = {
output = 'Not a valid message type or number.' output = 'Not a valid message type or number.'
else else
group.antiflood[key] = val group.antiflood[key] = val
output = 'A *' .. key .. '* message is now worth *' .. val .. '* points.' output = '*' .. key:gsub('^%l', string.upper) .. '* messages are now worth *' .. val .. '* points.'
end end
else else
output = 'usage: `/antiflood <type> <i>`\nexample: `/antiflood text 5`\nUse this command to configure the point values for each message type. When a user reaches 100 points, he is kicked. The points are reset each minute. The current values are:\n' output = 'usage: `/antiflood <type> <i>`\nexample: `/antiflood text 5`\nUse this command to configure the point values for each message type. When a user reaches 100 points, he is kicked. The points are reset each minute. The current values are:\n'
@ -928,21 +935,24 @@ local commands = {
sendReply(msg, target.err) sendReply(msg, target.err)
return return
end end
if group.govs[target.id_str] then if group.governor and group.governor == target.id then
if group.grouptype == 'supergroup' then if group.grouptype == 'supergroup' then
drua.channel_set_admin(msg.chat.id, target.id, 0) drua.channel_set_admin(msg.chat.id, target.id, 0)
end end
group.govs[target.id_str] = nil group.governor = nil
sendReply(msg, target.name .. ' is no longer a governor.') sendReply(msg, target.name .. ' is no longer the governor.')
else else
if group.grouptype == 'supergroup' then
if group.governor then
drua.channel_set_admin(msg.chat.id, group.governor, 0)
end
drua.channel_set_admin(msg.chat.id, target.id, 2)
end
if target.rank == 2 then if target.rank == 2 then
group.mods[target.id_str] = nil group.mods[target.id_str] = nil
end end
if group.grouptype == 'supergroup' then group.governor = target.id
drua.channel_set_admin(msg.chat.id, target.id, 2) sendReply(msg, target.name .. ' is the new governor.')
end
group.govs[target.id_str] = true
sendReply(msg, target.name .. ' is now a governor.')
end end
end end
}, },
@ -1006,7 +1016,6 @@ local commands = {
end end
for k,v in pairs(database.administration.groups) do for k,v in pairs(database.administration.groups) do
v.mods[target.id_str] = nil v.mods[target.id_str] = nil
v.govs[target.id_str] = nil
end end
database.administration.admins[target.id_str] = true database.administration.admins[target.id_str] = true
sendReply(msg, target.name .. ' is now an administrator.') sendReply(msg, target.name .. ' is now an administrator.')
@ -1016,7 +1025,8 @@ local commands = {
{ -- gadd { -- gadd
triggers = { triggers = {
'^/gadd[@'..bot.username..']*$' '^/gadd$',
'^/gadd@'..bot.username
}, },
command = 'gadd', command = 'gadd',
@ -1030,7 +1040,7 @@ local commands = {
end end
database.administration.groups[msg.chat.id_str] = { database.administration.groups[msg.chat.id_str] = {
mods = {}, mods = {},
govs = {}, governor = msg.from.id,
bans = {}, bans = {},
flags = {}, flags = {},
rules = {}, rules = {},
@ -1071,9 +1081,40 @@ local commands = {
end end
}, },
{ -- glist
triggers = {
'^/glist$',
'^/glist@'..bot.username
},
command = 'glist',
privilege = 5,
interior = false,
action = function(msg)
local output = ''
if table_size(database.administration.groups) > 0 then
for k,v in pairs(database.administration.groups) do
output = output .. '[' .. v.name:md_escape() .. '](' .. v.link .. ') `[' .. k .. ']`\n'
if v.governor then
local gov = database.users[tostring(v.governor)]
output = output .. '• Governor: ' .. build_name(gov.first_name, gov.last_name):md_escape() .. ' `[' .. gov.id .. ']`\n'
end
end
else
output = 'There are no groups.'
end
if sendMessage(msg.from.id, output, true, nil, true) then
if msg.from.id ~= msg.chat.id then
sendReply(msg, 'I have sent you the requested information in a private message.')
end
end
end
},
{ -- broadcast { -- broadcast
triggers = { triggers = {
'^/broadcast[@'..bot.username..']*' '^/broadcast'
}, },
command = 'broadcast <message>', command = 'broadcast <message>',
@ -1120,7 +1161,7 @@ local action = function(msg)
if v.interior and not database.administration.groups[msg.chat.id_str] then if v.interior and not database.administration.groups[msg.chat.id_str] then
break break
end end
if msg.chat.type ~= 'private' and get_rank(msg.from.id, msg.chat.id) < v.privilege then if get_rank(msg.from.id, msg.chat.id) < v.privilege then
break break
end end
local res = v.action(msg, database.administration.groups[msg.chat.id_str]) local res = v.action(msg, database.administration.groups[msg.chat.id_str])

View File

@ -27,7 +27,7 @@ local action = function(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(msg.from.username, msg.from.name, msg.from.id) user = user:format(markdown_escape(msg.from.username), msg.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(msg.from.name, msg.from.id)
@ -35,9 +35,9 @@ local action = function(msg)
local group = '@%s, also known as *%s* `[%s]`.' local group = '@%s, also known as *%s* `[%s]`.'
if msg.chat.type == 'private' then if msg.chat.type == 'private' then
group = group:format(bot.username, bot.first_name, bot.id) group = group:format(markdown_escape(bot.username), bot.first_name, bot.id)
elseif msg.chat.username then elseif msg.chat.username then
group = group:format(msg.chat.username, msg.chat.title, chat_id) group = group:format(markdown_escape(msg.chat.username), msg.chat.title, chat_id)
else else
group = '*%s* `[%s]`.' group = '*%s* `[%s]`.'
group = group:format(msg.chat.title, chat_id) group = group:format(msg.chat.title, chat_id)

View File

@ -255,3 +255,21 @@ markdown_escape = function(text)
return text return text
end end
function string:md_escape()
local text = self
text = text:gsub('_', '\\_')
text = text:gsub('%[', '\\[')
text = text:gsub('%*', '\\*')
text = text:gsub('`', '\\`')
return text
end
-- Just an easy way to get a user's full name.
build_name = function(first, last)
if last then
return first .. ' ' .. last
else
return first
end
end