Splitting commands in plugins

This commit is contained in:
David Muñoz 2014-11-04 16:09:08 +01:00
parent bc6df5d683
commit f8161ca1cf
12 changed files with 354 additions and 240 deletions

View File

@ -1,12 +1,33 @@
http = require("socket.http") http = require("socket.http")
URL = require("socket.url") URL = require("socket.url")
json = (loadfile "./bot/JSON.lua")() json = (loadfile "./bot/JSON.lua")()
lrexlib = require("rex_pcre")
VERSION = 'v0.5' VERSION = 'v0.5'
plugins = {}
-- taken from http://stackoverflow.com/a/11130774/3163199
function scandir(directory)
local i, t, popen = 0, {}, io.popen
for filename in popen('ls -a "'..directory..'"'):lines() do
i = i + 1
t[i] = filename
end
return t
end
-- load all plugins in the plugins/ directory
for k, v in pairs(scandir("plugins")) do
if not (v:sub(0, 1) == ".") then
print("Loading plugin", v)
t = loadfile("plugins/" .. v)()
table.insert(plugins, t)
end
end
function on_msg_receive (msg) function on_msg_receive (msg)
if msg_valid(msg) == false then if msg_valid(msg) == false then
return return
end end
@ -29,11 +50,13 @@
-- write_log_file(msg) -- write_log_file(msg)
end end
function ok_cb(extra, success, result) function ok_cb(extra, success, result)
end end
function msg_valid(msg) function msg_valid(msg)
if msg.from.id == our_id then
return true
end
if msg.out then if msg.out then
return false return false
end end
@ -57,6 +80,7 @@
function send_image_from_url (msg) function send_image_from_url (msg)
last = string.get_last_word(msg.text) last = string.get_last_word(msg.text)
file = download_to_file(last) file = download_to_file(last)
print("I will send the image " .. file)
send_photo(get_receiver(msg), file, ok_cb, false) send_photo(get_receiver(msg), file, ok_cb, false)
end end
@ -99,140 +123,72 @@
-- Where magic happens -- Where magic happens
function do_action(msg) function do_action(msg)
local receiver = get_receiver(msg) local receiver = get_receiver(msg)
local text = msg.text:sub(2) -- removes the '!'
if string.starts(msg.text, '!sh') then print("Received msg", msg.text)
text = run_sh(msg) for name, desc in pairs(plugins) do
send_msg(receiver, text, ok_cb, false) regexp = desc.regexp
return runmethod = desc.run
end print("Trying", text, "against", regexp)
matches = { string.match(text, regexp) }
if string.starts(msg.text, '!uc3m') then if matches[1] then
text = get_fortunes_uc3m() print(" matches!")
send_msg(receiver, text, ok_cb, false) result = runmethod(msg, matches)
return print(" should return", result)
end if (result) then
send_msg(receiver, result, ok_cb, false)
if string.starts(msg.text, '!img') then end
text = msg.text:sub(6,-1)
url = getGoogleImage(text)
file_path = download_to_file(url)
print(file_path)
send_photo(receiver, file_path, ok_cb, false)
return
end
if string.starts(msg.text, '!rae') then
text = msg.text:sub(6,-1)
meaning = getDulcinea(text)
send_msg(receiver, meaning, ok_cb, false)
end
if string.starts(msg.text, '!9gag') then
url, title = get_9GAG()
file_path = download_to_file(url)
send_photo(receiver, file_path, ok_cb, false)
send_msg(receiver, title, ok_cb, false)
return
end
if string.starts(msg.text, '!fortune') then
text = run_bash('fortune')
send_msg(receiver, text, ok_cb, false)
return
end
if string.starts(msg.text, '!forni') then
text = msg.text:sub(8,-1)
send_msg('Fornicio_2.0', text, ok_cb, false)
return
end
if string.starts(msg.text, '!fwd') then
fwd_msg (receiver, msg.id, ok_cb, false)
return
end
if string.starts(msg.text, '!cpu') then
text = run_bash('uname -snr') .. ' ' .. run_bash('whoami')
text = text .. '\n' .. run_bash('top -b |head -2')
send_msg(receiver, text, ok_cb, false)
return
end
if string.starts(msg.text, '!ping') then
print('receiver: '..receiver)
send_msg (receiver, 'pong', ok_cb, false)
return
end
if string.starts(msg.text, '!weather') then
if string.len(msg.text) <= 9 then
city = 'Madrid,ES'
else
city = msg.text:sub(10,-1)
end end
text = get_weather(city) end
send_msg(receiver, text, ok_cb, false)
return
end
if string.starts(msg.text, '!echo') then
echo = msg.text:sub(7,-1)
send_msg(receiver, echo, ok_cb, false)
return
end
if string.starts(msg.text, '!eur') then
local eur = getEURUSD(msg.text)
send_msg(receiver, eur, ok_cb, false)
return
end
if string.starts(msg.text, '!set') then
local text = save_value(msg.text:sub(5,-1))
send_msg(receiver, text, ok_cb, false)
return
end
if string.starts(msg.text, '!get') then
local text = get_value(msg.text:sub(6,-1))
send_msg(receiver, text, ok_cb, false)
return
end
if string.starts(msg.text, '!version') then
text = 'James Bot '.. VERSION .. [[
Licencia GNU v2, código disponible en http://git.io/6jdjGg
Al Bot le gusta la gente solidaria.
Puedes hacer una donación a la ONG que decidas y ayudar a otras personas.]]
send_msg(receiver, text, ok_cb, false)
return
end
if string.starts(msg.text, '!help') then
text = [[!help : print this help
!ping : bot sends pong
!sh (text) : send commands to bash (only privileged users)
!echo (text) : echo the msg
!version : version info
!cpu : status (uname + top)
!fwd : forward msg
!forni : send text to group Fornicio
!fortune : print a random adage
!weather [city] : weather in that city (Madrid if not city)
!9gag : send random url image from 9gag
!rae (word): Spanish dictionary
!eur : EURUSD market value
!img (text) : search image with Google API and sends it
!uc3m : fortunes from Universidad Carlos III]]
send_msg(receiver, text, ok_cb, false)
return
end
end end
-- function do_action(msg)
-- local receiver = get_receiver(msg)
-- if string.starts(msg.text, '!sh') then
-- text = run_sh(msg)
-- send_msg(receiver, text, ok_cb, false)
-- return
-- end
--
-- if string.starts(msg.text, '!fortune') then
-- text = run_bash('fortune')
-- send_msg(receiver, text, ok_cb, false)
-- return
-- end
-- if string.starts(msg.text, '!forni') then
-- text = msg.text:sub(8,-1)
-- send_msg('Fornicio_2.0', text, ok_cb, false)
-- return
-- end
-- if string.starts(msg.text, '!fwd') then
-- fwd_msg (receiver, msg.id, ok_cb, false)
-- return
-- end
-- if string.starts(msg.text, '!cpu') then
-- text = run_bash('uname -snr') .. ' ' .. run_bash('whoami')
-- text = text .. '\n' .. run_bash('top -b |head -2')
-- send_msg(receiver, text, ok_cb, false)
-- return
-- end
-- if string.starts(msg.text, '!set') then
-- local text = save_value(msg.text:sub(5,-1))
-- send_msg(receiver, text, ok_cb, false)
-- return
-- end
-- if string.starts(msg.text, '!get') then
-- local text = get_value(msg.text:sub(6,-1))
-- send_msg(receiver, text, ok_cb, false)
-- return
-- end
-- end
function string.starts(String,Start) function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start return string.sub(String,1,string.len(Start))==Start
end end
@ -338,93 +294,6 @@
return result return result
end end
function get_fortunes_uc3m()
math.randomseed(os.time())
local i = math.random(0,178) -- max 178
local web = "http://www.gul.es/fortunes/f"..i
b, c, h = http.request(web)
return b
end
function getDulcinea( text )
-- Powered by https://github.com/javierhonduco/dulcinea
local api = "http://dulcinea.herokuapp.com/api/?query="
b = http.request(api..text)
dulcinea = json:decode(b)
if dulcinea.status == "error" then
return "Error: " .. dulcinea.message
end
while dulcinea.type == "multiple" do
text = dulcinea.response[1].id
b = http.request(api..text)
dulcinea = json:decode(b)
end
vardump(dulcinea)
local text = ""
local responses = #dulcinea.response
if (responses > 5) then
responses = 5
end
for i = 1, responses, 1 do
text = text .. dulcinea.response[i].word .. "\n"
local meanings = #dulcinea.response[i].meanings
if (meanings > 5) then
meanings = 5
end
for j = 1, meanings, 1 do
local meaning = dulcinea.response[i].meanings[j].meaning
text = text .. meaning .. "\n\n"
end
end
return text
end
function getGoogleImage(text)
text = URL.escape(text)
for i = 1, 5, 1 do -- Try 5 times
local api = "https://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=8&q="
b = http.request(api..text)
local google = json:decode(b)
if (google.responseStatus == 200) then -- OK
math.randomseed(os.time())
i = math.random(#google.responseData.results) -- Random image from results
return google.responseData.results[i].url
end
end
end
function get_9GAG()
b = http.request("http://api-9gag.herokuapp.com/")
local gag = json:decode(b)
math.randomseed(os.time())
i = math.random(#gag) -- random max json table size (# is an operator o.O)
local link_image = gag[i].src
local title = gag[i].title
if link_image:sub(0,2) == '//' then
link_image = msg.text:sub(3,-1)
end
return link_image, title
end
function getEURUSD(text)
b = http.request("http://webrates.truefx.com/rates/connect.html?c=EUR/USD&f=csv&s=n")
local rates = b:split(", ")
local symbol = rates[1]
local timestamp = rates[2]
local sell = rates[3]..rates[4]
local buy = rates[5]..rates[6]
local usd = string.match(text, "!eur (%d+[%d%.]*)")
text = symbol..'\n'..'Buy: '..buy..'\n'..'Sell: '..sell
if usd then
eur = tonumber(usd) / tonumber(buy)
text = text.."\n "..usd.."USD = "..eur.."EUR"
end
return text
end
function download_to_file( url ) function download_to_file( url )
print("url a descargar: "..url) print("url a descargar: "..url)
req, c, h = http.request(url) req, c, h = http.request(url)
@ -454,26 +323,6 @@
return file_path return file_path
end end
function get_weather(location)
b, c, h = http.request("http://api.openweathermap.org/data/2.5/weather?q=" .. location .. "&units=metric")
weather = json:decode(b)
local city = weather.name
local country = weather.sys.country
temp = 'The temperature in ' .. city .. ' (' .. country .. ')'
temp = temp .. ' is ' .. weather.main.temp .. '°C'
conditions = 'Current conditions are: ' .. weather.weather[1].description
if weather.weather[1].main == 'Clear' then
conditions = conditions .. ''
elseif weather.weather[1].main == 'Clouds' then
conditions = conditions .. ' ☁☁'
elseif weather.weather[1].main == 'Rain' then
conditions = conditions .. ''
elseif weather.weather[1].main == 'Thunderstorm' then
conditions = conditions .. ' ☔☔☔☔'
end
return temp .. '\n' .. conditions
end
function string.random(length) function string.random(length)
math.randomseed(os.time()) math.randomseed(os.time())
local str = ""; local str = "";

29
plugins/9gag.lua Normal file
View File

@ -0,0 +1,29 @@
function get_9GAG()
b = http.request("http://api-9gag.herokuapp.com/")
local gag = json:decode(b)
math.randomseed(os.time())
i = math.random(#gag) -- random max json table size (# is an operator o.O)
local link_image = gag[i].src
local title = gag[i].title
if link_image:sub(0,2) == '//' then
link_image = msg.text:sub(3,-1)
end
return link_image, title
end
function run(msg, matches)
local receiver = get_receiver(msg)
url, title = get_9GAG()
file_path = download_to_file(url)
send_photo(receiver, file_path, ok_cb, false)
return title
end
return {
description = "send random url image from 9gag",
usage = "9gag",
regexp = "^9gag$",
run = run
}

12
plugins/echo.lua Normal file
View File

@ -0,0 +1,12 @@
function run(msg, matches)
return matches[1]
end
return {
description = "echoes the msg",
usage = "echo [whatever]",
regexp = "^echo (.*)$",
run = run
}

27
plugins/eur.lua Normal file
View File

@ -0,0 +1,27 @@
function getEURUSD(usd)
b = http.request("http://webrates.truefx.com/rates/connect.html?c=EUR/USD&f=csv&s=n")
local rates = b:split(", ")
local symbol = rates[1]
local timestamp = rates[2]
local sell = rates[3]..rates[4]
local buy = rates[5]..rates[6]
text = symbol..'\n'..'Buy: '..buy..'\n'..'Sell: '..sell
if usd then
eur = tonumber(usd) / tonumber(buy)
text = text.."\n "..usd.."USD = "..eur.."EUR"
end
return text
end
function run(msg, matches)
return getEURUSD(matches[1])
end
return {
description = "EURUSD market value",
usage = "eur [USD]",
regexp = "^eur (%d+[%d%.]*)$",
run = run
}

21
plugins/fortunes_uc3m.lua Normal file
View File

@ -0,0 +1,21 @@
function get_fortunes_uc3m()
math.randomseed(os.time())
local i = math.random(0,178) -- max 178
local web = "http://www.gul.es/fortunes/f"..i
b, c, h = http.request(web)
return b
end
function run(msg, matches)
return get_fortunes_uc3m()
end
return {
description = "Fortunes from Universidad Carlos III",
usage = "uc3m",
regexp = "^uc3m$",
run = run
}

12
plugins/hello.lua Normal file
View File

@ -0,0 +1,12 @@
function run(msg, matches)
return "Hello," .. matches[1]
end
return {
description = "Says hello to someone",
usage = "say hello to [name]",
regexp = "^say hello to (.*)$",
run = run
}

16
plugins/help.lua Normal file
View File

@ -0,0 +1,16 @@
function run(msg, matches)
local ret = ""
for k, dict in pairs(plugins) do
ret = ret .. dict.usage .. " -> " .. dict.description .. "\n"
end
return ret
end
return {
description = "Lists all available commands",
usage = "help",
regexp = "^help$",
run = run
}

33
plugins/images.lua Normal file
View File

@ -0,0 +1,33 @@
function getGoogleImage(text)
text = URL.escape(text)
for i = 1, 5, 1 do -- Try 5 times
local api = "https://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=8&q="
b = http.request(api..text)
local google = json:decode(b)
if (google.responseStatus == 200) then -- OK
math.randomseed(os.time())
i = math.random(#google.responseData.results) -- Random image from results
return google.responseData.results[i].url
end
end
end
function run(msg, matches)
local receiver = get_receiver(msg)
local text = msg.text:sub(6,-1)
local url = getGoogleImage(text)
local file_path = download_to_file(url)
print(file_path)
send_photo(receiver, file_path, ok_cb, false)
return nil
end
return {
description = "search image with Google API and sends it",
usage = "img [topic]",
regexp = "^img (.*)$",
run = run
}

14
plugins/ping.lua Normal file
View File

@ -0,0 +1,14 @@
function run(msg, matches)
local receiver = get_receiver(msg)
print('receiver: '..receiver)
return "pong"
end
return {
description = "bot sends pong",
usage = "ping",
regexp = "^ping$",
run = run
}

46
plugins/rae.lua Normal file
View File

@ -0,0 +1,46 @@
function getDulcinea( text )
-- Powered by https://github.com/javierhonduco/dulcinea
local api = "http://dulcinea.herokuapp.com/api/?query="
b = http.request(api..text)
dulcinea = json:decode(b)
if dulcinea.status == "error" then
return "Error: " .. dulcinea.message
end
while dulcinea.type == "multiple" do
text = dulcinea.response[1].id
b = http.request(api..text)
dulcinea = json:decode(b)
end
vardump(dulcinea)
local text = ""
local responses = #dulcinea.response
if (responses > 5) then
responses = 5
end
for i = 1, responses, 1 do
text = text .. dulcinea.response[i].word .. "\n"
local meanings = #dulcinea.response[i].meanings
if (meanings > 5) then
meanings = 5
end
for j = 1, meanings, 1 do
local meaning = dulcinea.response[i].meanings[j].meaning
text = text .. meaning .. "\n\n"
end
end
return text
end
function run(msg, matches)
return getDulcinea(matches[1])
end
return {
description = "Spanish dictionary",
usage = "rae [word]",
regexp = "^rae (.*)$",
run = run
}

16
plugins/version.lua Normal file
View File

@ -0,0 +1,16 @@
function run(msg, matches)
return 'James Bot '.. VERSION .. [[
Licencia GNU v2, código disponible en http://git.io/6jdjGg
Al Bot le gusta la gente solidaria.
Puedes hacer una donación a la ONG que decidas y ayudar a otras personas.]]
end
return {
description = "Shows the bot version",
usage = "version",
regexp = "^version$",
run = run
}

39
plugins/weather.lua Normal file
View File

@ -0,0 +1,39 @@
function get_weather(location)
print("Finding weather in ", location)
b, c, h = http.request("http://api.openweathermap.org/data/2.5/weather?q=" .. location .. "&units=metric")
weather = json:decode(b)
print("Weather returns", weather)
local city = weather.name
local country = weather.sys.country
temp = 'The temperature in ' .. city .. ' (' .. country .. ')'
temp = temp .. ' is ' .. weather.main.temp .. '°C'
conditions = 'Current conditions are: ' .. weather.weather[1].description
if weather.weather[1].main == 'Clear' then
conditions = conditions .. ''
elseif weather.weather[1].main == 'Clouds' then
conditions = conditions .. ' ☁☁'
elseif weather.weather[1].main == 'Rain' then
conditions = conditions .. ''
elseif weather.weather[1].main == 'Thunderstorm' then
conditions = conditions .. ' ☔☔☔☔'
end
return temp .. '\n' .. conditions
end
function run(msg, matches)
if string.len(matches[1]) > 2 then
city = matches[1]
else
city = "Madrid,ES"
end
return get_weather(city)
end
return {
description = "weather in that city (Madrid is default)",
usage = "weather [city]",
regexp = "^weather(.*)$",
run = run
}