Committe aktuellen Status.
NEU: - Twitter-Plugin (ohne Markdown bisher) - Get- Set-Plugins - 9GAG - Adfly - Redis-Integration - Google Search - Google Images (modifiziert, mit Blacklist, bisher ohne Caching) - Einige Plugins lokalisiert Das ist momentan noch alles WIP, das meiste ist einfach bloß copy&paste vom proprietären Brawlbot v1.
This commit is contained in:
parent
31a8e220ac
commit
a4d7c40ad9
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,3 @@
|
|||||||
otouto/plugins/mokubot*
|
config.lua
|
||||||
*.db
|
*.db
|
||||||
tg
|
tg
|
||||||
|
2
README.md
Executable file → Normal file
2
README.md
Executable file → Normal file
@ -1,4 +1,4 @@
|
|||||||
# otouto
|
# Brawlbot, auf Basis von otouto
|
||||||
The plugin-wielding, multipurpose Telegram bot.
|
The plugin-wielding, multipurpose Telegram bot.
|
||||||
|
|
||||||
[Public Bot](http://telegram.me/mokubot) | [Official Channel](http://telegram.me/otouto) | [Development Group](http://telegram.me/BotDevelopment)
|
[Public Bot](http://telegram.me/mokubot) | [Official Channel](http://telegram.me/otouto) | [Development Group](http://telegram.me/BotDevelopment)
|
||||||
|
56
config.lua → config.lua.example
Executable file → Normal file
56
config.lua → config.lua.example
Executable file → Normal file
@ -3,9 +3,9 @@ return {
|
|||||||
-- Your authorization token from the botfather.
|
-- Your authorization token from the botfather.
|
||||||
bot_api_key = '',
|
bot_api_key = '',
|
||||||
-- Your Telegram ID.
|
-- Your Telegram ID.
|
||||||
admin = 00000000,
|
admin = 1337,
|
||||||
-- Two-letter language code.
|
-- Two-letter language code.
|
||||||
lang = 'en',
|
lang = 'de',
|
||||||
-- The channel, group, or user to send error reports to.
|
-- The channel, group, or user to send error reports to.
|
||||||
-- If this is not set, errors will be printed to the console.
|
-- If this is not set, errors will be printed to the console.
|
||||||
log_chat = nil,
|
log_chat = nil,
|
||||||
@ -14,42 +14,22 @@ return {
|
|||||||
cli_port = 4567,
|
cli_port = 4567,
|
||||||
-- The block of text returned by /start.
|
-- The block of text returned by /start.
|
||||||
about_text = [[
|
about_text = [[
|
||||||
I am otouto, the plugin-wielding, multipurpose Telegram bot.
|
Dies ist die BETA-Version von Brawlbot v2.
|
||||||
|
|
||||||
Send /help to get started.
|
Sende /hilfe, um zu starten
|
||||||
]],
|
]],
|
||||||
-- The symbol that starts a command. Usually noted as '/' in documentation.
|
-- The symbol that starts a command. Usually noted as '/' in documentation.
|
||||||
cmd_pat = '/',
|
cmd_pat = '/',
|
||||||
|
|
||||||
-- https://datamarket.azure.com/dataset/bing/search
|
|
||||||
bing_api_key = '',
|
|
||||||
-- http://console.developers.google.com
|
|
||||||
google_api_key = '',
|
|
||||||
-- https://cse.google.com/cse
|
|
||||||
google_cse_key = '',
|
|
||||||
-- http://openweathermap.org/appid
|
|
||||||
owm_api_key = '',
|
|
||||||
-- http://last.fm/api
|
|
||||||
lastfm_api_key = '',
|
|
||||||
-- http://api.biblia.com
|
|
||||||
biblia_api_key = '',
|
|
||||||
-- http://thecatapi.com/docs.html
|
|
||||||
thecatapi_key = '',
|
|
||||||
-- http://api.nasa.gov
|
|
||||||
nasa_api_key = '',
|
|
||||||
-- http://tech.yandex.com/keys/get
|
|
||||||
yandex_key = '',
|
|
||||||
-- http://developer.simsimi.com/signUp
|
|
||||||
simsimi_key = '',
|
|
||||||
simsimi_trial = true,
|
|
||||||
|
|
||||||
errors = { -- Generic error messages used in various plugins.
|
errors = { -- Generic error messages used in various plugins.
|
||||||
connection = 'Connection error.',
|
connection = 'Verbindungsfehler.',
|
||||||
results = 'No results found.',
|
quotaexceeded = 'API-Quota aufgebraucht.',
|
||||||
argument = 'Invalid argument.',
|
results = 'Keine Ergebnisse gefunden.',
|
||||||
syntax = 'Invalid syntax.',
|
sudo = 'Du bist kein Superuser. Dieser Vorfall wird gemeldet!',
|
||||||
chatter_connection = 'I don\'t feel like talking right now.',
|
argument = 'Invalides Argument.',
|
||||||
chatter_response = 'I don\'t know what to say to that.'
|
syntax = 'Invalide Syntax.',
|
||||||
|
chatter_connection = 'Ich möchte gerade nicht reden',
|
||||||
|
chatter_response = 'Ich weiß nicht, was ich darauf antworten soll.'
|
||||||
},
|
},
|
||||||
|
|
||||||
plugins = { -- To enable a plugin, add its name to the list.
|
plugins = { -- To enable a plugin, add its name to the list.
|
||||||
@ -60,6 +40,9 @@ Send /help to get started.
|
|||||||
'whoami',
|
'whoami',
|
||||||
'nick',
|
'nick',
|
||||||
'echo',
|
'echo',
|
||||||
|
'imgblacklist',
|
||||||
|
'gImages',
|
||||||
|
'gSearch',
|
||||||
'gMaps',
|
'gMaps',
|
||||||
'wikipedia',
|
'wikipedia',
|
||||||
'hackernews',
|
'hackernews',
|
||||||
@ -67,7 +50,6 @@ Send /help to get started.
|
|||||||
'calc',
|
'calc',
|
||||||
'urbandictionary',
|
'urbandictionary',
|
||||||
'time',
|
'time',
|
||||||
'eightball',
|
|
||||||
'dice',
|
'dice',
|
||||||
'reddit',
|
'reddit',
|
||||||
'xkcd',
|
'xkcd',
|
||||||
@ -75,8 +57,14 @@ Send /help to get started.
|
|||||||
'commit',
|
'commit',
|
||||||
'pun',
|
'pun',
|
||||||
'currency',
|
'currency',
|
||||||
'cats',
|
|
||||||
'shout',
|
'shout',
|
||||||
|
'set',
|
||||||
|
'get',
|
||||||
|
'patterns',
|
||||||
|
'9gag',
|
||||||
|
'shell',
|
||||||
|
'adfly',
|
||||||
|
'twitter',
|
||||||
-- Put new plugins above this line.
|
-- Put new plugins above this line.
|
||||||
'help',
|
'help',
|
||||||
'greetings'
|
'greetings'
|
0
otouto/bindings.lua
Executable file → Normal file
0
otouto/bindings.lua
Executable file → Normal file
56
otouto/bot.lua
Executable file → Normal file
56
otouto/bot.lua
Executable file → Normal file
@ -3,13 +3,16 @@ local bot = {}
|
|||||||
-- Requires are moved to init to allow for reloads.
|
-- Requires are moved to init to allow for reloads.
|
||||||
local bindings -- Load Telegram bindings.
|
local bindings -- Load Telegram bindings.
|
||||||
local utilities -- Load miscellaneous and cross-plugin functions.
|
local utilities -- Load miscellaneous and cross-plugin functions.
|
||||||
|
local redis = (loadfile "./otouto/redis.lua")()
|
||||||
|
|
||||||
bot.version = '3.9'
|
bot.version = '2'
|
||||||
|
|
||||||
function bot:init(config) -- The function run when the bot is started or reloaded.
|
function bot:init(config) -- The function run when the bot is started or reloaded.
|
||||||
|
|
||||||
bindings = require('otouto.bindings')
|
bindings = require('otouto.bindings')
|
||||||
utilities = require('otouto.utilities')
|
utilities = require('otouto.utilities')
|
||||||
|
redis = (loadfile "./otouto/redis.lua")()
|
||||||
|
cred_data = load_cred()
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
config.bot_api_key and config.bot_api_key ~= '',
|
config.bot_api_key and config.bot_api_key ~= '',
|
||||||
@ -127,4 +130,55 @@ function bot:run(config)
|
|||||||
print('Halted.')
|
print('Halted.')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function load_cred()
|
||||||
|
if redis:exists("telegram:credentials") == false then
|
||||||
|
-- If credentials hash doesnt exists
|
||||||
|
print ("Created new credentials hash: telegram:credentials")
|
||||||
|
create_cred()
|
||||||
|
end
|
||||||
|
return redis:hgetall("telegram:credentials")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- create credentials hash with redis
|
||||||
|
function create_cred()
|
||||||
|
cred = {
|
||||||
|
bitly_access_token = "",
|
||||||
|
cloudinary_apikey = "",
|
||||||
|
cloudinary_api_secret = "",
|
||||||
|
cloudinary_public_id = "",
|
||||||
|
derpibooru_apikey = "",
|
||||||
|
fb_access_token = "",
|
||||||
|
flickr_apikey = "",
|
||||||
|
ftp_site = "",
|
||||||
|
ftp_username = "",
|
||||||
|
ftp_password = "",
|
||||||
|
gender_apikey = "",
|
||||||
|
golem_apikey = "",
|
||||||
|
google_apikey = "",
|
||||||
|
google_cse_id = "",
|
||||||
|
gitlab_private_token = "",
|
||||||
|
gitlab_project_id = "",
|
||||||
|
instagram_access_token = "",
|
||||||
|
lyricsnmusic_apikey = "",
|
||||||
|
mal_username = "",
|
||||||
|
mal_pw = "",
|
||||||
|
neutrino_userid = "",
|
||||||
|
neutrino_apikey = "",
|
||||||
|
owm_apikey = "",
|
||||||
|
page2images_restkey = "",
|
||||||
|
soundcloud_client_id = "",
|
||||||
|
tw_consumer_key = "",
|
||||||
|
tw_consumer_secret = "",
|
||||||
|
tw_access_token = "",
|
||||||
|
tw_access_token_secret = "",
|
||||||
|
x_mashape_key = "",
|
||||||
|
yandex_translate_apikey = "",
|
||||||
|
yandex_rich_content_apikey = "",
|
||||||
|
yourls_site_url = "",
|
||||||
|
yourls_signature_token = ""
|
||||||
|
}
|
||||||
|
redis:hmset("telegram:credentials", cred)
|
||||||
|
print ('saved credentials into reds hash telegram:credentials')
|
||||||
|
end
|
||||||
|
|
||||||
return bot
|
return bot
|
||||||
|
100
otouto/mimetype.lua
Normal file
100
otouto/mimetype.lua
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
-- Thanks to https://github.com/catwell/lua-toolbox/blob/master/mime.types
|
||||||
|
do
|
||||||
|
|
||||||
|
local mimetype = {}
|
||||||
|
|
||||||
|
-- TODO: Add more?
|
||||||
|
local types = {
|
||||||
|
["text/html"] = "html",
|
||||||
|
["text/css"] = "css",
|
||||||
|
["text/xml"] = "xml",
|
||||||
|
["image/gif"] = "gif",
|
||||||
|
["image/jpeg"] = "jpg",
|
||||||
|
["application/x-javascript"] = "js",
|
||||||
|
["application/atom+xml"] = "atom",
|
||||||
|
["application/rss+xml"] = "rss",
|
||||||
|
["text/mathml"] = "mml",
|
||||||
|
["text/plain"] = "txt",
|
||||||
|
["text/vnd.sun.j2me.app-descriptor"] = "jad",
|
||||||
|
["text/vnd.wap.wml"] = "wml",
|
||||||
|
["text/x-component"] = "htc",
|
||||||
|
["image/png"] = "png",
|
||||||
|
["image/tiff"] = "tiff",
|
||||||
|
["image/vnd.wap.wbmp"] = "wbmp",
|
||||||
|
["image/x-icon"] = "ico",
|
||||||
|
["image/x-jng"] = "jng",
|
||||||
|
["image/x-ms-bmp"] = "bmp",
|
||||||
|
["image/svg+xml"] = "svg",
|
||||||
|
["application/java-archive"] = "jar",
|
||||||
|
["application/mac-binhex40"] = "hqx",
|
||||||
|
["application/msword"] = "doc",
|
||||||
|
["application/pdf"] = "pdf",
|
||||||
|
["application/postscript"] = "ps",
|
||||||
|
["application/rtf"] = "rtf",
|
||||||
|
["application/vnd.android.package-archive"] = "apk",
|
||||||
|
["application/vnd.ms-excel"] = "xls",
|
||||||
|
["application/vnd.ms-powerpoint"] = "ppt",
|
||||||
|
["application/vnd.wap.wmlc"] = "wmlc",
|
||||||
|
["application/vnd.google-earth.kml+xml"] = "kml",
|
||||||
|
["application/vnd.google-earth.kmz"] = "kmz",
|
||||||
|
["application/x-7z-compressed"] = "7z",
|
||||||
|
["application/x-cocoa"] = "cco",
|
||||||
|
["application/x-java-archive-diff"] = "jardiff",
|
||||||
|
["application/x-java-jnlp-file"] = "jnlp",
|
||||||
|
["application/x-makeself"] = "run",
|
||||||
|
["application/x-perl"] = "pl",
|
||||||
|
["application/x-pilot"] = "prc",
|
||||||
|
["application/x-rar-compressed"] = "rar",
|
||||||
|
["application/x-redhat-package-manager"] = "rpm",
|
||||||
|
["application/x-sea"] = "sea",
|
||||||
|
["application/x-shockwave-flash"] = "swf",
|
||||||
|
["application/x-stuffit"] = "sit",
|
||||||
|
["application/x-tcl"] = "tcl",
|
||||||
|
["application/x-x509-ca-cert"] = "crt",
|
||||||
|
["application/x-xpinstall"] = "xpi",
|
||||||
|
["application/xhtml+xml"] = "xhtml",
|
||||||
|
["application/zip"] = "zip",
|
||||||
|
["application/octet-stream"] = "bin",
|
||||||
|
["audio/midi"] = "mid",
|
||||||
|
["audio/mpeg"] = "mp3",
|
||||||
|
["audio/ogg"] = "ogg",
|
||||||
|
["audio/x-m4a"] = "m4a",
|
||||||
|
["audio/x-realaudio"] = "ra",
|
||||||
|
["video/3gpp"] = "3gpp",
|
||||||
|
["video/mp4"] = "mp4",
|
||||||
|
["video/mpeg"] = "mpeg",
|
||||||
|
["video/quicktime"] = "mov",
|
||||||
|
["video/x-flv"] = "flv",
|
||||||
|
["video/x-m4v"] = "m4v",
|
||||||
|
["video/x-mng"] = "mng",
|
||||||
|
["video/x-ms-asf"] = "asf",
|
||||||
|
["video/x-ms-wmv"] = "wmv",
|
||||||
|
["video/x-msvideo"] = "avi"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Returns the common file extension from a content-type
|
||||||
|
function mimetype.get_mime_extension(content_type)
|
||||||
|
return types[content_type]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns the mimetype and subtype
|
||||||
|
function mimetype.get_content_type(extension)
|
||||||
|
for k,v in pairs(types) do
|
||||||
|
if v == extension then
|
||||||
|
return k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns the mimetype without the subtype
|
||||||
|
function mimetype.get_content_type_no_sub(extension)
|
||||||
|
for k,v in pairs(types) do
|
||||||
|
if v == extension then
|
||||||
|
-- Before /
|
||||||
|
return k:match('([%w-]+)/')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return mimetype
|
||||||
|
end
|
41
otouto/plugins/9gag.lua
Normal file
41
otouto/plugins/9gag.lua
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
local ninegag = {}
|
||||||
|
|
||||||
|
local HTTP = require('socket.http')
|
||||||
|
local URL = require('socket.url')
|
||||||
|
local JSON = require('dkjson')
|
||||||
|
local utilities = require('otouto.utilities')
|
||||||
|
local bindings = require('otouto.bindings')
|
||||||
|
|
||||||
|
ninegag.command = '9gag'
|
||||||
|
|
||||||
|
function ninegag:init(config)
|
||||||
|
ninegag.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('9gag', true):t('9fag', true).table
|
||||||
|
ninegag.doc = [[*
|
||||||
|
]]..config.cmd_pat..[[9gag*: Gibt ein zufälliges Bild von den momentan populärsten 9GAG-Posts aus]]
|
||||||
|
end
|
||||||
|
|
||||||
|
function ninegag:get_9GAG()
|
||||||
|
local url = "http://api-9gag.herokuapp.com/"
|
||||||
|
local b,c = HTTP.request(url)
|
||||||
|
if c ~= 200 then return nil end
|
||||||
|
local gag = JSON.decode(b)
|
||||||
|
-- random max json table size
|
||||||
|
local i = math.random(#gag) local link_image = gag[i].src
|
||||||
|
local title = gag[i].title
|
||||||
|
return link_image, title, post_url
|
||||||
|
end
|
||||||
|
|
||||||
|
function ninegag:action(msg, config)
|
||||||
|
local url, title = ninegag:get_9GAG()
|
||||||
|
if not url then
|
||||||
|
utilities.send_reply(self, msg, config.errors.connection)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local file = download_to_file(url)
|
||||||
|
bindings.sendPhoto(self, {chat_id = msg.chat.id, caption = title}, {photo = file} )
|
||||||
|
os.remove(file)
|
||||||
|
print("Deleted: "..file)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ninegag
|
4
otouto/plugins/about.lua
Executable file → Normal file
4
otouto/plugins/about.lua
Executable file → Normal file
@ -4,7 +4,7 @@ local bot = require('otouto.bot')
|
|||||||
local utilities = require('otouto.utilities')
|
local utilities = require('otouto.utilities')
|
||||||
|
|
||||||
about.command = 'about'
|
about.command = 'about'
|
||||||
about.doc = '`Returns information about the bot.`'
|
about.doc = '`Sendet Informationen über den Bot.`'
|
||||||
|
|
||||||
about.triggers = {
|
about.triggers = {
|
||||||
''
|
''
|
||||||
@ -16,7 +16,7 @@ function about:action(msg, config)
|
|||||||
-- other plugins.
|
-- other plugins.
|
||||||
if msg.forward_from then return end
|
if msg.forward_from then return end
|
||||||
|
|
||||||
local output = config.about_text .. '\nBased on otouto v'..bot.version..' by topkecleon.'
|
local output = config.about_text .. '\nBrawlbot v2, basierend auf Otouto v'..bot.version..' von topkecleon.'
|
||||||
|
|
||||||
if (msg.new_chat_participant and msg.new_chat_participant.id == self.info.id)
|
if (msg.new_chat_participant and msg.new_chat_participant.id == self.info.id)
|
||||||
or msg.text_lower:match('^'..config.cmd_pat..'about')
|
or msg.text_lower:match('^'..config.cmd_pat..'about')
|
||||||
|
49
otouto/plugins/adfly.lua
Normal file
49
otouto/plugins/adfly.lua
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
local adfly = {}
|
||||||
|
|
||||||
|
local utilities = require('otouto.utilities')
|
||||||
|
local HTTPS = require('ssl.https')
|
||||||
|
local redis = (loadfile "./otouto/redis.lua")()
|
||||||
|
|
||||||
|
function adfly:init(config)
|
||||||
|
adfly.triggers = {
|
||||||
|
'adf.ly/([A-Za-z0-9-_-]+)'
|
||||||
|
}
|
||||||
|
adfly.doc = [[*adf.ly-Link*: Postet vollen Link]]
|
||||||
|
end
|
||||||
|
|
||||||
|
function adfly:expand_adfly_link(adfly_code)
|
||||||
|
local BASE_URL = 'https://andibi.tk/dl/adfly.php'
|
||||||
|
local url = BASE_URL..'/?url=http://adf.ly/'..adfly_code
|
||||||
|
local res,code = HTTPS.request(url)
|
||||||
|
if code ~= 200 then return nil end
|
||||||
|
if res == 'Fehler: Keine Adf.ly-URL gefunden!' then return 'NOTFOUND' end
|
||||||
|
cache_data('adfly', adfly_code, res, 31536000, 'key')
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function adfly:action(msg)
|
||||||
|
local input = msg.text
|
||||||
|
if not input:match('adf.ly/([A-Za-z0-9-_-]+)') then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local adfly_code = input:match('adf.ly/([A-Za-z0-9-_-]+)')
|
||||||
|
local hash = 'telegram:cache:adfly:'..adfly_code
|
||||||
|
if redis:exists(hash) == false then
|
||||||
|
local expanded_url = adfly:expand_adfly_link(adfly_code)
|
||||||
|
if not expanded_url then
|
||||||
|
utilities.send_reply(self, msg, config.errors.connection)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if expanded_url == 'NOTFOUND' then
|
||||||
|
utilities.send_reply(self, msg, 'Fehler: Keine Adf.ly-URL gefunden!')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
utilities.send_reply(self, msg, expanded_url)
|
||||||
|
else
|
||||||
|
local data = redis:get(hash)
|
||||||
|
utilities.send_reply(self, msg, data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return adfly
|
0
otouto/plugins/apod.lua
Executable file → Normal file
0
otouto/plugins/apod.lua
Executable file → Normal file
0
otouto/plugins/bandersnatch.lua
Executable file → Normal file
0
otouto/plugins/bandersnatch.lua
Executable file → Normal file
0
otouto/plugins/bible.lua
Executable file → Normal file
0
otouto/plugins/bible.lua
Executable file → Normal file
0
otouto/plugins/blacklist.lua
Executable file → Normal file
0
otouto/plugins/blacklist.lua
Executable file → Normal file
0
otouto/plugins/calc.lua
Executable file → Normal file
0
otouto/plugins/calc.lua
Executable file → Normal file
0
otouto/plugins/cats.lua
Executable file → Normal file
0
otouto/plugins/cats.lua
Executable file → Normal file
0
otouto/plugins/chatter.lua
Executable file → Normal file
0
otouto/plugins/chatter.lua
Executable file → Normal file
0
otouto/plugins/commit.lua
Executable file → Normal file
0
otouto/plugins/commit.lua
Executable file → Normal file
0
otouto/plugins/currency.lua
Executable file → Normal file
0
otouto/plugins/currency.lua
Executable file → Normal file
0
otouto/plugins/dice.lua
Executable file → Normal file
0
otouto/plugins/dice.lua
Executable file → Normal file
0
otouto/plugins/echo.lua
Executable file → Normal file
0
otouto/plugins/echo.lua
Executable file → Normal file
0
otouto/plugins/eightball.lua
Executable file → Normal file
0
otouto/plugins/eightball.lua
Executable file → Normal file
0
otouto/plugins/fortune.lua
Executable file → Normal file
0
otouto/plugins/fortune.lua
Executable file → Normal file
46
otouto/plugins/gImages.lua
Executable file → Normal file
46
otouto/plugins/gImages.lua
Executable file → Normal file
@ -7,30 +7,30 @@ local HTTPS = require('ssl.https')
|
|||||||
local URL = require('socket.url')
|
local URL = require('socket.url')
|
||||||
local JSON = require('dkjson')
|
local JSON = require('dkjson')
|
||||||
local utilities = require('otouto.utilities')
|
local utilities = require('otouto.utilities')
|
||||||
|
local bindings = require('otouto.bindings')
|
||||||
|
|
||||||
function gImages:init(config)
|
function gImages:init(config)
|
||||||
if not config.google_api_key then
|
if not cred_data.google_apikey then
|
||||||
print('Missing config value: google_api_key.')
|
print('Missing config value: google_apikey.')
|
||||||
print('gImages.lua will not be enabled.')
|
print('gImages.lua will not be enabled.')
|
||||||
return
|
return
|
||||||
elseif not config.google_cse_key then
|
elseif not cred_data.google_cse_id then
|
||||||
print('Missing config value: google_cse_key.')
|
print('Missing config value: google_cse_id.')
|
||||||
print('gImages.lua will not be enabled.')
|
print('gImages.lua will not be enabled.')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
gImages.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('image', true):t('i', true):t('insfw', true).table
|
gImages.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('img', true):t('i', true):t('insfw', true).table
|
||||||
gImages.doc = [[```
|
gImages.doc = [[```
|
||||||
]]..config.cmd_pat..[[image <query>
|
]]..config.cmd_pat..[[img <Suchbegriff>
|
||||||
Returns a randomized top result from Google Images. Safe search is enabled by default; use "]]..config.cmd_pat..[[insfw" to disable it. NSFW results will not display an image preview.
|
Sucht Bild mit Google und versendet es (SafeSearch aktiv)
|
||||||
Alias: ]]..config.cmd_pat..[[i
|
Alias: ]]..config.cmd_pat..[[i
|
||||||
```]]
|
```]]
|
||||||
end
|
end
|
||||||
|
|
||||||
gImages.command = 'image <query>'
|
gImages.command = 'img <Suchbegriff>'
|
||||||
|
|
||||||
function gImages:action(msg, config)
|
function gImages:action(msg, config)
|
||||||
|
|
||||||
local input = utilities.input(msg.text)
|
local input = utilities.input(msg.text)
|
||||||
if not input then
|
if not input then
|
||||||
if msg.reply_to_message and msg.reply_to_message.text then
|
if msg.reply_to_message and msg.reply_to_message.text then
|
||||||
@ -41,15 +41,18 @@ function gImages:action(msg, config)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local url = 'https://www.googleapis.com/customsearch/v1?&searchType=image&imgSize=xlarge&alt=json&num=8&start=1&key=' .. config.google_api_key .. '&cx=' .. config.google_cse_key
|
print ('Checking if search contains blacklisted word: '..input)
|
||||||
|
if is_blacklisted(input) then
|
||||||
if not string.match(msg.text, '^'..config.cmd_pat..'i[mage]*nsfw') then
|
utilities.send_reply(self, msg, 'Vergiss es! ._.')
|
||||||
url = url .. '&safe=high'
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
url = url .. '&q=' .. URL.escape(input)
|
local apikey = cred_data.google_apikey
|
||||||
|
local cseid = cred_data.google_cse_id
|
||||||
|
local BASE_URL = 'https://www.googleapis.com/customsearch/v1'
|
||||||
|
local url = BASE_URL..'/?searchType=image&alt=json&num=10&key='..apikey..'&cx='..cseid..'&safe=high'..'&q=' .. URL.escape(input)
|
||||||
local jstr, res = HTTPS.request(url)
|
local jstr, res = HTTPS.request(url)
|
||||||
|
|
||||||
if res ~= 200 then
|
if res ~= 200 then
|
||||||
utilities.send_reply(self, msg, config.errors.connection)
|
utilities.send_reply(self, msg, config.errors.connection)
|
||||||
return
|
return
|
||||||
@ -63,16 +66,11 @@ function gImages:action(msg, config)
|
|||||||
|
|
||||||
local i = math.random(jdat.queries.request[1].count)
|
local i = math.random(jdat.queries.request[1].count)
|
||||||
local img_url = jdat.items[i].link
|
local img_url = jdat.items[i].link
|
||||||
local img_title = jdat.items[i].title
|
|
||||||
local output = '[' .. img_title .. '](' .. img_url .. ')'
|
|
||||||
|
|
||||||
|
|
||||||
if msg.text:match('nsfw') then
|
|
||||||
utilities.send_reply(self, '*NSFW*\n'..msg, output)
|
|
||||||
else
|
|
||||||
utilities.send_message(self, msg.chat.id, output, false, nil, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
local file = download_to_file(img_url)
|
||||||
|
bindings.sendPhoto(self, {chat_id = msg.chat.id, caption = img_url}, {photo = file} )
|
||||||
|
os.remove(file)
|
||||||
|
print("Deleted: "..file)
|
||||||
end
|
end
|
||||||
|
|
||||||
return gImages
|
return gImages
|
||||||
|
0
otouto/plugins/gMaps.lua
Executable file → Normal file
0
otouto/plugins/gMaps.lua
Executable file → Normal file
96
otouto/plugins/gSearch.lua
Executable file → Normal file
96
otouto/plugins/gSearch.lua
Executable file → Normal file
@ -10,14 +10,55 @@ gSearch.command = 'google <query>'
|
|||||||
function gSearch:init(config)
|
function gSearch:init(config)
|
||||||
gSearch.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('g', true):t('google', true):t('gnsfw', true).table
|
gSearch.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('g', true):t('google', true):t('gnsfw', true).table
|
||||||
gSearch.doc = [[```
|
gSearch.doc = [[```
|
||||||
]]..config.cmd_pat..[[google <query>
|
]]..config.cmd_pat..[[google <Suchbegriff>
|
||||||
Returns four (if group) or eight (if private message) results from Google. Safe search is enabled by default, use "]]..config.cmd_pat..[[gnsfw" to disable it.
|
Sendet Suchergebnisse von Google
|
||||||
Alias: ]]..config.cmd_pat..[[g
|
Alias: ]]..config.cmd_pat..[[g
|
||||||
```]]
|
```]]
|
||||||
end
|
end
|
||||||
|
|
||||||
function gSearch:action(msg, config)
|
function gSearch:googlethat(query, config)
|
||||||
|
local BASE_URL = 'https://www.googleapis.com/customsearch/v1'
|
||||||
|
local apikey = config.google_api_key
|
||||||
|
local cseid = config.google_cse_key
|
||||||
|
local number = 5 -- Set number of results
|
||||||
|
|
||||||
|
local api = BASE_URL.."/?key="..apikey.."&cx="..cseid.."&gl=de&num="..number.."&safe=medium&fields=searchInformation%28formattedSearchTime,formattedTotalResults%29,items%28title,link,displayLink%29&"
|
||||||
|
local parameters = "q=".. (URL.escape(query) or "")
|
||||||
|
-- Do the request
|
||||||
|
local res, code = HTTPS.request(api..parameters)
|
||||||
|
if code == 403 then
|
||||||
|
utilities.send_reply(self, msg, config.errors.quotaexceeded)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if code ~= 200 then
|
||||||
|
utilities.send_reply(self, msg, config.errors.connection)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local data = JSON.decode(res)
|
||||||
|
if data.searchInformation.formattedTotalResults == "0" then return nil end
|
||||||
|
|
||||||
|
local results={}
|
||||||
|
for key,result in ipairs(data.items) do
|
||||||
|
table.insert(results, {
|
||||||
|
result.title,
|
||||||
|
result.link,
|
||||||
|
result.displayLink
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local stats = data.searchInformation.formattedTotalResults..' Ergebnisse, gefunden in '..data.searchInformation.formattedSearchTime..' Sekunden'
|
||||||
|
return results, stats
|
||||||
|
end
|
||||||
|
|
||||||
|
function gSearch:stringlinks(results, stats)
|
||||||
|
local stringresults=""
|
||||||
|
for key,val in ipairs(results) do
|
||||||
|
stringresults=stringresults.."["..val[1].."]("..val[2]..") - `"..val[3].."`\n"
|
||||||
|
end
|
||||||
|
return stringresults..stats
|
||||||
|
end
|
||||||
|
|
||||||
|
function gSearch:action(msg, config)
|
||||||
local input = utilities.input(msg.text)
|
local input = utilities.input(msg.text)
|
||||||
if not input then
|
if not input then
|
||||||
if msg.reply_to_message and msg.reply_to_message.text then
|
if msg.reply_to_message and msg.reply_to_message.text then
|
||||||
@ -28,53 +69,8 @@ function gSearch:action(msg, config)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local url = 'https://ajax.googleapis.com/ajax/services/search/web?v=1.0'
|
local results, stats = gSearch:googlethat(input, config)
|
||||||
|
utilities.send_message(self, msg.chat.id, gSearch:stringlinks(results, stats), true, nil, true)
|
||||||
if msg.from.id == msg.chat.id then
|
|
||||||
url = url .. '&rsz=8'
|
|
||||||
else
|
|
||||||
url = url .. '&rsz=4'
|
|
||||||
end
|
|
||||||
|
|
||||||
if not string.match(msg.text, '^'..config.cmd_pat..'g[oogle]*nsfw') then
|
|
||||||
url = url .. '&safe=active'
|
|
||||||
end
|
|
||||||
|
|
||||||
url = url .. '&q=' .. URL.escape(input)
|
|
||||||
|
|
||||||
local jstr, res = HTTPS.request(url)
|
|
||||||
if res ~= 200 then
|
|
||||||
utilities.send_reply(self, msg, config.errors.connection)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local jdat = JSON.decode(jstr)
|
|
||||||
if not jdat.responseData then
|
|
||||||
utilities.send_reply(self, msg, config.errors.connection)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not jdat.responseData.results[1] then
|
|
||||||
utilities.send_reply(self, msg, config.errors.results)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local output = '*Google results for* _' .. input .. '_ *:*\n'
|
|
||||||
for i,_ in ipairs(jdat.responseData.results) do
|
|
||||||
local title = jdat.responseData.results[i].titleNoFormatting:gsub('%[.+%]', ''):gsub('&', '&')
|
|
||||||
--[[
|
|
||||||
if title:len() > 48 then
|
|
||||||
title = title:sub(1, 45) .. '...'
|
|
||||||
end
|
|
||||||
]]--
|
|
||||||
local u = jdat.responseData.results[i].unescapedUrl
|
|
||||||
if u:find('%)') then
|
|
||||||
output = output .. '• ' .. title .. '\n' .. u:gsub('_', '\\_') .. '\n'
|
|
||||||
else
|
|
||||||
output = output .. '• [' .. title .. '](' .. u .. ')\n'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
59
otouto/plugins/get.lua
Normal file
59
otouto/plugins/get.lua
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
local get = {}
|
||||||
|
|
||||||
|
local utilities = require('otouto.utilities')
|
||||||
|
local redis = (loadfile "./otouto/redis.lua")()
|
||||||
|
|
||||||
|
get.command = 'get <Variable>'
|
||||||
|
|
||||||
|
function get:init(config)
|
||||||
|
get.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('get', true).table
|
||||||
|
get.doc = [[*
|
||||||
|
]]..config.cmd_pat..[[get*: Gibt alle Variablen aus
|
||||||
|
*]]..config.cmd_pat..[[get* _<Variable>_: Gibt _Variable_ aus
|
||||||
|
Nutze `!set <Variable> <Wert>` zum Setzen von Variablen]]
|
||||||
|
end
|
||||||
|
|
||||||
|
function get:get_value(msg, var_name)
|
||||||
|
local hash = get_redis_hash(msg, 'variables')
|
||||||
|
if hash then
|
||||||
|
local value = redis:hget(hash, var_name)
|
||||||
|
if not value then
|
||||||
|
return'Nicht gefunden; benutze /get, um alle Variablen aufzulisten.'
|
||||||
|
else
|
||||||
|
return var_name..' = '..value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function get:list_variables(msg)
|
||||||
|
local hash = get_redis_hash(msg, 'variables')
|
||||||
|
print(hash)
|
||||||
|
|
||||||
|
if hash then
|
||||||
|
print('Getting variable from redis hash '..hash)
|
||||||
|
local names = redis:hkeys(hash)
|
||||||
|
local text = ''
|
||||||
|
for i=1, #names do
|
||||||
|
variables = get:get_value(msg, names[i])
|
||||||
|
text = text..variables.."\n"
|
||||||
|
end
|
||||||
|
if text == '' or text == nil then
|
||||||
|
return 'Keine Variablen vorhanden!'
|
||||||
|
else
|
||||||
|
return text
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function get:action(msg)
|
||||||
|
local input = utilities.input(msg.text)
|
||||||
|
if input then
|
||||||
|
output = get:get_value(msg, input:match('(.+)'))
|
||||||
|
else
|
||||||
|
output = get:list_variables(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
return get
|
0
otouto/plugins/greetings.lua
Executable file → Normal file
0
otouto/plugins/greetings.lua
Executable file → Normal file
0
otouto/plugins/hackernews.lua
Executable file → Normal file
0
otouto/plugins/hackernews.lua
Executable file → Normal file
0
otouto/plugins/hearthstone.lua
Executable file → Normal file
0
otouto/plugins/hearthstone.lua
Executable file → Normal file
16
otouto/plugins/help.lua
Executable file → Normal file
16
otouto/plugins/help.lua
Executable file → Normal file
@ -10,7 +10,7 @@ local help_text
|
|||||||
function help:init(config)
|
function help:init(config)
|
||||||
|
|
||||||
local commandlist = {}
|
local commandlist = {}
|
||||||
help_text = '*Available commands:*\n• '..config.cmd_pat
|
help_text = '*Verfügbare Befehle:*\n• '..config.cmd_pat
|
||||||
|
|
||||||
for _,plugin in ipairs(self.plugins) do
|
for _,plugin in ipairs(self.plugins) do
|
||||||
if plugin.command then
|
if plugin.command then
|
||||||
@ -19,14 +19,14 @@ function help:init(config)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(commandlist, 'help [command]')
|
table.insert(commandlist, 'hilfe [Plugin]')
|
||||||
table.sort(commandlist)
|
table.sort(commandlist)
|
||||||
|
|
||||||
help_text = help_text .. table.concat(commandlist, '\n• '..config.cmd_pat) .. '\nArguments: <required> [optional]'
|
help_text = help_text .. table.concat(commandlist, '\n• '..config.cmd_pat) .. '\nParameter: <benötigt> [optional]'
|
||||||
|
|
||||||
help_text = help_text:gsub('%[', '\\[')
|
help_text = help_text:gsub('%[', '\\[')
|
||||||
|
|
||||||
help.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('help', true):t('h', true).table
|
help.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('hilfe', true):t('help', true).table
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -39,22 +39,22 @@ function help:action(msg)
|
|||||||
if not input then
|
if not input then
|
||||||
local res = utilities.send_message(self, msg.from.id, help_text, true, nil, true)
|
local res = utilities.send_message(self, msg.from.id, help_text, true, nil, true)
|
||||||
if not res then
|
if not res then
|
||||||
utilities.send_reply(self, msg, 'Please message me privately or [click here](http://telegram.me/' .. self.info.username .. '?start=help) for a list of commands.', true)
|
utilities.send_reply(self, msg, 'Bitte schreibe mir zuerst [privat](http://telegram.me/' .. self.info.username .. '?start=help) für eine Hilfe.', true)
|
||||||
elseif msg.chat.type ~= 'private' then
|
elseif msg.chat.type ~= 'private' then
|
||||||
utilities.send_reply(self, msg, 'I have sent you the requested information in a private message.')
|
utilities.send_reply(self, msg, 'Ich habe dir die Hilfe per PN gesendet!.')
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
for _,plugin in ipairs(self.plugins) do
|
for _,plugin in ipairs(self.plugins) do
|
||||||
if plugin.command and utilities.get_word(plugin.command, 1) == input and plugin.doc then
|
if plugin.command and utilities.get_word(plugin.command, 1) == input and plugin.doc then
|
||||||
local output = '*Help for* _' .. utilities.get_word(plugin.command, 1) .. '_ *:*\n' .. plugin.doc
|
local output = '*Hilfe für* _' .. utilities.get_word(plugin.command, 1) .. '_ *:*' .. plugin.doc
|
||||||
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
utilities.send_reply(self, msg, 'Sorry, there is no help for that command.')
|
utilities.send_reply(self, msg, 'Für diesen Befehl gibt es keine Hilfe.')
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
19
otouto/plugins/imdb.lua
Executable file → Normal file
19
otouto/plugins/imdb.lua
Executable file → Normal file
@ -4,15 +4,15 @@ local HTTP = require('socket.http')
|
|||||||
local URL = require('socket.url')
|
local URL = require('socket.url')
|
||||||
local JSON = require('dkjson')
|
local JSON = require('dkjson')
|
||||||
local utilities = require('otouto.utilities')
|
local utilities = require('otouto.utilities')
|
||||||
|
local bindings = require('otouto.bindings')
|
||||||
|
|
||||||
imdb.command = 'imdb <query>'
|
imdb.command = 'imdb <query>'
|
||||||
|
|
||||||
function imdb:init(config)
|
function imdb:init(config)
|
||||||
imdb.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('imdb', true).table
|
imdb.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('imdb', true).table
|
||||||
imdb.doc = [[```
|
imdb.doc = [[*
|
||||||
]]..config.cmd_pat..[[imdb <query>
|
]]..config.cmd_pat..[[imdb* _<Film>_
|
||||||
Returns an IMDb entry.
|
Sucht _Film_ bei IMDB]]
|
||||||
```]]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function imdb:action(msg, config)
|
function imdb:action(msg, config)
|
||||||
@ -42,13 +42,18 @@ function imdb:action(msg, config)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local output = '*' .. jdat.Title .. ' ('.. jdat.Year ..')*\n'
|
local output = '*' .. jdat.Title .. ' ('.. jdat.Year ..')* von '..jdat.Director..'\n'
|
||||||
output = output .. jdat.imdbRating ..'/10 | '.. jdat.Runtime ..' | '.. jdat.Genre ..'\n'
|
output = output .. string.gsub(jdat.imdbRating, '%.', ',') ..'/10 | '.. jdat.Runtime ..' | '.. jdat.Genre ..'\n'
|
||||||
output = output .. '_' .. jdat.Plot .. '_\n'
|
output = output .. '_' .. jdat.Plot .. '_\n'
|
||||||
output = output .. '[Read more.](http://imdb.com/title/' .. jdat.imdbID .. ')'
|
output = output .. '[IMDB-Seite besuchen](http://imdb.com/title/' .. jdat.imdbID .. ')'
|
||||||
|
|
||||||
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
||||||
|
|
||||||
|
if jdat.Poster ~= "N/A" then
|
||||||
|
local file = download_to_file(jdat.Poster)
|
||||||
|
bindings.sendPhoto(self, {chat_id = msg.chat.id}, {photo = file} )
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return imdb
|
return imdb
|
||||||
|
71
otouto/plugins/imgblacklist.lua
Normal file
71
otouto/plugins/imgblacklist.lua
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
local imgblacklist = {}
|
||||||
|
|
||||||
|
local utilities = require('otouto.utilities')
|
||||||
|
local redis = (loadfile "./otouto/redis.lua")()
|
||||||
|
|
||||||
|
imgblacklist.command = 'imgblacklist'
|
||||||
|
|
||||||
|
function imgblacklist:init(config)
|
||||||
|
imgblacklist.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('imgblacklist', true).table
|
||||||
|
imgblacklist.doc = [[*
|
||||||
|
]]..config.cmd_pat..[[imgblacklist* _show_: Zeige Blacklist
|
||||||
|
*]]..config.cmd_pat..[[imgblacklist* _add_ _<Wort>_: Fügt Wort der Blacklist hinzu
|
||||||
|
*]]..config.cmd_pat..[[imgblacklist* _remove_ _<Wort>_: Entfernt Wort von der Blacklist]]
|
||||||
|
end
|
||||||
|
|
||||||
|
function imgblacklist:show_blacklist()
|
||||||
|
if not _blacklist[1] then
|
||||||
|
return "Keine Wörter geblacklisted!\nBlackliste welche mit `/imgblacklist add [Wort]`"
|
||||||
|
else
|
||||||
|
local sort_alph = function( a,b ) return a < b end
|
||||||
|
table.sort( _blacklist, sort_alph )
|
||||||
|
local blacklist = "Folgende Wörter stehen auf der Blacklist:\n"
|
||||||
|
for v,word in pairs(_blacklist) do
|
||||||
|
blacklist = blacklist..'- '..word..'\n'
|
||||||
|
end
|
||||||
|
return blacklist
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function imgblacklist:add_blacklist(word)
|
||||||
|
print('Blacklisting '..word..' - saving to redis set telegram:img_blacklist')
|
||||||
|
if redis:sismember("telegram:img_blacklist", word) == true then
|
||||||
|
return '"'..word..'" steht schon auf der Blacklist.'
|
||||||
|
else
|
||||||
|
redis:sadd("telegram:img_blacklist", word)
|
||||||
|
return '"'..word..'" blacklisted!'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function imgblacklist:remove_blacklist(word)
|
||||||
|
print('De-blacklisting '..word..' - removing from redis set telegram:img_blacklist')
|
||||||
|
if redis:sismember("telegram:img_blacklist", word) == true then
|
||||||
|
redis:srem("telegram:img_blacklist", word)
|
||||||
|
return '"'..word..'" erfolgreich von der Blacklist gelöscht!'
|
||||||
|
else
|
||||||
|
return '"'..word..'" steht nicht auf der Blacklist.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function imgblacklist:action(msg)
|
||||||
|
local input = utilities.input(msg.text)
|
||||||
|
local input = string.lower(input)
|
||||||
|
_blacklist = redis:smembers("telegram:img_blacklist")
|
||||||
|
|
||||||
|
if input:match('(add) (.*)') then
|
||||||
|
local word = input:match('add (.*)')
|
||||||
|
output = imgblacklist:add_blacklist(word)
|
||||||
|
elseif input:match('(remove) (.*)') then
|
||||||
|
local word = input:match('remove (.*)')
|
||||||
|
output = imgblacklist:remove_blacklist(word)
|
||||||
|
elseif input:match('(show)') then
|
||||||
|
output = imgblacklist:show_blacklist()
|
||||||
|
else
|
||||||
|
utilities.send_message(self, msg.chat.id, imgblacklist.doc, true, msg.message_id, true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
return imgblacklist
|
0
otouto/plugins/lastfm.lua
Executable file → Normal file
0
otouto/plugins/lastfm.lua
Executable file → Normal file
0
otouto/plugins/nick.lua
Executable file → Normal file
0
otouto/plugins/nick.lua
Executable file → Normal file
0
otouto/plugins/ping.lua
Executable file → Normal file
0
otouto/plugins/ping.lua
Executable file → Normal file
0
otouto/plugins/pokedex.lua
Executable file → Normal file
0
otouto/plugins/pokedex.lua
Executable file → Normal file
0
otouto/plugins/pun.lua
Executable file → Normal file
0
otouto/plugins/pun.lua
Executable file → Normal file
0
otouto/plugins/reactions.lua
Executable file → Normal file
0
otouto/plugins/reactions.lua
Executable file → Normal file
0
otouto/plugins/reddit.lua
Executable file → Normal file
0
otouto/plugins/reddit.lua
Executable file → Normal file
55
otouto/plugins/set.lua
Normal file
55
otouto/plugins/set.lua
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
local set = {}
|
||||||
|
|
||||||
|
local utilities = require('otouto.utilities')
|
||||||
|
local redis = (loadfile "./otouto/redis.lua")()
|
||||||
|
|
||||||
|
set.command = 'set <Variable> <Wert>'
|
||||||
|
|
||||||
|
function set:init(config)
|
||||||
|
set.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('set', true).table
|
||||||
|
set.doc = [[*
|
||||||
|
]]..config.cmd_pat..[[set* _<Variable>_ _<Wert>_: Speichert eine Variable mit einem Wert
|
||||||
|
*]]..config.cmd_pat..[[set* _<Variable>_ _nil_: Löscht Variable
|
||||||
|
Nutze `!get <Variable>` zum Abrufen]]
|
||||||
|
end
|
||||||
|
|
||||||
|
function set:save_value(msg, name, value)
|
||||||
|
local hash = get_redis_hash(msg, 'variables')
|
||||||
|
if hash then
|
||||||
|
print('Saving variable to redis hash '..hash)
|
||||||
|
redis:hset(hash, name, value)
|
||||||
|
return "Gespeichert: "..name.." = "..value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function set:delete_value(msg, name)
|
||||||
|
local hash = get_redis_hash(msg, 'variables')
|
||||||
|
if redis:hexists(hash, name) == true then
|
||||||
|
print('Deleting variable from redis hash '..hash)
|
||||||
|
redis:hdel(hash, name)
|
||||||
|
return 'Variable "'..name..'" erfolgreich gelöscht!'
|
||||||
|
else
|
||||||
|
return 'Du kannst keine Variable löschen, die nicht existiert .-.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function set:action(msg)
|
||||||
|
local input = utilities.input(msg.text)
|
||||||
|
if not input:match('([^%s]+) (.+)') then
|
||||||
|
utilities.send_message(self, msg.chat.id, set.doc, true, msg.message_id, true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = input:match('([^%s]+) ')
|
||||||
|
local value = input:match(' (.+)')
|
||||||
|
|
||||||
|
if value == "nil" then
|
||||||
|
output = set:delete_value(msg, name)
|
||||||
|
else
|
||||||
|
output = set:save_value(msg, name, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
return set
|
@ -1,72 +0,0 @@
|
|||||||
local setandget = {}
|
|
||||||
|
|
||||||
local utilities = require('otouto.utilities')
|
|
||||||
|
|
||||||
function setandget:init(config)
|
|
||||||
self.database.setandget = self.database.setandget or {}
|
|
||||||
setandget.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('set', true):t('get', true).table
|
|
||||||
setandget.doc = [[```
|
|
||||||
]]..config.cmd_pat..[[set <name> <value>
|
|
||||||
Stores a value with the given name. Use "]]..config.cmd_pat..[[set <name> --" to delete the stored value.
|
|
||||||
]]..config.cmd_pat..[[get [name]
|
|
||||||
Returns the stored value or a list of stored values.
|
|
||||||
```]]
|
|
||||||
end
|
|
||||||
|
|
||||||
setandget.command = 'set <name> <value>'
|
|
||||||
|
|
||||||
function setandget:action(msg, config)
|
|
||||||
|
|
||||||
local input = utilities.input(msg.text)
|
|
||||||
self.database.setandget[msg.chat.id_str] = self.database.setandget[msg.chat.id_str] or {}
|
|
||||||
|
|
||||||
if msg.text_lower:match('^'..config.cmd_pat..'set') then
|
|
||||||
|
|
||||||
if not input then
|
|
||||||
utilities.send_message(self, msg.chat.id, setandget.doc, true, nil, true)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local name = utilities.get_word(input:lower(), 1)
|
|
||||||
local value = utilities.input(input)
|
|
||||||
|
|
||||||
if not name or not value then
|
|
||||||
utilities.send_message(self, msg.chat.id, setandget.doc, true, nil, true)
|
|
||||||
elseif value == '--' or value == '—' then
|
|
||||||
self.database.setandget[msg.chat.id_str][name] = nil
|
|
||||||
utilities.send_message(self, msg.chat.id, 'That value has been deleted.')
|
|
||||||
else
|
|
||||||
self.database.setandget[msg.chat.id_str][name] = value
|
|
||||||
utilities.send_message(self, msg.chat.id, '"' .. name .. '" has been set to "' .. value .. '".', true)
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif msg.text_lower:match('^'..config.cmd_pat..'get') then
|
|
||||||
|
|
||||||
if not input then
|
|
||||||
local output
|
|
||||||
if utilities.table_size(self.database.setandget[msg.chat.id_str]) == 0 then
|
|
||||||
output = 'No values have been stored here.'
|
|
||||||
else
|
|
||||||
output = '*List of stored values:*\n'
|
|
||||||
for k,v in pairs(self.database.setandget[msg.chat.id_str]) do
|
|
||||||
output = output .. '• ' .. k .. ': `' .. v .. '`\n'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local output
|
|
||||||
if self.database.setandget[msg.chat.id_str][input:lower()] then
|
|
||||||
output = '`' .. self.database.setandget[msg.chat.id_str][input:lower()] .. '`'
|
|
||||||
else
|
|
||||||
output = 'There is no value stored by that name.'
|
|
||||||
end
|
|
||||||
|
|
||||||
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
return setandget
|
|
@ -3,26 +3,26 @@ local shell = {}
|
|||||||
local utilities = require('otouto.utilities')
|
local utilities = require('otouto.utilities')
|
||||||
|
|
||||||
function shell:init(config)
|
function shell:init(config)
|
||||||
shell.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('run', true).table
|
shell.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('sh', true).table
|
||||||
end
|
end
|
||||||
|
|
||||||
function shell:action(msg, config)
|
function shell:action(msg, config)
|
||||||
|
|
||||||
if msg.from.id ~= config.admin then
|
if msg.from.id ~= config.admin then
|
||||||
return
|
utilities.send_reply(self, msg, config.errors.sudo)
|
||||||
end
|
end
|
||||||
|
|
||||||
local input = utilities.input(msg.text)
|
local input = utilities.input(msg.text)
|
||||||
input = input:gsub('—', '--')
|
input = input:gsub('—', '--')
|
||||||
|
|
||||||
if not input then
|
if not input then
|
||||||
utilities.send_reply(self, msg, 'Please specify a command to run.')
|
utilities.send_reply(self, msg, 'Bitte gebe ein Kommando ein.')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local output = io.popen(input):read('*all')
|
local output = io.popen(input):read('*all')
|
||||||
if output:len() == 0 then
|
if output:len() == 0 then
|
||||||
output = 'Done!'
|
output = 'Ausgeführt.'
|
||||||
else
|
else
|
||||||
output = '```\n' .. output .. '\n```'
|
output = '```\n' .. output .. '\n```'
|
||||||
end
|
end
|
||||||
|
0
otouto/plugins/slap.lua
Executable file → Normal file
0
otouto/plugins/slap.lua
Executable file → Normal file
0
otouto/plugins/time.lua
Executable file → Normal file
0
otouto/plugins/time.lua
Executable file → Normal file
0
otouto/plugins/translate.lua
Executable file → Normal file
0
otouto/plugins/translate.lua
Executable file → Normal file
156
otouto/plugins/twitter.lua
Normal file
156
otouto/plugins/twitter.lua
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
local twitter = {}
|
||||||
|
|
||||||
|
local utilities = require('otouto.utilities')
|
||||||
|
local HTTPS = require('ssl.https')
|
||||||
|
local JSON = require('dkjson')
|
||||||
|
local redis = (loadfile "./otouto/redis.lua")()
|
||||||
|
local OAuth = (require "OAuth")
|
||||||
|
local bindings = require('otouto.bindings')
|
||||||
|
|
||||||
|
function twitter:init(config)
|
||||||
|
if not cred_data.tw_consumer_key then
|
||||||
|
print('Missing config value: tw_consumer_key.')
|
||||||
|
print('twitter.lua will not be enabled.')
|
||||||
|
return
|
||||||
|
elseif not cred_data.tw_consumer_secret then
|
||||||
|
print('Missing config value: tw_consumer_secret.')
|
||||||
|
print('twitter.lua will not be enabled.')
|
||||||
|
return
|
||||||
|
elseif not cred_data.tw_access_token then
|
||||||
|
print('Missing config value: tw_access_token.')
|
||||||
|
print('twitter.lua will not be enabled.')
|
||||||
|
return
|
||||||
|
elseif not cred_data.tw_access_token_secret then
|
||||||
|
print('Missing config value: tw_access_token_secret.')
|
||||||
|
print('twitter.lua will not be enabled.')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
twitter.triggers = {
|
||||||
|
'twitter.com/[^/]+/statuse?s?/([0-9]+)'
|
||||||
|
}
|
||||||
|
twitter.doc = [[*Twitter-Link*: Postet Tweet]]
|
||||||
|
end
|
||||||
|
|
||||||
|
local consumer_key = cred_data.tw_consumer_key
|
||||||
|
local consumer_secret = cred_data.tw_consumer_secret
|
||||||
|
local access_token = cred_data.tw_access_token
|
||||||
|
local access_token_secret = cred_data.tw_access_token_secret
|
||||||
|
|
||||||
|
local client = OAuth.new(consumer_key, consumer_secret, {
|
||||||
|
RequestToken = "https://api.twitter.com/oauth/request_token",
|
||||||
|
AuthorizeUser = {"https://api.twitter.com/oauth/authorize", method = "GET"},
|
||||||
|
AccessToken = "https://api.twitter.com/oauth/access_token"
|
||||||
|
}, {
|
||||||
|
OAuthToken = access_token,
|
||||||
|
OAuthTokenSecret = access_token_secret
|
||||||
|
})
|
||||||
|
|
||||||
|
function twitter:action(msg)
|
||||||
|
|
||||||
|
if not msg.text:match('twitter.com/[^/]+/statuse?s?/([0-9]+)') then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local id = msg.text:match('twitter.com/[^/]+/statuse?s?/([0-9]+)')
|
||||||
|
|
||||||
|
local twitter_url = "https://api.twitter.com/1.1/statuses/show/" .. id.. ".json"
|
||||||
|
local response_code, response_headers, response_status_line, response_body = client:PerformRequest("GET", twitter_url)
|
||||||
|
local response = JSON.decode(response_body)
|
||||||
|
|
||||||
|
local full_name = response.user.name
|
||||||
|
local user_name = response.user.screen_name
|
||||||
|
if response.user.verified then
|
||||||
|
verified = ' ✅'
|
||||||
|
else
|
||||||
|
verified = ''
|
||||||
|
end
|
||||||
|
-- MD: local header = 'Tweet von '..full_name..' ([@' ..user_name.. '](https://twitter.com/'..user_name..')'..verified..')\n'
|
||||||
|
local header = 'Tweet von '..full_name..' (@' ..user_name..verified..')\n'
|
||||||
|
|
||||||
|
local text = response.text
|
||||||
|
|
||||||
|
-- favorites & retweets
|
||||||
|
if response.retweet_count == 0 then
|
||||||
|
retweets = ""
|
||||||
|
else
|
||||||
|
retweets = response.retweet_count..'x retweeted'
|
||||||
|
end
|
||||||
|
if response.favorite_count == 0 then
|
||||||
|
favorites = ""
|
||||||
|
else
|
||||||
|
favorites = response.favorite_count..'x favorisiert'
|
||||||
|
end
|
||||||
|
if retweets == "" and favorites ~= "" then
|
||||||
|
footer = favorites
|
||||||
|
elseif retweets ~= "" and favorites == "" then
|
||||||
|
footer = retweets
|
||||||
|
elseif retweets ~= "" and favorites ~= "" then
|
||||||
|
footer = retweets..' - '..favorites
|
||||||
|
else
|
||||||
|
footer = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
-- replace short URLs
|
||||||
|
if response.entities.urls then
|
||||||
|
for k, v in pairs(response.entities.urls) do
|
||||||
|
local short = v.url
|
||||||
|
local long = v.expanded_url
|
||||||
|
text = text:gsub(short, long)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- remove images
|
||||||
|
local images = {}
|
||||||
|
local videos = {}
|
||||||
|
if response.entities.media and response.extended_entities.media then
|
||||||
|
for k, v in pairs(response.extended_entities.media) do
|
||||||
|
local url = v.url
|
||||||
|
local pic = v.media_url_https
|
||||||
|
if v.video_info then
|
||||||
|
if not v.video_info.variants[3] then
|
||||||
|
local vid = v.video_info.variants[1].url
|
||||||
|
table.insert(videos, vid)
|
||||||
|
else
|
||||||
|
local vid = v.video_info.variants[3].url
|
||||||
|
table.insert(videos, vid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
text = text:gsub(url, "")
|
||||||
|
table.insert(images, pic)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- quoted tweet
|
||||||
|
if response.quoted_status then
|
||||||
|
local quoted_text = response.quoted_status.text
|
||||||
|
local quoted_name = response.quoted_status.user.name
|
||||||
|
local quoted_screen_name = response.quoted_status.user.screen_name
|
||||||
|
if response.quoted_status.user.verified then
|
||||||
|
quoted_verified = ' ✅'
|
||||||
|
else
|
||||||
|
quoted_verified = ''
|
||||||
|
end
|
||||||
|
-- MD: quote = 'Als Antwort auf '..quoted_name..' ([@' ..quoted_screen_name.. '](https://twitter.com/'..quoted_screen_name..')'..quoted_verified..'):\n'..quoted_text
|
||||||
|
quote = 'Als Antwort auf '..quoted_name..' (@' ..quoted_screen_name..quoted_verified..'):\n'..quoted_text
|
||||||
|
text = text..'\n\n'..quote..'\n'
|
||||||
|
end
|
||||||
|
|
||||||
|
-- send the parts
|
||||||
|
local text = unescape(text)
|
||||||
|
print(header .. "\n" .. text.."\n"..footer)
|
||||||
|
utilities.send_reply(self, msg, header .. "\n" .. text.."\n"..footer)
|
||||||
|
for k, v in pairs(images) do
|
||||||
|
local file = download_to_file(v)
|
||||||
|
bindings.sendPhoto(self, {chat_id = msg.chat.id}, {photo = file} )
|
||||||
|
os.remove(file)
|
||||||
|
print("Deleted: "..file)
|
||||||
|
end
|
||||||
|
for k, v in pairs(videos) do
|
||||||
|
local file = download_to_file(v)
|
||||||
|
bindings.sendVideo(self, {chat_id = msg.chat.id}, {video = file} )
|
||||||
|
os.remove(file)
|
||||||
|
print("Deleted: "..file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return twitter
|
0
otouto/plugins/urbandictionary.lua
Executable file → Normal file
0
otouto/plugins/urbandictionary.lua
Executable file → Normal file
0
otouto/plugins/weather.lua
Executable file → Normal file
0
otouto/plugins/weather.lua
Executable file → Normal file
0
otouto/plugins/whoami.lua
Executable file → Normal file
0
otouto/plugins/whoami.lua
Executable file → Normal file
20
otouto/plugins/wikipedia.lua
Executable file → Normal file
20
otouto/plugins/wikipedia.lua
Executable file → Normal file
@ -5,20 +5,18 @@ local URL = require('socket.url')
|
|||||||
local JSON = require('dkjson')
|
local JSON = require('dkjson')
|
||||||
local utilities = require('otouto.utilities')
|
local utilities = require('otouto.utilities')
|
||||||
|
|
||||||
wikipedia.command = 'wikipedia <query>'
|
wikipedia.command = 'wiki <Begriff>'
|
||||||
|
|
||||||
function wikipedia:init(config)
|
function wikipedia:init(config)
|
||||||
wikipedia.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('wikipedia', true):t('wiki', true):t('w', true).table
|
wikipedia.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('wikipedia', true):t('wiki', true):t('w', true).table
|
||||||
wikipedia.doc = [[```
|
wikipedia.doc = [[*
|
||||||
]]..config.cmd_pat..[[wikipedia <query>
|
]]..config.cmd_pat..[[wiki* _<Begriff>_: Gibt Wikipedia-Artikel aus
|
||||||
Returns an article from Wikipedia.
|
Aliase: ]]..config.cmd_pat..[[w, ]]..config.cmd_pat..[[wikipedia]]
|
||||||
Aliases: ]]..config.cmd_pat..[[w, ]]..config.cmd_pat..[[wiki
|
|
||||||
```]]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local get_title = function(search)
|
local get_title = function(search)
|
||||||
for _,v in ipairs(search) do
|
for _,v in ipairs(search) do
|
||||||
if not v.snippet:match('may refer to:') then
|
if not v.snippet:match('steht für') then
|
||||||
return v.title
|
return v.title
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -46,7 +44,7 @@ function wikipedia:action(msg, config)
|
|||||||
local jstr, res, jdat
|
local jstr, res, jdat
|
||||||
|
|
||||||
-- All pretty standard from here.
|
-- All pretty standard from here.
|
||||||
local search_url = 'https://en.wikipedia.org/w/api.php?action=query&list=search&format=json&srsearch='
|
local search_url = 'https://de.wikipedia.org/w/api.php?action=query&list=search&format=json&srsearch='
|
||||||
|
|
||||||
jstr, res = HTTPS.request(search_url .. URL.escape(input))
|
jstr, res = HTTPS.request(search_url .. URL.escape(input))
|
||||||
if res ~= 200 then
|
if res ~= 200 then
|
||||||
@ -66,7 +64,7 @@ function wikipedia:action(msg, config)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local res_url = 'https://en.wikipedia.org/w/api.php?action=query&prop=extracts&format=json&exchars=4000&exsectionformat=plain&titles='
|
local res_url = 'https://de.wikipedia.org/w/api.php?action=query&prop=extracts&format=json&exchars=4000&exsectionformat=plain&titles='
|
||||||
|
|
||||||
jstr, res = HTTPS.request(res_url .. URL.escape(title))
|
jstr, res = HTTPS.request(res_url .. URL.escape(title))
|
||||||
if res ~= 200 then
|
if res ~= 200 then
|
||||||
@ -97,7 +95,7 @@ function wikipedia:action(msg, config)
|
|||||||
-- first part of the text is the title, and if so, we embolden that.
|
-- first part of the text is the title, and if so, we embolden that.
|
||||||
-- Otherwise, we prepend the text with a bold title. Then we append a "Read
|
-- Otherwise, we prepend the text with a bold title. Then we append a "Read
|
||||||
-- More" link.
|
-- More" link.
|
||||||
local url = 'https://en.wikipedia.org/wiki/' .. URL.escape(title)
|
local url = 'https://de.wikipedia.org/wiki/' .. URL.escape(title)
|
||||||
title = title:gsub('%(.+%)', '')
|
title = title:gsub('%(.+%)', '')
|
||||||
local output
|
local output
|
||||||
if string.match(text:sub(1, title:len()), title) then
|
if string.match(text:sub(1, title:len()), title) then
|
||||||
@ -105,7 +103,7 @@ function wikipedia:action(msg, config)
|
|||||||
else
|
else
|
||||||
output = '*' .. title:gsub('%(.+%)', '') .. '*\n' .. text:gsub('%[.+%]','')
|
output = '*' .. title:gsub('%(.+%)', '') .. '*\n' .. text:gsub('%[.+%]','')
|
||||||
end
|
end
|
||||||
output = output .. '\n[Read more.](' .. url:gsub('%)', '\\)') .. ')'
|
output = output .. '\n[Wikipedia - '..title..'](' .. url:gsub('%)', '\\)') .. ')'
|
||||||
|
|
||||||
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
utilities.send_message(self, msg.chat.id, output, true, nil, true)
|
||||||
|
|
||||||
|
0
otouto/plugins/xkcd.lua
Executable file → Normal file
0
otouto/plugins/xkcd.lua
Executable file → Normal file
0
otouto/plugins/youtube.lua
Executable file → Normal file
0
otouto/plugins/youtube.lua
Executable file → Normal file
47
otouto/redis.lua
Normal file
47
otouto/redis.lua
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
local Redis = require 'redis'
|
||||||
|
local FakeRedis = require 'fakeredis'
|
||||||
|
|
||||||
|
|
||||||
|
local params = {
|
||||||
|
'unix:///home/anditest/.redis/sock'
|
||||||
|
}
|
||||||
|
|
||||||
|
-- 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('unix:///home/anditest/.redis/sock') -- FUCKING FUCK REDIS LUA FUCK Y U NO WORK WITH 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
|
248
otouto/utilities.lua
Executable file → Normal file
248
otouto/utilities.lua
Executable file → Normal file
@ -8,7 +8,10 @@ local ltn12 = require('ltn12')
|
|||||||
local HTTPS = require('ssl.https')
|
local HTTPS = require('ssl.https')
|
||||||
local URL = require('socket.url')
|
local URL = require('socket.url')
|
||||||
local JSON = require('dkjson')
|
local JSON = require('dkjson')
|
||||||
|
local serpent = require("serpent")
|
||||||
local bindings = require('otouto.bindings')
|
local bindings = require('otouto.bindings')
|
||||||
|
local redis = (loadfile "./otouto/redis.lua")()
|
||||||
|
local mimetype = (loadfile "./otouto/mimetype.lua")()
|
||||||
|
|
||||||
-- For the sake of ease to new contributors and familiarity to old contributors,
|
-- For the sake of ease to new contributors and familiarity to old contributors,
|
||||||
-- we'll provide a couple of aliases to real bindings here.
|
-- we'll provide a couple of aliases to real bindings here.
|
||||||
@ -31,7 +34,6 @@ function utilities:send_reply(old_msg, text, use_markdown)
|
|||||||
parse_mode = use_markdown and 'Markdown' or nil
|
parse_mode = use_markdown and 'Markdown' or nil
|
||||||
} )
|
} )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get the indexed word in a string
|
-- get the indexed word in a string
|
||||||
function utilities.get_word(s, i)
|
function utilities.get_word(s, i)
|
||||||
s = s or ''
|
s = s or ''
|
||||||
@ -108,6 +110,92 @@ local lc_list = {
|
|||||||
['!'] = 'ǃ'
|
['!'] = 'ǃ'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- http://www.lua.org/manual/5.2/manual.html#pdf-io.popen
|
||||||
|
function run_command(str)
|
||||||
|
local cmd = io.popen(str)
|
||||||
|
local result = cmd:read('*all')
|
||||||
|
cmd:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.starts(String, Start)
|
||||||
|
return Start == string.sub(String,1,string.len(Start))
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_http_file_name(url, headers)
|
||||||
|
-- Eg: fooo.var
|
||||||
|
local file_name = url:match("[^%w]+([%.%w]+)$")
|
||||||
|
-- Any delimited aphanumeric 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)
|
||||||
|
|
||||||
|
local content_type = headers["content-type"]
|
||||||
|
|
||||||
|
local extension = nil
|
||||||
|
if content_type then
|
||||||
|
extension = mimetype.get_mime_extension(content_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
if extension then
|
||||||
|
file_name = file_name.."."..extension
|
||||||
|
end
|
||||||
|
|
||||||
|
local disposition = headers["content-disposition"]
|
||||||
|
if disposition then
|
||||||
|
-- attachment; filename=CodeCogsEqn.png
|
||||||
|
file_name = disposition:match('filename=([^;]+)') or file_name
|
||||||
|
file_name = string.gsub(file_name, "\"", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
return file_name
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Saves file to $HOME/tmp/. If file_name isn't provided,
|
||||||
|
-- will get the text after the last "/" for filename
|
||||||
|
-- and content-type for extension
|
||||||
|
function download_to_file(url, file_name)
|
||||||
|
print("url to download: "..url)
|
||||||
|
|
||||||
|
local respbody = {}
|
||||||
|
local options = {
|
||||||
|
url = url,
|
||||||
|
sink = ltn12.sink.table(respbody),
|
||||||
|
redirect = true
|
||||||
|
}
|
||||||
|
|
||||||
|
-- nil, code, headers, status
|
||||||
|
local response = nil
|
||||||
|
|
||||||
|
if string.starts(url, 'https') then
|
||||||
|
options.redirect = false
|
||||||
|
response = {HTTPS.request(options)}
|
||||||
|
else
|
||||||
|
response = {HTTP.request(options)}
|
||||||
|
end
|
||||||
|
|
||||||
|
local code = response[2]
|
||||||
|
local headers = response[3]
|
||||||
|
local status = response[4]
|
||||||
|
|
||||||
|
if code ~= 200 then return nil end
|
||||||
|
|
||||||
|
file_name = file_name or get_http_file_name(url, headers)
|
||||||
|
|
||||||
|
local file_path = "/home/anditest/tmp/telegram-bot/"..file_name
|
||||||
|
print("Saved to: "..file_path)
|
||||||
|
|
||||||
|
file = io.open(file_path, "w+")
|
||||||
|
file:write(table.concat(respbody))
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
return file_path
|
||||||
|
end
|
||||||
|
|
||||||
|
function vardump(value)
|
||||||
|
print(serpent.block(value, {comment=false}))
|
||||||
|
end
|
||||||
|
|
||||||
-- Replaces letters with corresponding Cyrillic characters.
|
-- Replaces letters with corresponding Cyrillic characters.
|
||||||
function utilities.latcyr(str)
|
function utilities.latcyr(str)
|
||||||
for k,v in pairs(lc_list) do
|
for k,v in pairs(lc_list) do
|
||||||
@ -373,4 +461,162 @@ utilities.char = {
|
|||||||
em_dash = '—'
|
em_dash = '—'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_redis_hash(msg, var)
|
||||||
|
if msg.chat.type == 'group' or msg.chat.type == 'supergroup' then
|
||||||
|
return 'chat:'..msg.chat.id..':'..var
|
||||||
|
end
|
||||||
|
if msg.chat.type == 'private' then
|
||||||
|
return 'user:'..msg.from.id..':'..var
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- remove whitespace
|
||||||
|
function all_trim(s)
|
||||||
|
return s:match( "^%s*(.-)%s*$" )
|
||||||
|
end
|
||||||
|
|
||||||
|
function tablelength(T)
|
||||||
|
local count = 0
|
||||||
|
for _ in pairs(T) do count = count + 1 end
|
||||||
|
return count
|
||||||
|
end
|
||||||
|
|
||||||
|
function comma_value(amount)
|
||||||
|
local formatted = amount
|
||||||
|
while true do
|
||||||
|
formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1.%2')
|
||||||
|
if (k==0) then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return formatted
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function string.ends(str, fin)
|
||||||
|
return fin=='' or string.sub(str,-string.len(fin)) == fin
|
||||||
|
end
|
||||||
|
|
||||||
|
function cache_data(plugin, query, data, timeout, typ)
|
||||||
|
-- How to: cache_data(pluginname, query_name, data_to_cache, expire_in_seconds)
|
||||||
|
local hash = 'telegram:cache:'..plugin..':'..query
|
||||||
|
if timeout then
|
||||||
|
print('Caching "'..query..'" from plugin '..plugin..' (expires in '..timeout..' seconds)')
|
||||||
|
else
|
||||||
|
print('Caching "'..query..'" from plugin '..plugin..' (expires never)')
|
||||||
|
end
|
||||||
|
if typ == 'key' then
|
||||||
|
redis:set(hash, data)
|
||||||
|
elseif typ == 'set' then
|
||||||
|
-- make sure that you convert your data into a table:
|
||||||
|
-- {"foo", "bar", "baz"} instead of
|
||||||
|
-- {"bar" = "foo", "foo" = "bar", "bar" = "baz"}
|
||||||
|
-- because other formats are not supported by redis (or I haven't found a way to store them)
|
||||||
|
for _,str in pairs(data) do
|
||||||
|
redis:sadd(hash, str)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
redis:hmset(hash, data)
|
||||||
|
end
|
||||||
|
if timeout then
|
||||||
|
redis:expire(hash, timeout)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Ordered table iterator, allow to iterate on the natural order of the keys of a
|
||||||
|
table.
|
||||||
|
-- http://lua-users.org/wiki/SortedIteration
|
||||||
|
]]
|
||||||
|
|
||||||
|
function __genOrderedIndex( t )
|
||||||
|
local orderedIndex = {}
|
||||||
|
for key in pairs(t) do
|
||||||
|
table.insert( orderedIndex, key )
|
||||||
|
end
|
||||||
|
table.sort( orderedIndex )
|
||||||
|
return orderedIndex
|
||||||
|
end
|
||||||
|
|
||||||
|
function orderedNext(t, state)
|
||||||
|
-- Equivalent of the next function, but returns the keys in the alphabetic
|
||||||
|
-- order. We use a temporary ordered key table that is stored in the
|
||||||
|
-- table being iterated.
|
||||||
|
|
||||||
|
key = nil
|
||||||
|
--print("orderedNext: state = "..tostring(state) )
|
||||||
|
if state == nil then
|
||||||
|
-- the first time, generate the index
|
||||||
|
t.__orderedIndex = __genOrderedIndex( t )
|
||||||
|
key = t.__orderedIndex[1]
|
||||||
|
else
|
||||||
|
-- fetch the next value
|
||||||
|
for i = 1,table.getn(t.__orderedIndex) do
|
||||||
|
if t.__orderedIndex[i] == state then
|
||||||
|
key = t.__orderedIndex[i+1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if key then
|
||||||
|
return key, t[key]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- no more value to return, cleanup
|
||||||
|
t.__orderedIndex = nil
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
function orderedPairs(t)
|
||||||
|
-- Equivalent of the pairs() function on tables. Allows to iterate
|
||||||
|
-- in order
|
||||||
|
return orderedNext, t, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- converts total amount of seconds (e.g. 65 seconds) to human redable time (e.g. 1:05 minutes)
|
||||||
|
function makeHumanTime(totalseconds)
|
||||||
|
local seconds = totalseconds % 60
|
||||||
|
local minutes = math.floor(totalseconds / 60)
|
||||||
|
local minutes = minutes % 60
|
||||||
|
local hours = math.floor(totalseconds / 3600)
|
||||||
|
if minutes == 00 and hours == 00 then
|
||||||
|
return seconds..' Sekunden'
|
||||||
|
elseif hours == 00 and minutes ~= 00 then
|
||||||
|
return string.format("%02d:%02d", minutes, seconds)..' Minuten'
|
||||||
|
elseif hours ~= 00 then
|
||||||
|
return string.format("%02d:%02d:%02d", hours, minutes, seconds)..' Stunden'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function is_blacklisted(msg)
|
||||||
|
_blacklist = redis:smembers("telegram:img_blacklist")
|
||||||
|
local var = false
|
||||||
|
for v,word in pairs(_blacklist) do
|
||||||
|
if string.find(string.lower(msg), string.lower(word)) then
|
||||||
|
print("Wort steht auf der Blacklist!")
|
||||||
|
var = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return var
|
||||||
|
end
|
||||||
|
|
||||||
|
function unescape(str)
|
||||||
|
str = string.gsub( str, '<', '<' )
|
||||||
|
str = string.gsub( str, '>', '>' )
|
||||||
|
str = string.gsub( str, '"', '"' )
|
||||||
|
str = string.gsub( str, ''', "'" )
|
||||||
|
str = string.gsub( str, "Ä", "Ä")
|
||||||
|
str = string.gsub( str, "ä", "ä")
|
||||||
|
str = string.gsub( str, "Ö", "Ö")
|
||||||
|
str = string.gsub( str, "ö", "ö")
|
||||||
|
str = string.gsub( str, "Uuml;", "Ü")
|
||||||
|
str = string.gsub( str, "ü", "ü")
|
||||||
|
str = string.gsub( str, "ß", "ß")
|
||||||
|
str = string.gsub( str, '&#(%d+);', function(n) return string.char(n) end )
|
||||||
|
str = string.gsub( str, '&#x(%d+);', function(n) return string.char(tonumber(n,16)) end )
|
||||||
|
str = string.gsub( str, '&', '&' ) -- Be sure to do this after all others
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
return utilities
|
return utilities
|
||||||
|
0
tg-install.sh
Executable file → Normal file
0
tg-install.sh
Executable file → Normal file
0
tg-launch.sh
Executable file → Normal file
0
tg-launch.sh
Executable file → Normal file
Reference in New Issue
Block a user