big update

too much changed ._.
This commit is contained in:
Akamaru 2015-05-28 16:47:30 +02:00
parent 1e77e4de80
commit bd5ae0d642
21 changed files with 409 additions and 279 deletions

View File

@ -1,3 +1,7 @@
package.path = package.path .. ';.luarocks/share/lua/5.2/?.lua'
..';.luarocks/share/lua/5.2/?/init.lua'
package.cpath = package.cpath .. ';.luarocks/lib/lua/5.2/?.so'
require("./bot/utils") require("./bot/utils")
VERSION = '2.5-reloaded' VERSION = '2.5-reloaded'
@ -12,10 +16,13 @@ function on_msg_receive (msg)
local receiver = get_receiver(msg) local receiver = get_receiver(msg)
-- vardump(msg) -- vardump(msg)
msg = pre_process_service_msg(msg)
if msg_valid(msg) then if msg_valid(msg) then
msg = pre_process_msg(msg) msg = pre_process_msg(msg)
match_plugins(msg) if msg then
--mark_read(receiver, ok_cb, false) match_plugins(msg)
--mark_read(receiver, ok_cb, false)
end
end end
end end
@ -25,7 +32,7 @@ end
function on_binlog_replay_end() function on_binlog_replay_end()
started = true started = true
postpone (cron_plugins, false, 60*5.0) postpone (cron_plugins, false, 60*5.0)
-- See plugins/ping.lua as an example for cron -- See plugins/isup.lua as an example for cron
_config = load_config() _config = load_config()
cred_data = load_cred() cred_data = load_cred()
@ -36,7 +43,7 @@ function on_binlog_replay_end()
end end
function msg_valid(msg) function msg_valid(msg)
-- Dont process outgoing messages -- Don't process outgoing messages
if msg.out then if msg.out then
print('\27[36mNicht gültig: Nachricht von mir\27[39m') print('\27[36mNicht gültig: Nachricht von mir\27[39m')
return false return false
@ -53,11 +60,6 @@ function msg_valid(msg)
return false return false
end end
if msg.service then
print('\27[36mNicht gültig: Service\27[39m')
return false
end
if not msg.to.id then if not msg.to.id then
print('\27[36mNicht gültig: To id not provided\27[39m') print('\27[36mNicht gültig: To id not provided\27[39m')
return false return false
@ -68,13 +70,48 @@ function msg_valid(msg)
return false return false
end end
if msg.from.id == our_id then
print('\27[36mNicht gültig: Nachricht von unserer ID\27[39m')
return false
end
if msg.to.type == 'encr_chat' then
print('\27[36mNicht gültig: Encrypted Chat\27[39m')
return false
end
if msg.from.id == 777000 then
print('\27[36mNicht gültig: Telegram Nachricht\27[39m')
return false
end
return true return true
end end
--
function pre_process_service_msg(msg)
if msg.service then
local action = msg.action or {type=""}
-- Double / to discriminate of normal actions
msg.text = "//tgservice " .. action.type
msg.realservice = true
-- wipe the data to allow the bot to read service messages
if msg.out then
msg.out = false
end
if msg.from.id == our_id then
msg.from.id = 0
end
end
return msg
end
-- Apply plugin.pre_process function -- Apply plugin.pre_process function
function pre_process_msg(msg) function pre_process_msg(msg)
for name,plugin in pairs(plugins) do for name,plugin in pairs(plugins) do
if plugin.pre_process then if plugin.pre_process and msg then
msg = plugin.pre_process(msg) msg = plugin.pre_process(msg)
end end
end end
@ -110,7 +147,7 @@ end
function match_plugin(plugin, plugin_name, msg) function match_plugin(plugin, plugin_name, msg)
local receiver = get_receiver(msg) local receiver = get_receiver(msg)
-- Go over patterns. If one matches is enough. -- Go over patterns. If one matches it's enough.
for k, pattern in pairs(plugin.patterns) do for k, pattern in pairs(plugin.patterns) do
local matches = match_pattern(pattern, msg.text) local matches = match_pattern(pattern, msg.text)
if matches then if matches then
@ -154,7 +191,7 @@ function save_config( )
end end
-- Returns the config from config.lua file. -- Returns the config from config.lua file.
-- If file doesnt exists, create it. -- If file doesn't exist, create it.
function load_config( ) function load_config( )
local f = io.open('./data/config.lua', "r") local f = io.open('./data/config.lua', "r")
-- If config.lua doesnt exists -- If config.lua doesnt exists
@ -186,7 +223,7 @@ end
-- Create a basic config.json file and saves it. -- Create a basic config.json file and saves it.
function create_config( ) function create_config( )
-- A simple config with basic plugins and ourserves as priviled user -- A simple config with basic plugins and ourselves as privileged user
config = { config = {
enabled_plugins = { enabled_plugins = {
"help", "help",

View File

@ -5,6 +5,7 @@ URL = require "socket.url"
json = (loadfile "./libs/JSON.lua")() json = (loadfile "./libs/JSON.lua")()
serpent = (loadfile "./libs/serpent.lua")() serpent = (loadfile "./libs/serpent.lua")()
mimetype = (loadfile "./libs/mimetype.lua")() mimetype = (loadfile "./libs/mimetype.lua")()
redis = (loadfile "./libs/redis.lua")()
http.TIMEOUT = 10 http.TIMEOUT = 10
@ -55,9 +56,9 @@ function string:trim()
end end
function get_http_file_name(url, headers) function get_http_file_name(url, headers)
-- Eg: fooo.var -- Eg: foo.var
local file_name = url:match("[^%w]+([%.%w]+)$") local file_name = url:match("[^%w]+([%.%w]+)$")
-- Any delimited aphanumeric on the url -- Any delimited alphanumeric on the url
file_name = file_name or url:match("[^%w]+(%w+)[^%w]+$") file_name = file_name or url:match("[^%w]+(%w+)[^%w]+$")
-- Random name, hope content-type works -- Random name, hope content-type works
file_name = file_name or str:random(5) file_name = file_name or str:random(5)
@ -105,7 +106,7 @@ function download_to_file(url, file_name)
file_name = file_name or get_http_file_name(url, headers) file_name = file_name or get_http_file_name(url, headers)
local file_path = "/home/pi/Mikubot/tmp/"..file_name local file_path = "tmp/"..file_name
print("Gespeichert in: "..file_path) print("Gespeichert in: "..file_path)
file = io.open(file_path, "w+") file = io.open(file_path, "w+")
@ -138,7 +139,7 @@ function run_command(str)
return result return result
end end
-- User has priviledges -- User has privileges
function is_sudo(msg) function is_sudo(msg)
local var = false local var = false
-- Check users id in config -- Check users id in config
@ -210,12 +211,12 @@ function serialize_to_file(data, file, uglify)
file:close() file:close()
end end
-- Retruns true if the string is empty -- Returns true if the string is empty
function string:isempty() function string:isempty()
return self == nil or self == '' return self == nil or self == ''
end end
-- Retruns true if the string is blank -- Returns true if the string is blank
function string:isblank() function string:isblank()
self = self:trim() self = self:trim()
return self:isempty() return self:isempty()
@ -276,7 +277,7 @@ function send_photo_from_url_callback(cb_extra, success, result)
end end
end end
-- Send multimple images asynchronous. -- Send multiple images asynchronous.
-- param urls must be a table. -- param urls must be a table.
function send_photos_from_url(receiver, urls) function send_photos_from_url(receiver, urls)
local cb_extra = { local cb_extra = {
@ -288,7 +289,7 @@ function send_photos_from_url(receiver, urls)
end end
-- Use send_photos_from_url. -- Use send_photos_from_url.
-- This fuction might be difficult to understand. -- This function might be difficult to understand.
function send_photos_from_url_callback(cb_extra, success, result) function send_photos_from_url_callback(cb_extra, success, result)
-- cb_extra is a table containing receiver, urls and remove_path -- cb_extra is a table containing receiver, urls and remove_path
local receiver = cb_extra.receiver local receiver = cb_extra.receiver
@ -330,7 +331,7 @@ function rmtmp_cb(cb_extra, success, result)
os.remove(file_path) os.remove(file_path)
print(file_path.." gelöscht!") print(file_path.." gelöscht!")
end end
-- Finaly call the callback -- Finally call the callback
cb_function(cb_extra, success, result) cb_function(cb_extra, success, result)
end end
@ -394,7 +395,7 @@ function user_allowed(plugin, msg)
return true return true
end end
-- Same as send_large_msg_callback but frienly params -- Same as send_large_msg_callback but friendly params
function send_large_msg(destination, text) function send_large_msg(destination, text)
local cb_extra = { local cb_extra = {
destination = destination, destination = destination,
@ -450,12 +451,13 @@ function sleep(n)
end end
-- Function to read data from files -- Function to read data from files
function load_from_file(file) function load_from_file(file, default_data)
local f = io.open(file, "r+") local f = io.open(file, "r+")
-- If file doesn't exists -- If file doesn't exists
if f == nil then if f == nil then
-- Create a new empty table -- Create a new empty table
serialize_to_file({}, file) default_data = default_data or {}
serialize_to_file(default_data, file)
print ('Erstelle Datei', file) print ('Erstelle Datei', file)
else else
print ('Daten geladen von', file) print ('Daten geladen von', file)
@ -463,3 +465,10 @@ function load_from_file(file)
end end
return loadfile (file)() return loadfile (file)()
end end
function run_bash(str)
local cmd = io.popen(str)
local result = cmd:read('*all')
cmd:close()
return result
end

View File

@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
THIS_DIR=$(cd $(dirname $0); pwd) THIS_DIR=$(cd $(dirname $0); pwd)
RAM=`grep MemTotal /proc/meminfo | awk '{print $2}'`
cd $THIS_DIR cd $THIS_DIR
update() { update() {
@ -42,12 +43,37 @@ install_rocks() {
RET=$?; if [ $RET -ne 0 ]; RET=$?; if [ $RET -ne 0 ];
then echo "Error. Exiting."; exit $RET; then echo "Error. Exiting."; exit $RET;
fi fi
./.luarocks/bin/luarocks install redis-lua
RET=$?; if [ $RET -ne 0 ];
then echo "Error. Exiting."; exit $RET;
fi
./.luarocks/bin/luarocks install lua-cjson
RET=$?; if [ $RET -ne 0 ];
then echo "Error. Exiting."; exit $RET;
fi
./.luarocks/bin/luarocks install fakeredis
RET=$?; if [ $RET -ne 0 ];
then echo "Error. Exiting."; exit $RET;
fi
./.luarocks/bin/luarocks install xml
RET=$?; if [ $RET -ne 0 ];
then echo "Error. Exiting."; exit $RET;
fi
} }
install() { install() {
git pull git pull
git submodule update --init --recursive git submodule update --init --recursive
cd tg && ./configure && make # If RAM is lower than 300MB disable extf queries
if [ $RAM -lt 307200 ]; then
cd tg && ./configure --disable-extf && make
else
cd tg && ./configure && make
fi
RET=$?; if [ $RET -ne 0 ]; RET=$?; if [ $RET -ne 0 ];
then echo "Error. Exiting."; exit $RET; then echo "Error. Exiting."; exit $RET;
fi fi
@ -73,7 +99,5 @@ else
exit 1 exit 1
fi fi
LUA_PATH=";;.luarocks/share/lua/5.2/?.lua;.luarocks/share/lua/5.2/?/init.lua" \ ./tg/bin/telegram-cli -k ./tg/tg-server.pub -s ./bot/bot.lua -l 1 -E
LUA_CPATH=";;.luarocks/lib/lua/5.2/?.so" \
./tg/bin/telegram-cli -k ./tg/tg-server.pub -s ./bot/bot.lua -l 1
fi fi

47
libs/redis.lua Normal file
View File

@ -0,0 +1,47 @@
local Redis = require 'redis'
local FakeRedis = require 'fakeredis'
local params = {
host = '127.0.0.1',
port = 6379,
}
-- Overwrite HGETALL
Redis.commands.hgetall = Redis.command('hgetall', {
response = function(reply, command, ...)
local new_reply = { }
for i = 1, #reply, 2 do new_reply[reply[i]] = reply[i + 1] end
return new_reply
end
})
local redis = nil
-- Won't launch an error if fails
local ok = pcall(function()
redis = Redis.connect(params)
end)
if not ok then
local fake_func = function()
print('\27[31mCan\'t connect with Redis, install/configure it!\27[39m')
end
fake_func()
fake = FakeRedis.new()
print('\27[31mRedis addr: '..params.host..'\27[39m')
print('\27[31mRedis port: '..params.port..'\27[39m')
redis = setmetatable({fakeredis=true}, {
__index = function(a, b)
if b ~= 'data' and fake[b] then
fake_func(b)
end
return fake[b] or fake_func
end })
end
return redis

View File

@ -24,7 +24,6 @@ end
local function run(msg, matches) local function run(msg, matches)
local receiver = get_receiver(msg) local receiver = get_receiver(msg)
local url, title = get_9GAG() local url, title = get_9GAG()
local file_path = download_to_file(url)
send_photo_from_url(receiver, url, send_title, {receiver, title}) send_photo_from_url(receiver, url, send_title, {receiver, title})
return false return false
end end

View File

@ -11,7 +11,7 @@ local function getRandomButts(attempt)
local data = json:decode(res)[1] local data = json:decode(res)[1]
-- The OpenBoobs API sometimes returns an empty array -- The OpenBoobs API sometimes returns an empty array
if not data and attempt < 3 then if not data and attempt <= 3 then
print('Keine Butts gefunden!') print('Keine Butts gefunden!')
return getRandomButts(attempt) return getRandomButts(attempt)
end end

View File

@ -40,7 +40,7 @@ end
local function pre_process(msg) local function pre_process(msg)
local receiver = get_receiver(msg) local receiver = get_receiver(msg)
-- If is sudo can reeanble the channel -- If sender is sudo then re-enable the channel
if is_sudo(msg) then if is_sudo(msg) then
if msg.text == "/channel enable" then if msg.text == "/channel enable" then
enable_channel(receiver) enable_channel(receiver)

14
plugins/cowsay.lua Normal file
View File

@ -0,0 +1,14 @@
function run(msg, matches)
cow = matches[1]
local receiver = get_receiver(msg)
local text = run_bash('cowsay "' .. cow .. '"')
send_msg(receiver, text, ok_cb, false)
end
return {
description = "",
usage = {""},
patterns = {"^/cowsay (.*)$"},
run = run
}
--by Akamaru [https://ponywave.de]

View File

@ -7,19 +7,15 @@ local scale_day = "?scale=day"
local scale_week = "?scale=week" local scale_week = "?scale=week"
local scale_month = "?scale=month" local scale_month = "?scale=month"
function get_post(url) local function get_post(url)
local b, c, h = http.request(url) local b, c, h = http.request(url)
if c ~= 200 then return nil end
local posts = json:decode(b) local posts = json:decode(b)
-- bad random - bad magic...
math.randomseed( os.time() )
math.random(#posts)
math.random(#posts)
return posts[math.random(#posts)] return posts[math.random(#posts)]
end end
function run(msg, matches) local function run(msg, matches)
local url = URL local url = URL
@ -28,39 +24,48 @@ function run(msg, matches)
else else
url = url .. URL_POP url = url .. URL_POP
if matches[1] == "/dand" then if matches[1] == "d" then
url = url .. scale_day url = url .. scale_day
elseif matches[1] == "/danw" then elseif matches[1] == "w" then
url = url .. scale_week url = url .. scale_week
elseif matches[1] == "/danm" then elseif matches[1] == "m" then
url = url .. scale_month url = url .. scale_month
end end
end end
local post = get_post(url) local post = get_post(url)
local receiver = get_receiver(msg) if post then
local img = URL .. post.large_file_url vardump(post)
send_photo_from_url(receiver, img) local img = URL .. post.large_file_url
send_photo_from_url(get_receiver(msg), img)
local txt = 'Artist: ' .. post.tag_string_artist .. '\n' local txt = ''
txt = txt .. 'Character: ' .. post.tag_string_character .. '\n' if post.tag_string_artist ~= '' then
--txt = txt .. '[' .. math.ceil(post.file_size/1000) .. 'kb] ' .. URL .. post.file_url txt = 'Artist: ' .. post.tag_string_artist .. '\n'
return txt end
if post.tag_string_character ~= '' then
txt = txt .. 'Character: ' .. post.tag_string_character .. '\n'
end
if post.file_size ~= '' then
txt = txt .. '[' .. math.ceil(post.file_size/1000) .. 'kb] ' .. URL .. post.file_url
end
return txt
end
end end
return { return {
description = "Gets a random fresh or popular image from Danbooru", description = "Gets a random fresh or popular image from Danbooru",
usage = { usage = {
"/dan - gets a random fresh image from Danbooru 🔞", "/dan - gets a random fresh image from Danbooru 🔞",
"/dand - random daily popular image 🔞", "/dan d - random daily popular image 🔞",
"/danw - random weekly popular image 🔞", "/dan w - random weekly popular image 🔞",
"/danm - random monthly popular image 🔞"}, "/dan m - random monthly popular image 🔞"},
patterns = { patterns = {
"^/dan$", "^/dan$",
"^/dand$", "^/dan ?(d)$",
"^/danw$", "^/dan ?(w)$",
"^/danm$"}, "^/dan ?(m)$"},
run = run run = run
} }

View File

@ -1,5 +1,12 @@
local function run(msg, matches) local function run(msg, matches)
return matches[1] local text = matches[1]
local b = 1
while b ~= 0 do
text,b = text:gsub('^/+','')
text = text:trim()
end
return text
end end
return { return {

View File

@ -1,78 +1,49 @@
local _file_values = './data/values.lua' local function get_variables_hash(msg)
if msg.to.type == 'chat' then
_values = load_from_file(_file_values) return 'chat:'..msg.to.id..':variables'
local function fetch_value(chat, value_name)
-- Chat non exists
if _values[chat] == nil then
return nil
end end
if msg.to.type == 'user' then
if value_name == nil then return 'user:'..msg.from.id..':variables'
return nil
end end
local value = _values[chat][value_name]
return value
end end
local function get_value(chat, value_name) local function list_variables(msg)
local hash = get_variables_hash(msg)
-- If chat values is empty if hash then
if (_values[chat] == nil) then local names = redis:hkeys(hash)
return "Hier sind keine Daten" local text = ''
end for i=1, #names do
text = text..names[i]..'\n'
-- If there is not value name, return all the values.
if (value_name == nil ) then
local text = ""
for key,value in pairs(_values[chat]) do
text = text..key.." = "..value.."\n"
end end
return text return text
end end
local value = _values[chat][value_name] end
if ( value == nil) then
return 'Konnte "'..value_name..' nicht finden' local function get_value(msg, var_name)
local hash = get_variables_hash(msg)
if hash then
local value = redis:hget(hash, var_name)
if not value then
return'Not found, use "/get" to list variables'
else
return var_name..' => '..value
end
end end
return value_name.." = "..value
end end
local function run(msg, matches) local function run(msg, matches)
local chat_id = tostring(msg.to.id) if matches[2] then
if matches[1] == "/get" then return get_value(msg, matches[2])
return get_value(chat_id, nil) else
return list_variables(msg)
end end
return get_value(chat_id, matches[1])
end
local function lex(msg)
if msg.text then
local text = msg.text
local chat_id = tostring(msg.to.id)
local s, e = text:find("%$%a+")
if s then
local var = text:sub(s + 1, e)
local value = fetch_value(chat_id, var)
if (value == nil) then
value = "(Unbekannter Wert " .. var .. ")"
end
msg.text = text:sub(0, s - 1) .. value .. text:sub(e + 1)
end
end
return msg
end end
return { return {
description = "Bekommt Variable, die mit /set gesetzt wurde", description = "Bekommt Variable, die mit /set gesetzt wurde",
usage = {"/get (Variable)"}, usage = {"/get (Variable)"},
patterns = {"^/get (%a+)$","^/get$"}, patterns = {"^/get (%a+)$","^/get$"},
patterns = {"^/get (%a+)$","^/get$"},
run = run, run = run,
pre_process = lex pre_process = lex
} }

View File

@ -38,16 +38,10 @@ local function search(text)
return get_image(response) return get_image(response)
end end
local function send_gif(cb_extra, success, result)
local receiver = cb_extra.receiver
local gif_url = cb_extra.gif_url
send_document_from_url(receiver, gif_url)
end
local function run(msg, matches) local function run(msg, matches)
local gif_url = nil local gif_url = nil
-- If no search data, a random trending GIF will be sended -- If no search data, a random trending GIF will be sent
if matches[1] == "/gif" or matches[1] == "/giphy" then if matches[1] == "/gif" or matches[1] == "/giphy" then
gif_url = get_random_top() gif_url = get_random_top()
else else
@ -55,17 +49,12 @@ local function run(msg, matches)
end end
if not gif_url then if not gif_url then
return "Kein GIF gefunden!" return 'Keine GIF gefunden!'
end end
local receiver = get_receiver(msg) local receiver = get_receiver(msg)
print("GIF URL"..gif_url) print("GIF URL: "..gif_url)
local text = 'Einen Moment, GIF wird hochgeladen.' send_document_from_url(receiver, gif_url)
local cb_extra = {
gif_url = gif_url,
receiver = receiver
}
send_msg(receiver, text, send_gif, cb_extra)
end end
return { return {

View File

@ -1,4 +1,4 @@
function googlethat(query) local function googlethat(query)
local api = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&safe=active&hl=de&" local api = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&safe=active&hl=de&"
local parameters = "q=".. (URL.escape(query) or "") local parameters = "q=".. (URL.escape(query) or "")
@ -7,7 +7,7 @@ function googlethat(query)
if code ~=200 then return nil end if code ~=200 then return nil end
local data = json:decode(res) local data = json:decode(res)
local results={} local results = {}
for key,result in ipairs(data.responseData.results) do for key,result in ipairs(data.responseData.results) do
table.insert(results, { table.insert(results, {
result.titleNoFormatting, result.titleNoFormatting,
@ -17,7 +17,7 @@ function googlethat(query)
return results return results
end end
function stringlinks(results) local function stringlinks(results)
local stringresults="" local stringresults=""
for key,val in ipairs(results) do for key,val in ipairs(results) do
stringresults=stringresults..val[1].." - "..val[2].."\n" stringresults=stringresults..val[1].." - "..val[2].."\n"
@ -25,7 +25,7 @@ function stringlinks(results)
return stringresults return stringresults
end end
function run(msg, matches) local function run(msg, matches)
local results = googlethat(matches[1]) local results = googlethat(matches[1])
return stringlinks(results) return stringlinks(results)
end end

View File

@ -1,32 +1,36 @@
-- Invite other user to the chat group. -- Invite other user to the chat group.
-- Use /invite name User_name or /invite id id_number -- Use !invite name User_name or !invite id id_number
-- The User_name is the print_name (there are no spaces but _) -- The User_name is the print_name (there are no spaces but _)
do do
local function callback(extra, success, result)
vardump(success)
vardump(result)
end
local function run(msg, matches) local function run(msg, matches)
-- User submitted a user name local user = matches[2]
if matches[1] == "name" then
user = matches[2] -- User submitted a user name
user = string.gsub(user," ","_") if matches[1] == "name" then
end user = string.gsub(user," ","_")
-- User submitted an id end
if matches[1] == "id" then
user = matches[2] -- User submitted an id
user = 'user#id'..user if matches[1] == "id" then
end user = 'user#id'..user
-- The message must come from a chat group end
if msg.to.type == 'chat' then
chat = 'chat#id'..msg.to.id -- The message must come from a chat group
else if msg.to.type == 'chat' then
return 'Dies ist keine Gruppe!!' local chat = 'chat#id'..msg.to.id
end chat_add_user(chat, user, callback, false)
print ("Füge "..user.." zu "..chat.." hinzu") return "User "..user.." zu "..chat.." hinzugefügt!"
status = chat_add_user (chat, user, ok_cb, false) else
if not status then return 'Dies ist keine Gruppe!!'
return "Ein Fehler ist aufgetreten" end
end
return "User "..user.." zu "..chat.." hinzugefügt!"
end end
return { return {

View File

@ -9,7 +9,7 @@ end
local function run(msg, matches) local function run(msg, matches)
if msg.media then if msg.media then
if msg.media.type == 'document' then if msg.media.type == 'document' then
load_document(msg.id, callback, msg.id) load_document(msg.id, callback, msg.id)
end end
if msg.media.type == 'photo' then if msg.media.type == 'photo' then

View File

@ -1,6 +1,6 @@
do do
-- Retruns the key (index) in the config.enabled_plugins table -- Returns the key (index) in the config.enabled_plugins table
local function plugin_enabled( name ) local function plugin_enabled( name )
for k,v in pairs(_config.enabled_plugins) do for k,v in pairs(_config.enabled_plugins) do
if name == v then if name == v then
@ -126,7 +126,7 @@ local function run(msg, matches)
return list_plugins() return list_plugins()
end end
-- Reenable a plugin for this chat -- Re-enable a plugin for this chat
if matches[1] == 'enable' and matches[3] == 'chat' then if matches[1] == 'enable' and matches[3] == 'chat' then
local receiver = get_receiver(msg) local receiver = get_receiver(msg)
local plugin = matches[2] local plugin = matches[2]

View File

@ -32,7 +32,7 @@ end
return { return {
description = "Sendet euch ein Charakter aus Sakurasou no Pet na Kanojo", description = "Sendet euch ein Charakter aus Sakurasou no Pet na Kanojo",
usage = {"/shiina","/Shiina","/chihiro","/Chihiro","/jin","/Jin","/misaki","/Misaki","/nanami","/Nanami","/ryuunosuke","/Ryuunosuke","/sorata","/Sorata"}, usage = {"/shiina","/Shiina","/chihiro","/Chihiro","/jin","/Jin","/misaki","/Misaki","/nanami","/Nanami","/ryuunosuke","/Ryuunosuke","/sorata","/Sorata"},
patterns = {"^/shiina$","^/Shiina$","^/chihiro$","^/Chihiro"$,"^/jin$","^/Jin$","^/misaki$","^/Misaki$","^/nanami$","^/Nanami$","^/ryuunosuke$","^/Ryuunosuke$","^/sorata$","^/Sorata$"}, patterns = {"^/shiina$","^/Shiina$","^/chihiro$","^/Chihiro$","^/jin$","^/Jin$","^/misaki$","^/Misaki$","^/nanami$","^/Nanami$","^/ryuunosuke$","^/Ryuunosuke$","^/sorata$","^/Sorata$"},
run = run run = run
} }
--by Akamaru [https://ponywave.de] --by Akamaru [https://ponywave.de]

View File

@ -6,13 +6,6 @@ function run_sh(msg)
return text return text
end end
function run_bash(str)
local cmd = io.popen(str)
local result = cmd:read('*all')
cmd:close()
return result
end
function run(msg, matches) function run(msg, matches)
local receiver = get_receiver(msg) local receiver = get_receiver(msg)
if string.starts(msg.text, '/sh') then if string.starts(msg.text, '/sh') then

View File

@ -1,115 +1,153 @@
-- Saves the number of messages from a user -- Saves the number of messages from a user
-- Can check the number of messages with !stats -- Can check the number of messages with /stats
do do
local socket = require('socket') local NUM_MSG_MAX = 500
local _file_stats = './data/stats.lua' local TIME_CHECK = 4 -- seconds
local _stats
function update_user_stats(msg) local function user_print_name(user)
-- Save user to stats table if user.print_name then
local from_id = tostring(msg.from.id) return user.print_name
local to_id = tostring(msg.to.id)
local user_name = get_name(msg)
print ('Neue Nachricht von '..user_name..'['..from_id..']'..' in '..to_id)
-- If last name is nil dont save last_name.
local user_last_name = msg.from.last_name
local user_print_name = msg.from.print_name
if _stats[to_id] == nil then
print ('Neuer stats key to_id: '..to_id)
_stats[to_id] = {}
end
if _stats[to_id][from_id] == nil then
print ('Neuer stats key from_id: '..to_id)
_stats[to_id][from_id] = {
user_id = from_id,
name = user_name,
last_name = user_last_name,
print_name = user_print_name,
msg_num = 1
}
else
print ('Updated '..to_id..' '..from_id)
local actual_num = _stats[to_id][from_id].msg_num
_stats[to_id][from_id].msg_num = actual_num + 1
_stats[to_id][from_id].user_id = from_id
_stats[to_id][from_id].last_name = user_last_name
end
end
function read_file_stats( )
local f = io.open(_file_stats, "r+")
-- If file doesn't exists
if f == nil then
-- Create a new empty table
print ('"user stats file" erstellt '.._file_stats)
serialize_to_file({}, _file_stats)
else
print ('Stats geladen: '.._file_stats)
f:close()
end
return loadfile (_file_stats)()
end
local function save_stats()
-- Save stats to file
serialize_to_file(_stats, _file_stats)
end
local function get_stats_status( msg )
-- vardump(stats)
local text = ""
local to_id = tostring(msg.to.id)
local rank = {}
for id, user in pairs(_stats[to_id]) do
table.insert(rank, user)
end end
table.sort(rank, function(a, b) local text = ''
if a.msg_num and b.msg_num then if user.first_name then
return a.msg_num > b.msg_num text = user.last_name..' '
end
end
)
for id, user in pairs(rank) do
-- Previous versions didn't save that
user_id = user.user_id or ''
print(">> ", id, user.name)
if user.last_name == nil then
text = text..user.name..": "..user.msg_num.."\n"
else
--text = text..user.name.." "..user.last_name..": "..user.msg_num.."\n"
text = text..user.name..": "..user.msg_num.."\n"
end
end end
print("usuarios: "..text) if user.lastname then
text = text..user.last_name
end
return text return text
end end
local function run(msg, matches) -- Returns a table with `name` and `msgs`
if matches[1] == "stats" then local function get_msgs_user_chat(user_id, chat_id)
if msg.to.type == 'chat' or is_sudo(msg) then local user_info = {}
return get_stats_status(msg) local uhash = 'user:'..user_id
else local user = redis:hgetall(uhash)
return 'Stats funktioniert nur in Chats' local um_hash = 'msgs:'..user_id..':'..chat_id
user_info.msgs = tonumber(redis:get(um_hash) or 0)
user_info.name = user_print_name(user)..' ('..user_id..')'
return user_info
end
local function get_msg_num_stats(msg)
if msg.to.type == 'chat' then
local chat_id = msg.to.id
-- Users on chat
local hash = 'chat:'..chat_id..':users'
local users = redis:smembers(hash)
local users_info = {}
-- Get user info
for i = 1, #users do
local user_id = users[i]
local user_info = get_msgs_user_chat(user_id, chat_id)
table.insert(users_info, user_info)
end end
else
update_user_stats(msg) -- Sort users by msgs number
table.sort(users_info, function(a, b)
if a.msgs and b.msgs then
return a.msgs > b.msgs
end
end)
local text = ''
for k,user in pairs(users_info) do
text = text..user.name..' => '..user.msgs..'\n'
end
return text
end end
end end
_stats = read_file_stats() -- Save stats, ban user
local function pre_process(msg)
-- Save user on Redis
if msg.from.type == 'user' then
local hash = 'user:'..msg.from.id
if msg.from.print_name then
redis:hset(hash, 'print_name', msg.from.print_name)
end
if msg.from.first_name then
redis:hset(hash, 'first_name', msg.from.first_name)
end
if msg.from.last_name then
redis:hset(hash, 'last_name', msg.from.last_name)
end
end
-- Save stats on Redis
if msg.to.type == 'chat' then
-- User is on chat
local hash = 'chat:'..msg.to.id..':users'
redis:sadd(hash, msg.from.id)
end
-- Total user msgs
local hash = 'msgs:'..msg.from.id..':'..msg.to.id
redis:incr(hash)
-- Check flood
if msg.from.type == 'user' then
local hash = 'user:'..msg.from.id..':msgs'
local msgs = tonumber(redis:get(hash) or 0)
if msgs > NUM_MSG_MAX then
print('User '..msg.from.id..'is flooding '..msgs)
msg = nil
end
redis:setex(hash, TIME_CHECK, msgs+1)
end
return msg
end
local function get_bot_stats()
local redis_scan = [[
local cursor = '0'
local count = 0
repeat
local r = redis.call("SCAN", cursor, "MATCH", KEYS[1])
cursor = r[1]
count = count + #r[2]
until cursor == '0'
return count]]
-- Users
local hash = 'msgs:*:'..our_id
local r = redis:eval(redis_scan, 1, hash)
local text = 'Users: '..r
hash = 'chat:*:users'
r = redis:eval(redis_scan, 1, hash)
text = text..'\nChats: '..r
return text
end
local function run(msg, matches)
if matches[1]:lower() == "stats" then
if msg.to.type == 'chat' then
return get_msg_num_stats(msg)
elseif is_sudo(msg) then
return get_bot_stats()
else
return 'Stats works only on chats'
end
end
end
return { return {
description = "Zeigt wieviel ihr spamt", description = "Zeigt wieviel ihr spamt",
usage = {"/stats"}, usage = {"/stats"},
patterns = {"^/(stats)",}, patterns = {"^/([Ss]tats)$"},
run = run, run = run,
cron = save_stats pre_process = pre_process
} }
end end

View File

@ -1,10 +1,3 @@
function run_bash(str)
local cmd = io.popen(str)
local result = cmd:read('*all')
cmd:close()
return result
end
function run(msg, matches) function run(msg, matches)
URL = matches[1] URL = matches[1]
local receiver = get_receiver(msg) local receiver = get_receiver(msg)