administration.lua: 1.10: Added /ahelp $command support. No

migration required. All actions have been reworked to be more
 elegant. Style has been slightly changed (no more weak-looking,
 italic group names). Added some (but not many) comments.

drua-tg.lua: Slightly changed send function with error catching
 for failed TCP connections.

reddit.lua: Rewritten, no more brokenness. Yay.
This commit is contained in:
topkecleon 2016-05-25 09:01:54 -04:00
parent 85c9785099
commit 684cca287f
7 changed files with 453 additions and 319 deletions

View File

@ -89,6 +89,8 @@ Some plugins are designed to be used by the bot's owner. Here are some examples,
## administration.lua ## administration.lua
The administration plugin enables self-hosted, single-realm group administration, supporting both normal groups and supergroups. This works by sending TCP commands to an instance of tg running on the owner's account. The administration plugin enables self-hosted, single-realm group administration, supporting both normal groups and supergroups. This works by sending TCP commands to an instance of tg running on the owner's account.
**For best results, make your bot an administrator of any group it administrates.**
To get started, run `./tg-install.sh`. Note that this script is written for Ubuntu/Debian. If you're running Arch (the only acceptable alternative), you'll have to do it yourself. If that is the case, note that otouto uses the "test" branch of tg, and the AUR package `telegram-cli-git` will not be sufficient, as it does not have support for supergroups yet. To get started, run `./tg-install.sh`. Note that this script is written for Ubuntu/Debian. If you're running Arch (the only acceptable alternative), you'll have to do it yourself. If that is the case, note that otouto uses the "test" branch of tg, and the AUR package `telegram-cli-git` will not be sufficient, as it does not have support for supergroups yet.
Once the installation is finished, enable `administration.lua` in your config file. **The administration plugin must be loaded before about.lua and blacklist.lua.** You may have reason to change the default TCP port (4567); if that is the case, remember to change it in `tg-launch.sh` as well. Run `./tg-launch.sh` in a separate screen/tmux window. You'll have to enter your phone number and go through the login process the first time. The script is set to restart tg after two seconds, so you'll need to Ctrl+C after exiting. Once the installation is finished, enable `administration.lua` in your config file. **The administration plugin must be loaded before about.lua and blacklist.lua.** You may have reason to change the default TCP port (4567); if that is the case, remember to change it in `tg-launch.sh` as well. Run `./tg-launch.sh` in a separate screen/tmux window. You'll have to enter your phone number and go through the login process the first time. The script is set to restart tg after two seconds, so you'll need to Ctrl+C after exiting.
@ -223,6 +225,7 @@ The bot will accept these commands from both Liberbot and the configured adminis
## Style ## Style
Bot output from every plugin should follow a consistent style. This style is easily observed interacting with the bot. Bot output from every plugin should follow a consistent style. This style is easily observed interacting with the bot.
Titles should be either **bold** (along with their colons) or a [link](http://otou.to) (with plaintext colons) to the content's source. Names should be _italic_. Numbered lists should use bold numbers followed by a bold period followed by a space. Unnumbered lists should use the • bullet point followed by a space. Descriptions and information should be in plaintext, although "flavor" text should be italic. Technical information should be `monospace`. Links should be named. Titles should be either **bold** (along with their colons) or a [link](http://otou.to) (with plaintext colons) to the content's source. Names should be _italic_. Numbered lists should use bold numbers followed by a bold period followed by a space. Unnumbered lists should use the • bullet point followed by a space. Descriptions and information should be in plaintext, although "flavor" text should be italic. Technical information should be `monospace`. Links should be named.
The standard count for plugins which return multiple results is eight results in a private message, and four results elsewhere. This is a trivial number, but consistency is noticeable and desirable.
## Contributors ## Contributors
Everybody is free to contribute to otouto. If you are interested, you are invited to fork the [repo](http://github.com/topkecleon/otouto) and start making pull requests. If you have an idea and you are not sure how to implement it, open an issue or bring it up in the Bot Development group. Everybody is free to contribute to otouto. If you are interested, you are invited to fork the [repo](http://github.com/topkecleon/otouto) and start making pull requests. If you have an idea and you are not sure how to implement it, open an issue or bring it up in the Bot Development group.

View File

@ -50,17 +50,16 @@ local drua = {
} }
drua.send = function(command, do_receive) drua.send = function(command, do_receive)
command = command .. '\n' local s = SOCKET.connect(drua.IP, drua.PORT)
local s = SOCKET.connect('localhost', 4567) assert(s, '\nUnable to connect to tg session.')
s:send(command) s:send(command..'\n')
local output
if do_receive then if do_receive then
-- Get the size of the output, and get the output. output = string.match(s:receive('*l'), 'ANSWER (%d+)')
-- Thanks Juan for making this so easy to read. :^) output = s:receive(tonumber(n)):gsub('\n$', '')
local output = s:receive(tonumber(string.match(s:receive("*l"), "ANSWER (%d+)")))
s:close()
return output:gsub('\n$', '')
end end
s:close() s:close()
return output
end end
drua.message = function(target, text) drua.message = function(target, text)

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@ function lastfm:action(msg)
elseif string.match(msg.text, '^/fmset') then elseif string.match(msg.text, '^/fmset') then
if not input then if not input then
bindings.sendMessage(self, msg.chat.id, lastfm.doc, true, msg.message_id, true) bindings.sendMessage(self, msg.chat.id, lastfm.doc, true, msg.message_id, true)
elseif input == '--' or input == '' then elseif input == '--' or input == utilities.char.em_dash then
self.database.users[msg.from.id_str].lastfm = nil self.database.users[msg.from.id_str].lastfm = nil
bindings.sendReply(self, msg, 'Your last.fm username has been forgotten.') bindings.sendReply(self, msg, 'Your last.fm username has been forgotten.')
else else

