diff --git a/otouto/plugins/echo.lua b/otouto/plugins/echo.lua index 93d3b29..eb5d28c 100644 --- a/otouto/plugins/echo.lua +++ b/otouto/plugins/echo.lua @@ -2,14 +2,12 @@ local echo = {} local utilities = require('otouto.utilities') -echo.command = 'echo ' +echo.command = 'echo ' function echo:init(config) echo.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('echo', true).table - echo.doc = [[``` -]]..config.cmd_pat..[[echo -Repeats a string of text. -```]] + echo.doc = [[* +]]..config.cmd_pat..[[echo* __: Gibt den Text aus]] end function echo:action(msg) diff --git a/otouto/plugins/steam.lua b/otouto/plugins/steam.lua new file mode 100644 index 0000000..1db3888 --- /dev/null +++ b/otouto/plugins/steam.lua @@ -0,0 +1,63 @@ +local steam = {} + +local utilities = require('otouto.utilities') +local http = require('socket.http') +local json = require('dkjson') +local bindings = require('otouto.bindings') + +steam.triggers = { + "store.steampowered.com/app/([0-9]+)", + "steamcommunity.com/app/([0-9]+)" +} + +local BASE_URL = 'http://store.steampowered.com/api/appdetails/' +local DESC_LENTH = 400 + +function steam:get_steam_data(appid) + local url = BASE_URL + url = url..'?appids='..appid + url = url..'&l=german&cc=DE' + local res,code = http.request(url) + if code ~= 200 then return nil end + local data = json.decode(res)[appid].data + return data +end + +function steam:price_info(data) + local price = '' -- If no data is empty + + if data then + local initial = data.initial + local final = data.final or data.initial + local min = math.min(data.initial, data.final) + price = tostring(min/100) + if data.discount_percent and initial ~= final then + price = price..data.currency..' ('..data.discount_percent..'% OFF)' + end + price = price..' €' + end + + return price +end + +function steam:send_steam_data(data, self, msg) + local description = string.sub(unescape(data.about_the_game:gsub("%b<>", "")), 1, DESC_LENTH) .. '...' + local title = data.name + local price = steam:price_info(data.price_overview) + + local text = '*'..title..'* _'..price..'_\n'..description + local image_url = data.header_image + return text, image_url +end + +function steam:action(msg) + local data = steam:get_steam_data(matches[1]) + if not data then utilities.send_reply(self, msg, config.errors.connection) return end + + local text, image_url = steam:send_steam_data(data, self, msg) + utilities.send_typing(self, msg.chat.id, 'upload_photo') + utilities.send_photo(self, msg.chat.id, download_to_file(image_url, matches[1]..'.jpg'), nil, msg.message_id) + utilities.send_reply(self, msg, text, true) +end + +return steam \ No newline at end of file diff --git a/otouto/plugins/thetvdb.lua b/otouto/plugins/thetvdb.lua new file mode 100644 index 0000000..78d77dc --- /dev/null +++ b/otouto/plugins/thetvdb.lua @@ -0,0 +1,96 @@ +local tv = {} + +local http = require('socket.http') +local URL = require('socket.url') +local xml = require("xml") +local utilities = require('otouto.utilities') + +tv.command = 'tv ' + +function tv:init(config) + tv.triggers = { + "^/tv (.+)$" + } + tv.doc = [[* +]]..config.cmd_pat..[[tv*_ _: Sendet Infos zur TV-Serie]] +end + +local BASE_URL = 'http://thetvdb.com/api' + +local makeOurDate = function(dateString) + local pattern = "(%d+)%-(%d+)%-(%d+)" + local year, month, day = dateString:match(pattern) + return day..'.'..month..'.'..year +end + + +function tv:get_tv_info(series) + local url = BASE_URL..'/GetSeries.php?seriesname='..series..'&language=de' + local res,code = http.request(url) + if code ~= 200 then return "HTTP-ERROR" end + local result = xml.load(res) + if not xml.find(result, 'seriesid') then return "NOTFOUND" end + return result +end + +function tv:send_tv_data(result, self, msg) + local title = xml.find(result, 'SeriesName')[1] + local id = xml.find(result, 'seriesid')[1] + + if xml.find(result, 'AliasNames') and xml.find(result, 'AliasNames')[1] ~= title then + alias = '\noder: '..xml.find(result, 'AliasNames')[1] + else + alias = '' + end + + if xml.find(result, 'Overview') then + desc = '\n_'..string.sub(xml.find(result, 'Overview')[1], 1, 250) .. '..._' + else + desc = '' + end + + if xml.find(result, 'FirstAired') then + aired = '\n*Erstausstrahlung:* '..makeOurDate(xml.find(result, 'FirstAired')[1]) + else + aired = '' + end + + + if xml.find(result, 'Network') then + publisher = '\n*Publisher:* '..xml.find(result, 'Network')[1] + else + publisher = '' + end + + if xml.find(result, 'IMDB_ID') then + imdb = '\n[IMDB-Seite](http://www.imdb.com/title/'..xml.find(result, 'IMDB_ID')[1]..')' + else + imdb = '' + end + + local text = '*'..title..'*'..alias..aired..publisher..imdb..desc..'\n[TVDB-Seite besuchen](http://thetvdb.com/?id='..id..'&tab=series)' + if xml.find(result, 'banner') then + local image_url = 'http://www.thetvdb.com/banners/'..xml.find(result, 'banner')[1] + utilities.send_typing(self, msg.chat.id, 'upload_photo') + local file = download_to_file(image_url) + utilities.send_photo(self, msg.chat.id, file, nil, msg.message_id) + end + utilities.send_reply(self, msg, text, true) +end + + +function tv:action(msg, config, matches) + local series = URL.escape(matches[1]) + local tv_info = tv:get_tv_info(series) + if tv_info == "NOTFOUND" then + utilities.send_reply(self, msg, config.errors.results) + return + elseif tv_info == "HTTP-ERROR" then + utilities.send_reply(self, msg, config.errors.connection) + return + else + tv:send_tv_data(tv_info, self,msg) + end +end + +return tv diff --git a/otouto/plugins/translate.lua b/otouto/plugins/translate.lua index bcff57e..a80cb9f 100644 --- a/otouto/plugins/translate.lua +++ b/otouto/plugins/translate.lua @@ -1,50 +1,140 @@ local translate = {} -local HTTPS = require('ssl.https') +local https = require('ssl.https') local URL = require('socket.url') -local JSON = require('dkjson') +local json = require('dkjson') local utilities = require('otouto.utilities') +local mime = require("mime") +require("./otouto/plugins/pasteee") -translate.command = 'translate [text]' +translate.command = 'translate [Text]' function translate:init(config) - translate.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('translate', true):t('tl', true).table - translate.doc = [[``` -]]..config.cmd_pat..[[translate [text] -Translates input or the replied-to message into the bot's language. -```]] + translate.triggers = { + "^/translate ([%w]+),([%a]+) (.+)", + "^/translate (to%:)([%w]+) (.+)", + "^/translate (.+)", + "^/getlanguages$", + "^/(whatlang) (.+)" + } + translate.doc = [[* +]]..config.cmd_pat..[[translate* _[Text]_: Übersetze Text in deutsch +*]]..config.cmd_pat..[[translate* to:Zielsprache _[Text]_: Übersetze Text in Zielsprache +*]]..config.cmd_pat..[[translate* Quellsprache,Zielsprache _[Text]_: Übersetze Text von beliebiger Sprache in beliebige Sprache +*]]..config.cmd_pat..[[getlanguages*: Postet alle verfügbaren Sprachcodes +*]]..config.cmd_pat..[[whatlang* _[Text]_: Gibt erkannte Sprache zurück]] end -function translate:action(msg, config) +local bing_key = cred_data.bing_key +local accountkey = mime.b64(bing_key..':'..bing_key) - local input = utilities.input(msg.text) - if not input then - if msg.reply_to_message and msg.reply_to_message.text then - input = msg.reply_to_message.text - else - utilities.send_message(self, msg.chat.id, translate.doc, true, msg.message_id, true) - return - end - end +function translate:translate(source_lang, target_lang, text) + if not target_lang then target_lang = 'de' end + local url = 'https://api.datamarket.azure.com/Bing/MicrosoftTranslator/Translate?$format=json&Text=%27'..URL.escape(text)..'%27&To=%27'..target_lang..'%27&From=%27'..source_lang..'%27' + local response_body = {} + local request_constructor = { + url = url, + method = "GET", + sink = ltn12.sink.table(response_body), + headers = { + Authorization = "Basic "..accountkey + } + } + local ok, response_code, response_headers, response_status_line = https.request(request_constructor) + if not ok or response_code ~= 200 then return 'Ein Fehler ist aufgetreten.' end - local url = 'https://translate.yandex.net/api/v1.5/tr.json/translate?key=' .. config.yandex_key .. '&lang=' .. config.lang .. '&text=' .. URL.escape(input) + local trans = json.decode(table.concat(response_body)).d.results[1].Text - local str, res = HTTPS.request(url) - if res ~= 200 then - utilities.send_reply(self, msg, config.errors.connection) - return - end + return trans +end - local jdat = JSON.decode(str) - if jdat.code ~= 200 then - utilities.send_reply(self, msg, config.errors.connection) - return - end +function translate:detect_language(text) + local url = 'https://api.datamarket.azure.com/Bing/MicrosoftTranslator/Detect?$format=json&Text=%27'..URL.escape(text)..'%27' + local response_body = {} + local request_constructor = { + url = url, + method = "GET", + sink = ltn12.sink.table(response_body), + headers = { + Authorization = "Basic "..accountkey + } + } + local ok, response_code, response_headers, response_status_line = https.request(request_constructor) + if not ok or response_code ~= 200 then return 'en' end + + local language = json.decode(table.concat(response_body)).d.results[1].Code + print('Erkannte Sprache: '..language) + return language +end - local output = jdat.text[1] - output = '*Translation:*\n"' .. utilities.md_escape(output) .. '"' +function translate:get_all_languages() + local url = 'https://api.datamarket.azure.com/Bing/MicrosoftTranslator/GetLanguagesForTranslation?$format=json' + local response_body = {} + local request_constructor = { + url = url, + method = "GET", + sink = ltn12.sink.table(response_body), + headers = { + Authorization = "Basic "..accountkey + } + } + local ok, response_code, response_headers, response_status_line = https.request(request_constructor) + if not ok or response_code ~= 200 then return 'Ein Fehler ist aufgetreten.' end + + local lang_table = json.decode(table.concat(response_body)).d.results + + local languages = "" + for i in pairs(lang_table) do + languages = languages..lang_table[i].Code..'\n' + end + + local link = upload(languages) + return '[Sprachliste auf Paste.ee ansehen]('..link..')' +end - utilities.send_reply(self, msg.reply_to_message or msg, output, true) +function translate:action(msg, config, matches) + utilities.send_typing(self, msg.chat.id, 'typing') + + if matches[1] == '/getlanguages' then + utilities.send_reply(self, msg, translate:get_all_languages(), true) + return + end + + if matches[1] == 'whatlang' and matches[2] then + local text = matches[2] + local lang = translate:detect_language(text) + utilities.send_reply(self, msg, 'Erkannte Sprache: '..lang, true) + return + end + + -- Third pattern + if #matches == 1 then + print("First") + local text = matches[1] + local language = translate:detect_language(text) + utilities.send_reply(self, msg, translate:translate(language, nil, text)) + return + end + + -- Second pattern + if #matches == 3 and matches[1] == "to:" then + print("Second") + local target = matches[2] + local text = matches[3] + local language = translate:detect_language(text) + utilities.send_reply(self, msg, translate:translate(language, target, text)) + return + end + + -- First pattern + if #matches == 3 then + print("Third") + local source = matches[1] + local target = matches[2] + local text = matches[3] + utilities.send_reply(self, msg, translate:translate(source, target, text)) + return + end end diff --git a/otouto/plugins/twitch.lua b/otouto/plugins/twitch.lua new file mode 100644 index 0000000..c28511e --- /dev/null +++ b/otouto/plugins/twitch.lua @@ -0,0 +1,40 @@ +local twitch = {} + +local https = require('ssl.https') +local json = require('dkjson') +local utilities = require('otouto.utilities') + +twitch.triggers = { + "twitch.tv/([A-Za-z0-9-_-]+)" +} + +local BASE_URL = 'https://api.twitch.tv' + +function twitch:send_twitch_info(twitch_name) + local url = BASE_URL..'/kraken/channels/'..twitch_name + local res,code = https.request(url) + if code ~= 200 then return "HTTP-FEHLER" end + local data = json.decode(res) + + local display_name = data.display_name + local name = data.name + if not data.game then + game = 'nichts' + else + game = data.game + end + local status = data.status + local views = comma_value(data.views) + local followers = comma_value(data.followers) + local text = '*'..display_name..'* ('..name..') streamt *'..game..'*\n'..status..'\n_'..views..' Zuschauer insgesamt und '..followers..' Follower_' + + return text +end + +function twitch:action(msg, config, matches) + local text = twitch:send_twitch_info(matches[1]) + if not text then utilities.send_reply(self, msg, config.errors.connection) return end + utilities.send_reply(self, msg, text, true) +end + +return twitch diff --git a/otouto/plugins/urbandictionary.lua b/otouto/plugins/urbandictionary.lua index c206057..39cc10e 100644 --- a/otouto/plugins/urbandictionary.lua +++ b/otouto/plugins/urbandictionary.lua @@ -43,9 +43,9 @@ function urbandictionary:action(msg, config) return end - local output = '*' .. jdat.list[1].word .. '*\n\n' .. utilities.trim(jdat.list[1].definition) + local output = '*' .. jdat.list[1].word .. '*\n' .. utilities.trim(jdat.list[1].definition) if string.len(jdat.list[1].example) > 0 then - output = output .. '_\n\n' .. utilities.trim(jdat.list[1].example) .. '_' + output = output .. '_\n' .. utilities.trim(jdat.list[1].example) .. '_' end output = output:gsub('%[', ''):gsub('%]', '') diff --git a/otouto/plugins/webshot.lua b/otouto/plugins/webshot.lua new file mode 100644 index 0000000..9bf373d --- /dev/null +++ b/otouto/plugins/webshot.lua @@ -0,0 +1,83 @@ +local webshot = {} + +local helpers = require('OAuth.helpers') +local utilities = require('otouto.utilities') +local https = require('ssl.https') +local ltn12 = require('ltn12') +local json = require('dkjson') +local bindings = require('otouto.bindings') + +local base = 'https://screenshotmachine.com/' +local url = base .. 'processor.php' + +function webshot:init(config) + webshot.triggers = { + "^/webshot ([T|t|S|s|E|e|N|n|M|m|L|l|X|x|F|f]) ([%w-_%.%?%.:,/%+=&#!]+)$", + "^/scrot ([T|t|S|s|E|e|N|n|M|m|L|l|X|x|F|f]) ([%w-_%.%?%.:,/%+=&#!]+)$", + "^/webshot ([%w-_%.%?%.:,/%+=&#!]+)$", + "^/scrot ([%w-_%.%?%.:,/%+=&#!]+)$" + } + webshot.doc = [[* +]]..config.cmd_pat..[[scrot* __: Fertigt Bild mit Größe 1024x768 (X) an +*]]..config.cmd_pat..[[scrot* _[T|S|E|N|M|L|X|F]_ __: Fertigt Bild mit bestimmter Größe an (T = tiny, F = full)]] +end + +webshot.command = 'scrot [T|S|E|N|M|L|X|F] ' + +function webshot:get_webshot_url(param, size) + local response_body = {} + local request_constructor = { + url = url, + method = "GET", + sink = ltn12.sink.table(response_body), + headers = { + referer = base, + dnt = "1", + origin = base, + ["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.41 Safari/537.36" + }, + redirect = false + } + + local arguments = { + urlparam = param, + size = size, + cacheLimit = "0" + } + + request_constructor.url = url .. "?" .. helpers.url_encode_arguments(arguments) + + local ok, response_code, response_headers, response_status_line = https.request(request_constructor) + if not ok or response_code ~= 200 then + return nil + end + + local response = table.concat(response_body) + return string.match(response, "href='(.-)'") +end + +function webshot:action(msg, config, matches) + if not matches[2] then + webshot_url = matches[1] + size = "X" + else + webshot_url = matches[2] + size = string.upper(matches[1]) + end + utilities.send_typing(self, msg.chat.id, 'upload_photo') + local find = webshot:get_webshot_url(webshot_url, size) + if find then + local imgurl = base .. find + local file = download_to_file(imgurl) + if size == "F" then + utilities.send_document(self, msg.chat.id, file, nil, msg.message_id) + return + else + utilities.send_photo(self, msg.chat.id, file, nil, msg.message_id) + end + else + utilities.send_reply(self, msg, config.errors.connection) + end +end + +return webshot \ No newline at end of file