From bd5ae0d64287b2d61cc3247d4d61f1d416b9f3ed Mon Sep 17 00:00:00 2001 From: Akamaru Date: Thu, 28 May 2015 16:47:30 +0200 Subject: [PATCH] big update too much changed ._. --- bot/bot.lua | 63 ++++++++--- bot/utils.lua | 35 +++--- etc/telegram.conf | 2 +- launch.sh | 44 ++++++-- libs/redis.lua | 47 ++++++++ plugins/9gag.lua | 1 - plugins/boobs.lua | 2 +- plugins/channels.lua | 2 +- plugins/cowsay.lua | 14 +++ plugins/danbooru2.lua | 51 +++++---- plugins/echo.lua | 9 +- plugins/get.lua | 91 +++++---------- plugins/giphy.lua | 23 +--- plugins/google.lua | 8 +- plugins/invite.lua | 50 +++++---- plugins/media_download.lua | 2 +- plugins/plugins.lua | 4 +- plugins/sakurasou.lua | 2 +- plugins/sh.lua | 7 -- plugins/stats.lua | 224 ++++++++++++++++++++++--------------- plugins/youtube_dl.lua | 7 -- 21 files changed, 409 insertions(+), 279 deletions(-) create mode 100644 libs/redis.lua create mode 100644 plugins/cowsay.lua diff --git a/bot/bot.lua b/bot/bot.lua index 7bf700a..fa79f11 100644 --- a/bot/bot.lua +++ b/bot/bot.lua @@ -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") VERSION = '2.5-reloaded' @@ -12,10 +16,13 @@ function on_msg_receive (msg) local receiver = get_receiver(msg) -- vardump(msg) + msg = pre_process_service_msg(msg) if msg_valid(msg) then msg = pre_process_msg(msg) - match_plugins(msg) - --mark_read(receiver, ok_cb, false) + if msg then + match_plugins(msg) + --mark_read(receiver, ok_cb, false) + end end end @@ -25,7 +32,7 @@ end function on_binlog_replay_end() started = true 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() cred_data = load_cred() @@ -36,7 +43,7 @@ function on_binlog_replay_end() end function msg_valid(msg) - -- Dont process outgoing messages + -- Don't process outgoing messages if msg.out then print('\27[36mNicht gültig: Nachricht von mir\27[39m') return false @@ -53,11 +60,6 @@ function msg_valid(msg) return false end - if msg.service then - print('\27[36mNicht gültig: Service\27[39m') - return false - end - if not msg.to.id then print('\27[36mNicht gültig: To id not provided\27[39m') return false @@ -68,13 +70,48 @@ function msg_valid(msg) return false 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 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 function pre_process_msg(msg) for name,plugin in pairs(plugins) do - if plugin.pre_process then + if plugin.pre_process and msg then msg = plugin.pre_process(msg) end end @@ -110,7 +147,7 @@ end function match_plugin(plugin, plugin_name, 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 local matches = match_pattern(pattern, msg.text) if matches then @@ -154,7 +191,7 @@ function save_config( ) end -- Returns the config from config.lua file. --- If file doesnt exists, create it. +-- If file doesn't exist, create it. function load_config( ) local f = io.open('./data/config.lua', "r") -- If config.lua doesnt exists @@ -186,7 +223,7 @@ end -- Create a basic config.json file and saves it. 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 = { enabled_plugins = { "help", diff --git a/bot/utils.lua b/bot/utils.lua index 16eec86..7e24a73 100644 --- a/bot/utils.lua +++ b/bot/utils.lua @@ -5,6 +5,7 @@ URL = require "socket.url" json = (loadfile "./libs/JSON.lua")() serpent = (loadfile "./libs/serpent.lua")() mimetype = (loadfile "./libs/mimetype.lua")() +redis = (loadfile "./libs/redis.lua")() http.TIMEOUT = 10 @@ -55,9 +56,9 @@ function string:trim() end function get_http_file_name(url, headers) - -- Eg: fooo.var + -- Eg: foo.var 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]+$") -- Random name, hope content-type works 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) - local file_path = "/home/pi/Mikubot/tmp/"..file_name + local file_path = "tmp/"..file_name print("Gespeichert in: "..file_path) file = io.open(file_path, "w+") @@ -138,7 +139,7 @@ function run_command(str) return result end --- User has priviledges +-- User has privileges function is_sudo(msg) local var = false -- Check users id in config @@ -210,12 +211,12 @@ function serialize_to_file(data, file, uglify) file:close() end --- Retruns true if the string is empty +-- Returns true if the string is empty function string:isempty() return self == nil or self == '' end --- Retruns true if the string is blank +-- Returns true if the string is blank function string:isblank() self = self:trim() return self:isempty() @@ -276,7 +277,7 @@ function send_photo_from_url_callback(cb_extra, success, result) end end --- Send multimple images asynchronous. +-- Send multiple images asynchronous. -- param urls must be a table. function send_photos_from_url(receiver, urls) local cb_extra = { @@ -288,7 +289,7 @@ function send_photos_from_url(receiver, urls) end -- 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) -- cb_extra is a table containing receiver, urls and remove_path local receiver = cb_extra.receiver @@ -330,7 +331,7 @@ function rmtmp_cb(cb_extra, success, result) os.remove(file_path) print(file_path.." gelöscht!") end - -- Finaly call the callback + -- Finally call the callback cb_function(cb_extra, success, result) end @@ -394,7 +395,7 @@ function user_allowed(plugin, msg) return true 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) local cb_extra = { destination = destination, @@ -450,16 +451,24 @@ function sleep(n) end -- Function to read data from files -function load_from_file(file) +function load_from_file(file, default_data) local f = io.open(file, "r+") -- If file doesn't exists if f == nil then -- Create a new empty table - serialize_to_file({}, file) + default_data = default_data or {} + serialize_to_file(default_data, file) print ('Erstelle Datei', file) else print ('Daten geladen von', file) f:close() end return loadfile (file)() - end \ No newline at end of file + end + + function run_bash(str) + local cmd = io.popen(str) + local result = cmd:read('*all') + cmd:close() + return result +end \ No newline at end of file diff --git a/etc/telegram.conf b/etc/telegram.conf index bdb4279..4619945 100644 --- a/etc/telegram.conf +++ b/etc/telegram.conf @@ -7,4 +7,4 @@ start on runlevel [2345] stop on shutdown setuid yourusername -exec /bin/sh telegrambotpath/launch.sh +exec /bin/sh telegrambotpath/launch.sh \ No newline at end of file diff --git a/launch.sh b/launch.sh index cc71e51..d722c6f 100755 --- a/launch.sh +++ b/launch.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash THIS_DIR=$(cd $(dirname $0); pwd) +RAM=`grep MemTotal /proc/meminfo | awk '{print $2}'` cd $THIS_DIR update() { @@ -14,20 +15,20 @@ install_luarocks() { git clone https://github.com/keplerproject/luarocks.git cd luarocks git checkout tags/v2.2.1 # Current stable - + PREFIX="$THIS_DIR/.luarocks" - + ./configure --prefix=$PREFIX --sysconfdir=$PREFIX/luarocks --force-config - + RET=$?; if [ $RET -ne 0 ]; - then echo "Error. Exiting."; exit $RET; + then echo "Error. Exiting."; exit $RET; fi make build && make install RET=$?; if [ $RET -ne 0 ]; then echo "Error. Exiting.";exit $RET; fi - + cd .. rm -rf luarocks } @@ -42,12 +43,37 @@ install_rocks() { RET=$?; if [ $RET -ne 0 ]; then echo "Error. Exiting."; exit $RET; 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() { git pull 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 ]; then echo "Error. Exiting."; exit $RET; fi @@ -73,7 +99,5 @@ else exit 1 fi - LUA_PATH=";;.luarocks/share/lua/5.2/?.lua;.luarocks/share/lua/5.2/?/init.lua" \ - LUA_CPATH=";;.luarocks/lib/lua/5.2/?.so" \ - ./tg/bin/telegram-cli -k ./tg/tg-server.pub -s ./bot/bot.lua -l 1 -fi + ./tg/bin/telegram-cli -k ./tg/tg-server.pub -s ./bot/bot.lua -l 1 -E +fi \ No newline at end of file diff --git a/libs/redis.lua b/libs/redis.lua new file mode 100644 index 0000000..c09142b --- /dev/null +++ b/libs/redis.lua @@ -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 \ No newline at end of file diff --git a/plugins/9gag.lua b/plugins/9gag.lua index 3427604..b354fa0 100644 --- a/plugins/9gag.lua +++ b/plugins/9gag.lua @@ -24,7 +24,6 @@ end local function run(msg, matches) local receiver = get_receiver(msg) local url, title = get_9GAG() - local file_path = download_to_file(url) send_photo_from_url(receiver, url, send_title, {receiver, title}) return false end diff --git a/plugins/boobs.lua b/plugins/boobs.lua index e92101f..7092822 100644 --- a/plugins/boobs.lua +++ b/plugins/boobs.lua @@ -11,7 +11,7 @@ local function getRandomButts(attempt) local data = json:decode(res)[1] -- 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!') return getRandomButts(attempt) end diff --git a/plugins/channels.lua b/plugins/channels.lua index a22603c..a4ce5fd 100644 --- a/plugins/channels.lua +++ b/plugins/channels.lua @@ -40,7 +40,7 @@ end local function pre_process(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 msg.text == "/channel enable" then enable_channel(receiver) diff --git a/plugins/cowsay.lua b/plugins/cowsay.lua new file mode 100644 index 0000000..904efca --- /dev/null +++ b/plugins/cowsay.lua @@ -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] \ No newline at end of file diff --git a/plugins/danbooru2.lua b/plugins/danbooru2.lua index 51af768..dac3adc 100644 --- a/plugins/danbooru2.lua +++ b/plugins/danbooru2.lua @@ -7,19 +7,15 @@ local scale_day = "?scale=day" local scale_week = "?scale=week" local scale_month = "?scale=month" -function get_post(url) +local function get_post(url) local b, c, h = http.request(url) + if c ~= 200 then return nil end local posts = json:decode(b) - -- bad random - bad magic... - math.randomseed( os.time() ) - math.random(#posts) - math.random(#posts) - return posts[math.random(#posts)] end -function run(msg, matches) +local function run(msg, matches) local url = URL @@ -28,39 +24,48 @@ function run(msg, matches) else url = url .. URL_POP - if matches[1] == "/dand" then + if matches[1] == "d" then url = url .. scale_day - elseif matches[1] == "/danw" then + elseif matches[1] == "w" then url = url .. scale_week - elseif matches[1] == "/danm" then + elseif matches[1] == "m" then url = url .. scale_month end end local post = get_post(url) - local receiver = get_receiver(msg) - local img = URL .. post.large_file_url - send_photo_from_url(receiver, img) + if post then + vardump(post) + local img = URL .. post.large_file_url + send_photo_from_url(get_receiver(msg), img) - local txt = 'Artist: ' .. post.tag_string_artist .. '\n' - txt = txt .. 'Character: ' .. post.tag_string_character .. '\n' - --txt = txt .. '[' .. math.ceil(post.file_size/1000) .. 'kb] ' .. URL .. post.file_url - return txt + local txt = '' + if post.tag_string_artist ~= '' then + txt = 'Artist: ' .. post.tag_string_artist .. '\n' + 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 return { description = "Gets a random fresh or popular image from Danbooru", usage = { "/dan - gets a random fresh image from Danbooru 🔞", - "/dand - random daily popular image 🔞", - "/danw - random weekly popular image 🔞", - "/danm - random monthly popular image 🔞"}, + "/dan d - random daily popular image 🔞", + "/dan w - random weekly popular image 🔞", + "/dan m - random monthly popular image 🔞"}, patterns = { "^/dan$", - "^/dand$", - "^/danw$", - "^/danm$"}, + "^/dan ?(d)$", + "^/dan ?(w)$", + "^/dan ?(m)$"}, run = run } diff --git a/plugins/echo.lua b/plugins/echo.lua index ea1e347..323cd5b 100644 --- a/plugins/echo.lua +++ b/plugins/echo.lua @@ -1,5 +1,12 @@ 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 return { diff --git a/plugins/get.lua b/plugins/get.lua index db306cc..cba79a2 100644 --- a/plugins/get.lua +++ b/plugins/get.lua @@ -1,78 +1,49 @@ -local _file_values = './data/values.lua' - -_values = load_from_file(_file_values) - -local function fetch_value(chat, value_name) - -- Chat non exists - if _values[chat] == nil then - return nil +local function get_variables_hash(msg) + if msg.to.type == 'chat' then + return 'chat:'..msg.to.id..':variables' end - - if value_name == nil then - return nil - end - - local value = _values[chat][value_name] - return value -end - -local function get_value(chat, value_name) - - -- If chat values is empty - if (_values[chat] == nil) then - return "Hier sind keine Daten" + if msg.to.type == 'user' then + return 'user:'..msg.from.id..':variables' end +end - -- 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" +local function list_variables(msg) + local hash = get_variables_hash(msg) + + if hash then + local names = redis:hkeys(hash) + local text = '' + for i=1, #names do + text = text..names[i]..'\n' end return text - end - local value = _values[chat][value_name] - if ( value == nil) then - return 'Konnte "'..value_name..' nicht finden' end - return value_name.." = "..value +end + +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 local function run(msg, matches) - local chat_id = tostring(msg.to.id) - if matches[1] == "/get" then - return get_value(chat_id, nil) + if matches[2] then + return get_value(msg, matches[2]) + else + return list_variables(msg) 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 return { description = "Bekommt Variable, die mit /set gesetzt wurde", usage = {"/get (Variable)"}, - patterns = {"^/get (%a+)$","^/get$"}, - patterns = {"^/get (%a+)$","^/get$"}, + patterns = {"^/get (%a+)$","^/get$"}, run = run, pre_process = lex } diff --git a/plugins/giphy.lua b/plugins/giphy.lua index c780d4c..c0ed7a2 100644 --- a/plugins/giphy.lua +++ b/plugins/giphy.lua @@ -38,34 +38,23 @@ local function search(text) return get_image(response) 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 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 gif_url = get_random_top() else gif_url = search(matches[1]) end - if not gif_url then - return "Kein GIF gefunden!" + if not gif_url then + return 'Keine GIF gefunden!' end local receiver = get_receiver(msg) - print("GIF URL"..gif_url) - local text = 'Einen Moment, GIF wird hochgeladen.' - local cb_extra = { - gif_url = gif_url, - receiver = receiver - } - send_msg(receiver, text, send_gif, cb_extra) + print("GIF URL: "..gif_url) + send_document_from_url(receiver, gif_url) end return { diff --git a/plugins/google.lua b/plugins/google.lua index 89f103c..70c1092 100644 --- a/plugins/google.lua +++ b/plugins/google.lua @@ -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 parameters = "q=".. (URL.escape(query) or "") @@ -7,7 +7,7 @@ function googlethat(query) if code ~=200 then return nil end local data = json:decode(res) - local results={} + local results = {} for key,result in ipairs(data.responseData.results) do table.insert(results, { result.titleNoFormatting, @@ -17,7 +17,7 @@ function googlethat(query) return results end -function stringlinks(results) +local function stringlinks(results) local stringresults="" for key,val in ipairs(results) do stringresults=stringresults..val[1].." - "..val[2].."\n" @@ -25,7 +25,7 @@ function stringlinks(results) return stringresults end -function run(msg, matches) +local function run(msg, matches) local results = googlethat(matches[1]) return stringlinks(results) end diff --git a/plugins/invite.lua b/plugins/invite.lua index c3e29e6..1057d3c 100644 --- a/plugins/invite.lua +++ b/plugins/invite.lua @@ -1,32 +1,36 @@ -- 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 _) do +local function callback(extra, success, result) + vardump(success) + vardump(result) +end + local function run(msg, matches) - -- User submitted a user name - if matches[1] == "name" then - user = matches[2] - user = string.gsub(user," ","_") - end - -- User submitted an id - if matches[1] == "id" then - user = matches[2] - user = 'user#id'..user - end - -- The message must come from a chat group - if msg.to.type == 'chat' then - chat = 'chat#id'..msg.to.id - else - return 'Dies ist keine Gruppe!!' - end - print ("Füge "..user.." zu "..chat.." hinzu") - status = chat_add_user (chat, user, ok_cb, false) - if not status then - return "Ein Fehler ist aufgetreten" - end - return "User "..user.." zu "..chat.." hinzugefügt!" + local user = matches[2] + + -- User submitted a user name + if matches[1] == "name" then + user = string.gsub(user," ","_") + end + + -- User submitted an id + if matches[1] == "id" then + user = 'user#id'..user + end + + -- The message must come from a chat group + if msg.to.type == 'chat' then + local chat = 'chat#id'..msg.to.id + chat_add_user(chat, user, callback, false) + return "User "..user.." zu "..chat.." hinzugefügt!" + else + return 'Dies ist keine Gruppe!!' + end + end return { diff --git a/plugins/media_download.lua b/plugins/media_download.lua index 2f2080c..1425480 100644 --- a/plugins/media_download.lua +++ b/plugins/media_download.lua @@ -9,7 +9,7 @@ end local function run(msg, matches) if msg.media then - if msg.media.type == 'document' then + if msg.media.type == 'document' then load_document(msg.id, callback, msg.id) end if msg.media.type == 'photo' then diff --git a/plugins/plugins.lua b/plugins/plugins.lua index 9b6e9fa..ec8318a 100644 --- a/plugins/plugins.lua +++ b/plugins/plugins.lua @@ -1,6 +1,6 @@ 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 ) for k,v in pairs(_config.enabled_plugins) do if name == v then @@ -126,7 +126,7 @@ local function run(msg, matches) return list_plugins() end - -- Reenable a plugin for this chat + -- Re-enable a plugin for this chat if matches[1] == 'enable' and matches[3] == 'chat' then local receiver = get_receiver(msg) local plugin = matches[2] diff --git a/plugins/sakurasou.lua b/plugins/sakurasou.lua index 4d4ad56..1efe7a7 100644 --- a/plugins/sakurasou.lua +++ b/plugins/sakurasou.lua @@ -32,7 +32,7 @@ end return { 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"}, - 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 } --by Akamaru [https://ponywave.de] \ No newline at end of file diff --git a/plugins/sh.lua b/plugins/sh.lua index 68a5fc9..da6933d 100644 --- a/plugins/sh.lua +++ b/plugins/sh.lua @@ -6,13 +6,6 @@ function run_sh(msg) return text end -function run_bash(str) - local cmd = io.popen(str) - local result = cmd:read('*all') - cmd:close() - return result -end - function run(msg, matches) local receiver = get_receiver(msg) if string.starts(msg.text, '/sh') then diff --git a/plugins/stats.lua b/plugins/stats.lua index 20cb8a7..a7129b7 100644 --- a/plugins/stats.lua +++ b/plugins/stats.lua @@ -1,115 +1,153 @@ -- 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 -local socket = require('socket') -local _file_stats = './data/stats.lua' -local _stats +local NUM_MSG_MAX = 500 +local TIME_CHECK = 4 -- seconds -function update_user_stats(msg) - -- Save user to stats table - local from_id = tostring(msg.from.id) - 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) +local function user_print_name(user) + if user.print_name then + return user.print_name end - table.sort(rank, function(a, b) - if a.msg_num and b.msg_num then - return a.msg_num > b.msg_num - 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 + local text = '' + if user.first_name then + text = user.last_name..' ' end - print("usuarios: "..text) + if user.lastname then + text = text..user.last_name + end + return text end -local function run(msg, matches) - if matches[1] == "stats" then - if msg.to.type == 'chat' or is_sudo(msg) then - return get_stats_status(msg) - else - return 'Stats funktioniert nur in Chats' +-- Returns a table with `name` and `msgs` +local function get_msgs_user_chat(user_id, chat_id) + local user_info = {} + local uhash = 'user:'..user_id + local user = redis:hgetall(uhash) + 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 - 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 -_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 { description = "Zeigt wieviel ihr spamt", usage = {"/stats"}, - patterns = {"^/(stats)",}, + patterns = {"^/([Ss]tats)$"}, run = run, - cron = save_stats + pre_process = pre_process } -end +end \ No newline at end of file diff --git a/plugins/youtube_dl.lua b/plugins/youtube_dl.lua index f027f41..aead337 100644 --- a/plugins/youtube_dl.lua +++ b/plugins/youtube_dl.lua @@ -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) URL = matches[1] local receiver = get_receiver(msg)