View File

@ -36,7 +36,7 @@ function nick:action(msg)
end end
elseif string.len(input) > 32 then elseif string.len(input) > 32 then
output = 'The character limit for nicknames is 32.' output = 'The character limit for nicknames is 32.'
elseif input == '--' or input == '' then elseif input == '--' or input == utilities.char.em_dash then
self.database.users[target.id_str].nickname = nil self.database.users[target.id_str].nickname = nil
output = target.name .. '\'s nickname has been deleted.' output = target.name .. '\'s nickname has been deleted.'
else else

View File

@ -9,77 +9,78 @@ local utilities = require('utilities')
reddit.command = 'reddit [r/subreddit | query]' reddit.command = 'reddit [r/subreddit | query]'
reddit.doc = [[``` reddit.doc = [[```
/reddit [r/subreddit | query] /reddit [r/subreddit | query]
Returns the four (if group) or eight (if private message) top posts for the given subreddit or query, or from the frontpage. Returns the top posts or results for a given subreddit or query. If no argument is given, returns the top posts from r/all. Querying specific subreddits is not supported.
Aliases: /r, /r/[subreddit] Aliases: /r, /r/subreddit
```]] ```]]
function reddit:init() function reddit:init()
reddit.triggers = utilities.triggers(self.info.username, {'^/r/'}):t('reddit', true):t('r', true):t('r/', true).table reddit.triggers = utilities.triggers(self.info.username, {'^/r/'}):t('reddit', true):t('r', true):t('r/', true).table
end end
function reddit:action(msg) local format_results = function(posts)
local output = ''
msg.text_lower = msg.text_lower:gsub('/r/', '/r r/') for _,v in ipairs(posts) do
local input local post = v.data
if msg.text_lower:match('^/r/') then local title = post.title:gsub('%[', '('):gsub('%]', ')'):gsub('&', '&')
msg.text_lower = msg.text_lower:gsub('/r/', '/r r/') if title:len() > 256 then
input = utilities.get_word(msg.text_lower, 1) title = title:sub(1, 253)
else title = utilities.trim(title) .. '...'
input = utilities.input(msg.text_lower) end
local short_url = 'redd.it/' .. post.id
local s = '[' .. title .. '](' .. short_url .. ')'
if not post.is_self and not post.over_18 then
s = '`[`[' .. post.domain .. '](' .. post.url:gsub('%)', '\\)') .. ')`]` ' .. s
end
output = output .. '' .. s .. '\n'
end end
local url return output
end
reddit.subreddit_url = 'http://www.reddit.com/%s/.json?limit='
reddit.search_url = 'http://www.reddit.com/search.json?q=%s&limit='
reddit.rall_url = 'http://www.reddit.com/.json?limit='
function reddit:action(msg)
-- Eight results in PM, four results elsewhere.
local limit = 4 local limit = 4
if msg.chat.id == msg.from.id then if msg.chat.type == 'private' then
limit = 8 limit = 8
end end
local text = msg.text_lower
local source if text:match('^/r/.') then
-- Normalize input so this hack works easily.
text = msg.text_lower:gsub('^/r/', '/r r/')
end
local input = utilities.input(text)
local source, url
if input then if input then
if input:match('^r/.') then if input:match('^r/.') then
url = 'http://www.reddit.com/' .. URL.escape(input) .. '/.json?limit=' .. limit input = utilities.get_word(input, 1)
source = '*/r/' .. input:match('^r/(.+)') .. '*\n' url = reddit.subreddit_url:format(input) .. limit
source = '*/' .. utilities.md_escape(input) .. '*\n'
else else
url = 'http://www.reddit.com/search.json?q=' .. URL.escape(input) .. '&limit=' .. limit input = utilities.input(msg.text)
source = '*reddit results for* _' .. input .. '_ *:*\n' source = '*Results for* _' .. utilities.md_escape(input) .. '_ *:*\n'
input = URL.escape(input)
url = reddit.search_url:format(input) .. limit
end end
else else
url = 'http://www.reddit.com/.json?limit=' .. limit url = reddit.rall_url .. limit
source = '*/r/all*\n' source = '*/r/all*\n'
end end
local jstr, res = HTTP.request(url) local jstr, res = HTTP.request(url)
if res ~= 200 then if res ~= 200 then
bindings.sendReply(self, msg, self.config.errors.connection) bindings.sendReply(self, msg, self.config.errors.connection)
return else
end local jdat = JSON.decode(jstr)
if #jdat.data.children == 0 then
local jdat = JSON.decode(jstr) bindings.sendReply(self, msg, self.config.errors.results)
if #jdat.data.children == 0 then else
bindings.sendReply(self, msg, self.config.errors.results) local output = format_results(jdat.data.children)
return output = source .. output
end bindings.sendMessage(self, msg.chat.id, output, true, nil, true)
local output = ''
for _,v in ipairs(jdat.data.children) do
local title = v.data.title:gsub('%[', '('):gsub('%]', ')'):gsub('&', '&')
if title:len() > 48 then
title = title:sub(1,45) .. '...'
end
if v.data.over_18 then
v.data.is_self = true
end
local short_url = 'redd.it/' .. v.data.id
output = output .. '• [' .. title .. '](' .. short_url .. ')\n'
if not v.data.is_self then
output = output .. v.data.url:gsub('_', '\\_') .. '\n'
end end
end end
output = source .. output
bindings.sendMessage(self, msg.chat.id, output, true, nil, true)
end end
return reddit return reddit

View File

@ -336,7 +336,8 @@ utilities.char = {
zwnj = '', zwnj = '',
arabic = '[\216-\219][\128-\191]', arabic = '[\216-\219][\128-\191]',
rtl_override = '', rtl_override = '',
rtl_mark = '' rtl_mark = '',
em_dash = ''
} }
return utilities return utilities