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
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.
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
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.
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
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)
command = command .. '\n'
local s = SOCKET.connect('localhost', 4567)
s:send(command)
local s = SOCKET.connect(drua.IP, drua.PORT)
assert(s, '\nUnable to connect to tg session.')
s:send(command..'\n')
local output
if do_receive then
-- Get the size of the output, and get the output.
-- Thanks Juan for making this so easy to read. :^)
local output = s:receive(tonumber(string.match(s:receive("*l"), "ANSWER (%d+)")))
s:close()
return output:gsub('\n$', '')
output = string.match(s:receive('*l'), 'ANSWER (%d+)')
output = s:receive(tonumber(n)):gsub('\n$', '')
end
s:close()
return output
end
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
if not input then
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
bindings.sendReply(self, msg, 'Your last.fm username has been forgotten.')
else

View File

@ -36,7 +36,7 @@ function nick:action(msg)
end
elseif string.len(input) > 32 then
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
output = target.name .. '\'s nickname has been deleted.'
else

View File

@ -9,77 +9,78 @@ local utilities = require('utilities')
reddit.command = 'reddit [r/subreddit | query]'
reddit.doc = [[```
/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.
Aliases: /r, /r/[subreddit]
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
```]]
function reddit:init()
reddit.triggers = utilities.triggers(self.info.username, {'^/r/'}):t('reddit', true):t('r', true):t('r/', true).table
end
function reddit:action(msg)
msg.text_lower = msg.text_lower:gsub('/r/', '/r r/')
local input
if msg.text_lower:match('^/r/') then
msg.text_lower = msg.text_lower:gsub('/r/', '/r r/')
input = utilities.get_word(msg.text_lower, 1)
else
input = utilities.input(msg.text_lower)
local format_results = function(posts)
local output = ''
for _,v in ipairs(posts) do
local post = v.data
local title = post.title:gsub('%[', '('):gsub('%]', ')'):gsub('&', '&')
if title:len() > 256 then
title = title:sub(1, 253)
title = utilities.trim(title) .. '...'
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
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
if msg.chat.id == msg.from.id then
if msg.chat.type == 'private' then
limit = 8
end
local source
local text = msg.text_lower
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:match('^r/.') then
url = 'http://www.reddit.com/' .. URL.escape(input) .. '/.json?limit=' .. limit
source = '*/r/' .. input:match('^r/(.+)') .. '*\n'
input = utilities.get_word(input, 1)
url = reddit.subreddit_url:format(input) .. limit
source = '*/' .. utilities.md_escape(input) .. '*\n'
else
url = 'http://www.reddit.com/search.json?q=' .. URL.escape(input) .. '&limit=' .. limit
source = '*reddit results for* _' .. input .. '_ *:*\n'
input = utilities.input(msg.text)
source = '*Results for* _' .. utilities.md_escape(input) .. '_ *:*\n'
input = URL.escape(input)
url = reddit.search_url:format(input) .. limit
end
else
url = 'http://www.reddit.com/.json?limit=' .. limit
url = reddit.rall_url .. limit
source = '*/r/all*\n'
end
local jstr, res = HTTP.request(url)
if res ~= 200 then
bindings.sendReply(self, msg, self.config.errors.connection)
return
end
local jdat = JSON.decode(jstr)
if #jdat.data.children == 0 then
bindings.sendReply(self, msg, self.config.errors.results)
return
end
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'
else
local jdat = JSON.decode(jstr)
if #jdat.data.children == 0 then
bindings.sendReply(self, msg, self.config.errors.results)
else
local output = format_results(jdat.data.children)
output = source .. output
bindings.sendMessage(self, msg.chat.id, output, true, nil, true)
end
end
output = source .. output
bindings.sendMessage(self, msg.chat.id, output, true, nil, true)
end
return reddit

View File

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