From c484023791faba621980c819dc398d708233f03f Mon Sep 17 00:00:00 2001 From: Andreas Bielawski Date: Sun, 19 Jun 2016 19:25:24 +0200 Subject: [PATCH] - Portierung folgender Plugins: + Games + GDrive + Gfycat + Googl + GPS + Hackernews + Hello + Instagram + IP_info + GMaps so angepasst, dass es wie Location funktioniert - Bugfixes, Pattern-Fixes, etc. --- otouto/plugins/9gag.lua | 2 +- otouto/plugins/gMaps.lua | 31 ++++--- otouto/plugins/games.lua | 147 ++++++++++++++++++++++++++++++++++ otouto/plugins/gdrive.lua | 99 +++++++++++++++++++++++ otouto/plugins/gfycat.lua | 36 +++++++++ otouto/plugins/googl.lua | 47 +++++++++++ otouto/plugins/gps.lua | 38 +++++++++ otouto/plugins/hackernews.lua | 90 ++++++++------------- otouto/plugins/hello.lua | 13 +++ otouto/plugins/instagram.lua | 80 ++++++++++++++++++ otouto/plugins/ip_info.lua | 92 +++++++++++++++++++++ 11 files changed, 603 insertions(+), 72 deletions(-) create mode 100644 otouto/plugins/games.lua create mode 100644 otouto/plugins/gdrive.lua create mode 100644 otouto/plugins/gfycat.lua create mode 100644 otouto/plugins/googl.lua create mode 100644 otouto/plugins/gps.lua create mode 100644 otouto/plugins/hello.lua create mode 100644 otouto/plugins/instagram.lua create mode 100644 otouto/plugins/ip_info.lua diff --git a/otouto/plugins/9gag.lua b/otouto/plugins/9gag.lua index e32fda6..15590da 100644 --- a/otouto/plugins/9gag.lua +++ b/otouto/plugins/9gag.lua @@ -34,7 +34,7 @@ function ninegag:action(msg, config) end local file = download_to_file(url) - utilities.send_photo(self, msg.chat.id, file, title) + utilities.send_photo(self, msg.chat.id, file, title, msg.message_id) end return ninegag diff --git a/otouto/plugins/gMaps.lua b/otouto/plugins/gMaps.lua index d3719e9..ccce85b 100644 --- a/otouto/plugins/gMaps.lua +++ b/otouto/plugins/gMaps.lua @@ -1,21 +1,25 @@ local gMaps = {} -local bindings = require('otouto.bindings') +local URL = require('socket.url') local utilities = require('otouto.utilities') -gMaps.command = 'location ' +gMaps.command = 'loc ' function gMaps:init(config) gMaps.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('location', true):t('loc', true).table - gMaps.doc = [[``` -]]..config.cmd_pat..[[location -Returns a location from Google Maps. -Alias: ]]..config.cmd_pat..[[loc -```]] + gMaps.doc = [[* +]]..config.cmd_pat..[[loc* __: Sendet Ort via Google Maps]] +end + +function gMaps:get_staticmap(area, lat, lon) + local base_api = "https://maps.googleapis.com/maps/api" + local url = base_api .. "/staticmap?size=600x300&zoom=12¢er="..URL.escape(area).."&markers=color:red"..URL.escape("|"..area) + + local file = download_to_file(url) + return file end function gMaps:action(msg, config) - local input = utilities.input(msg.text) if not input then if msg.reply_to_message and msg.reply_to_message.text then @@ -25,20 +29,15 @@ function gMaps:action(msg, config) return end end - + utilities.send_typing(self, msg.chat.id, 'find_location') local coords = utilities.get_coords(input, config) if type(coords) == 'string' then utilities.send_reply(self, msg, coords) return end - bindings.sendLocation(self, { - chat_id = msg.chat.id, - latitude = coords.lat, - longitude = coords.lon, - reply_to_message_id = msg.message_id - } ) - + utilities.send_location(self, msg.chat.id, coords.lat, coords.lon, msg.message_id) + utilities.send_photo(self, msg.chat.id, gMaps:get_staticmap(input, coords.lat, coords.lon), nil, msg.message_id) end return gMaps diff --git a/otouto/plugins/games.lua b/otouto/plugins/games.lua new file mode 100644 index 0000000..61841bd --- /dev/null +++ b/otouto/plugins/games.lua @@ -0,0 +1,147 @@ +local games = {} + +local http = require('socket.http') +local URL = require('socket.url') +local xml = require("xml") +local utilities = require('otouto.utilities') +local bindings = require('otouto.bindings') + +games.command = 'game ' + +function games:init(config) + games.triggers = { + "^/game (.+)$" + } + games.doc = [[* +]]..config.cmd_pat..[[game*_ _: Sendet Infos zum Spiel]] +end + +local BASE_URL = 'http://thegamesdb.net/api' + +local makeOurDate = function(dateString) + local pattern = "(%d+)%/(%d+)%/(%d+)" + local month, day, year = dateString:match(pattern) + return day..'.'..month..'.'..year +end + + +function games:get_game_id(game) + local url = BASE_URL..'/GetGamesList.php?name='..game + local res,code = http.request(url) + if code ~= 200 then return "HTTP-FEHLER" end + local result = xml.load(res) + if xml.find(result, 'id') then + local game = xml.find(result, 'id')[1] + return game + else + return nil + end +end + +function games:send_game_photo(result, self, msg) + local BASE_URL = xml.find(result, 'baseImgUrl')[1] + local images = {} + + if xml.find(result, 'fanart') then + local fanart = xml.find(result, 'fanart')[1] + local fanrt_url = BASE_URL..fanart[1] + table.insert(images, fanrt_url) + end + + if xml.find(result, 'boxart', 'side', 'front') then + local boxart = xml.find(result, 'boxart', 'side', 'front')[1] + local boxart_url = BASE_URL..boxart + table.insert(images, boxart_url) + end + + local i = 0 + for k, v in pairs(images) do + i = i+1 + local file = download_to_file(v, 'game'..i..'.jpg') + utilities.send_photo(self, msg.chat.id, file, nil, msg.message_id) + end +end + +function games:send_game_data(game_id, self, msg) + local url = BASE_URL..'/GetGame.php?id='..game_id + local res,code = http.request(url) + if code ~= 200 then return nil end + local result = xml.load(res) + + local title = xml.find(result, 'GameTitle')[1] + local platform = xml.find(result, 'Platform')[1] + + if xml.find(result, 'ReleaseDate') then + date = ', erschienen am '..makeOurDate(xml.find(result, 'ReleaseDate')[1]) + else + date = '' + end + + if xml.find(result, 'Overview') then + desc = '\n_'..string.sub(xml.find(result, 'Overview')[1], 1, 200) .. '..._' + else + desc = '' + end + + if xml.find(result, 'Genres') then + local genres = xml.find(result, 'Genres') + local genre_count = tablelength(genres)-1 + if genre_count == 1 then + genre = '\nGenre: '..genres[1][1] + else + local genre_loop = '\nGenres: ' + for v in pairs(genres) do + if v == 'xml' then break; end + if v < genre_count then + genre_loop = genre_loop..genres[v][1]..', ' + else + genre_loop = genre_loop..genres[v][1] + end + end + genre = genre_loop + end + else + genre = '' + end + + if xml.find(result, 'Players') then + players = '\nSpieler: '..xml.find(result, 'Players')[1] + else + players = '' + end + + if xml.find(result, 'Youtube') then + video = '\n[Video auf YouTube ansehen]('..xml.find(result, 'Youtube')[1]..')' + else + video = '' + end + + if xml.find(result, 'Publisher') then + publisher = '\nPublisher: '..xml.find(result, 'Publisher')[1] + else + publisher = '' + end + + local text = '*'..title..'* für *'..platform..'*'..date..desc..genre..players..video..publisher + utilities.send_reply(self, msg, text, true) + + if xml.find(result, 'fanrt') or xml.find(result, 'boxart') then + utilities.send_typing(self, msg.chat.id, 'upload_photo') + games:send_game_photo(result, self, msg) + end + return +end + + +function games:action(msg, config, matches) + local game = URL.escape(matches[1]) + local game_id = games:get_game_id(game) + if not game_id then + utilities.send_reply(self, msg, 'Spiel nicht gefunden!') + return + else + games:send_game_data(game_id, self, msg) + end +end + +return games diff --git a/otouto/plugins/gdrive.lua b/otouto/plugins/gdrive.lua new file mode 100644 index 0000000..1ddb00b --- /dev/null +++ b/otouto/plugins/gdrive.lua @@ -0,0 +1,99 @@ +local gdrive = {} + +local utilities = require('otouto.utilities') +local https = require('ssl.https') +local ltn12 = require('ltn12') +local json = require('dkjson') +local bindings = require('otouto.bindings') + +function gdrive:init(config) + if not cred_data.google_apikey then + print('Missing config value: google_apikey.') + print('gdrive.lua will not be enabled.') + return + end + + gdrive.triggers = { + "docs.google.com/(.*)/d/([A-Za-z0-9-_-]+)", + "drive.google.com/(.*)/d/([A-Za-z0-9-_-]+)", + "drive.google.com/(open)%?id=([A-Za-z0-9-_-]+)" + } +end + +local apikey = cred_data.google_apikey + +local BASE_URL = 'https://www.googleapis.com/drive/v2' + +function gdrive:get_drive_document_data (docid) + local apikey = cred_data.google_apikey + local url = BASE_URL..'/files/'..docid..'?key='..apikey..'&fields=id,title,mimeType,ownerNames,exportLinks,fileExtension' + local res,code = https.request(url) + local res = string.gsub(res, 'image/', '') + local res = string.gsub(res, 'application/', '') + if code ~= 200 then return nil end + local data = json.decode(res) + return data +end + +function gdrive:send_drive_document_data(data, self, msg) + local title = data.title + local mimetype = data.mimeType + local id = data.id + local owner = data.ownerNames[1] + local text = '"'..title..'", freigegeben von '..owner + if data.exportLinks then + if data.exportLinks.png then + local image_url = data.exportLinks.png + utilities.send_typing(self, msg.chat.id, 'upload_photo') + local file = download_to_file(image_url) + utilities.send_photo(self, msg.chat.id, file, text, msg.message_id) + return + else + local pdf_url = data.exportLinks.pdf + utilities.send_typing(self, msg.chat.id, 'upload_document') + local file = download_to_file(pdf_url) + utilities.send_document(self, msg.chat.id, file, text, msg.message_id) + return + end + else + local get_file_url = 'https://drive.google.com/uc?id='..id + local ext = data.fileExtension + if mimetype == "png" or mimetype == "jpg" or mimetype == "jpeg" or mimetype == "gif" or mimetype == "webp" then + local respbody = {} + local options = { + url = get_file_url, + sink = ltn12.sink.table(respbody), + redirect = false + } + local response = {https.request(options)} -- luasec doesn't support 302 redirects, so we must contact gdrive again + local code = response[2] + local headers = response[3] + local file_url = headers.location + if ext == "jpg" or ext == "jpeg" or ext == "png" then + utilities.send_typing(self, msg.chat.id, 'upload_photo') + local file = download_to_file(file_url) + utilities.send_photo(self, msg.chat.id, file, text, msg.message_id) + return + else + utilities.send_typing(self, msg.chat.id, 'upload_document') + local file = download_to_file(file_url) + utilities.send_document(self, msg.chat.id, file, text, msg.message_id) + return + end + else + local text = '*'..title..'*, freigegeben von _'..owner..'_\n[Direktlink]('..get_file_url..')' + utilities.send_reply(self, msg, text, true) + return + end + end +end + +function gdrive:action(msg, config, matches) + local docid = matches[2] + local data = gdrive:get_drive_document_data(docid) + if not data then utilities.send_reply(self, msg, config.errors.connection) return end + gdrive:send_drive_document_data(data, self, msg) + return +end + +return gdrive \ No newline at end of file diff --git a/otouto/plugins/gfycat.lua b/otouto/plugins/gfycat.lua new file mode 100644 index 0000000..0793355 --- /dev/null +++ b/otouto/plugins/gfycat.lua @@ -0,0 +1,36 @@ +-- Thanks to Akamaru for the API entrypoints and the initial idea + +local gfycat = {} + +local https = require('ssl.https') +local json = require('dkjson') +local utilities = require('otouto.utilities') + +gfycat.triggers = { + "gfycat.com/([A-Za-z0-9-_-]+)" +} + +function gfycat:send_gfycat_video(name, self, msg) + local BASE_URL = "https://gfycat.com" + local url = BASE_URL..'/cajax/get/'..name + local res,code = https.request(url) + if code ~= 200 then return "HTTP-FEHLER" end + local data = json.decode(res).gfyItem + utilities.send_typing(self, msg.chat.id, 'upload_video') + local file = download_to_file(data.webmUrl) + if file == nil then + send_reply(self, msg, 'Fehler beim Herunterladen von '..name) + return + else + utilities.send_video(self, msg.chat.id, file, nil, msg.message_id) + return + end +end + +function gfycat:action(msg, config, matches) + local name = matches[1] + gfycat:send_gfycat_video(name, self, msg) + return +end + +return gfycat diff --git a/otouto/plugins/googl.lua b/otouto/plugins/googl.lua new file mode 100644 index 0000000..802fa27 --- /dev/null +++ b/otouto/plugins/googl.lua @@ -0,0 +1,47 @@ +local googl = {} + +local https = require('ssl.https') +local json = require('dkjson') +local utilities = require('otouto.utilities') + +function googl:init(config) + if not cred_data.google_apikey then + print('Missing config value: google_apikey.') + print('googl.lua will not be enabled.') + return + end + + googl.triggers = { + "goo.gl/([A-Za-z0-9-_-/-/]+)" + } +end + +local BASE_URL = 'https://www.googleapis.com/urlshortener/v1' + +local makeOurDate = function(dateString) + local pattern = "(%d+)%-(%d+)%-(%d+)" + local year, month, day = dateString:match(pattern) + return day..'.'..month..'.'..year +end + +function googl:send_googl_info (shorturl) + local apikey = cred_data.google_apikey + local url = BASE_URL..'/url?key='..apikey..'&shortUrl=http://goo.gl/'..shorturl..'&projection=FULL&fields=longUrl,created,analytics(allTime(shortUrlClicks))' + local res,code = https.request(url) + if code ~= 200 then return "HTTP-FEHLER" end + local data = json.decode(res) + + local longUrl = data.longUrl + local shortUrlClicks = data.analytics.allTime.shortUrlClicks + local created = makeOurDate(data.created) + local text = longUrl..'\n'..shortUrlClicks..' mal geklickt (erstellt am '..created..')' + + return text +end + +function googl:action(msg, config, matches) + local shorturl = matches[1] + utilities.send_reply(self, msg, googl:send_googl_info(shorturl)) +end + +return googl diff --git a/otouto/plugins/gps.lua b/otouto/plugins/gps.lua new file mode 100644 index 0000000..cb958a1 --- /dev/null +++ b/otouto/plugins/gps.lua @@ -0,0 +1,38 @@ +local gps = {} + +local utilities = require('otouto.utilities') +local bindings = require('otouto.bindings') + +gps.command = 'gps ,' + +function gps:init(config) + gps.triggers = { + "^/gps ([^,]*)[,%s]([^,]*)$", + "google.de/maps/@([^,]*)[,%s]([^,]*)", + "google.com/maps/@([^,]*)[,%s]([^,]*)", + "google.de/maps/place/@([^,]*)[,%s]([^,]*)", + "google.com/maps/place/@([^,]*)[,%s]([^,]*)" + } + gps.doc = [[* +]]..config.cmd_pat..[[gps* __,__: Sendet Karte mit diesen Koordinaten]] +end + +function gps:action(msg, config, matches) + utilities.send_typing(self, msg.chat.id, 'upload_photo') + local lat = matches[1] + local lon = matches[2] + + local zooms = {16, 18} + + local urls = {} + for i in ipairs(zooms) do + local zoom = zooms[i] + local url = "https://maps.googleapis.com/maps/api/staticmap?zoom=" .. zoom .. "&size=600x300&maptype=hybrid¢er=" .. lat .. "," .. lon .. "&markers=color:red%7Clabel:•%7C" .. lat .. "," .. lon + local file = download_to_file(url, 'zoom_'..i..'.png') + utilities.send_photo(self, msg.chat.id, file, nil, msg.message_id) + end + + utilities.send_location(self, msg.chat.id, lat, lon, msg.message_id) +end + +return gps diff --git a/otouto/plugins/hackernews.lua b/otouto/plugins/hackernews.lua index b0a9f69..4da99c0 100644 --- a/otouto/plugins/hackernews.lua +++ b/otouto/plugins/hackernews.lua @@ -1,65 +1,45 @@ local hackernews = {} -local HTTPS = require('ssl.https') -local JSON = require('dkjson') -local bindings = require('otouto.bindings') +local https = require('ssl.https') +local json = require('dkjson') +local URL = require('socket.url') local utilities = require('otouto.utilities') -hackernews.command = 'hackernews' +hackernews.triggers = { + "news.ycombinator.com/item%?id=(%d+)" +} -function hackernews:init(config) - hackernews.triggers = utilities.triggers(self.info.username, config.cmd_pat):t('hackernews', true):t('hn', true).table - hackernews.doc = [[``` -Returns four (if group) or eight (if private message) top stories from Hacker News. -Alias: ]]..config.cmd_pat..[[hn -```]] +local BASE_URL = 'https://hacker-news.firebaseio.com/v0' + +function hackernews:send_hackernews_post (hn_code) + local url = BASE_URL..'/item/'..hn_code..'.json' + local res,code = https.request(url) + if code ~= 200 then return "HTTP-FEHLER" end + local data = json.decode(res) + + local by = data.by + local title = data.title + + if data.url then + url = '\n[Link besuchen]('..data.url..')' + else + url = '' + end + + if data.text then + post = '\n'..unescape_html(data.text) + post = string.gsub(post, '

', ' ') + else + post = '' + end + local text = '*'..title..'* von _'..by..'_'..post..url + + return text end -function hackernews:action(msg, config) - - bindings.sendChatAction(self, { chat_id = msg.chat.id, action = 'typing' } ) - - local jstr, res = HTTPS.request('https://hacker-news.firebaseio.com/v0/topstories.json') - if res ~= 200 then - utilities.send_reply(self, msg, config.errors.connection) - return - end - - local jdat = JSON.decode(jstr) - - local res_count = 4 - if msg.chat.id == msg.from.id then - res_count = 8 - end - - local output = '*Hacker News:*\n' - for i = 1, res_count do - local res_url = 'https://hacker-news.firebaseio.com/v0/item/' .. jdat[i] .. '.json' - jstr, res = HTTPS.request(res_url) - if res ~= 200 then - utilities.send_reply(self, msg, config.errors.connection) - return - end - local res_jdat = JSON.decode(jstr) - local title = res_jdat.title:gsub('%[.+%]', ''):gsub('%(.+%)', ''):gsub('&', '&') - if title:len() > 48 then - title = title:sub(1, 45) .. '...' - end - local url = res_jdat.url - if not url then - utilities.send_reply(self, msg, config.errors.connection) - return - end - if url:find('%(') then - output = output .. '• ' .. title .. '\n' .. url:gsub('_', '\\_') .. '\n' - else - output = output .. '• [' .. title .. '](' .. url .. ')\n' - end - - end - - utilities.send_message(self, msg.chat.id, output, true, nil, true) - +function hackernews:action(msg, config, matches) + local hn_code = matches[1] + utilities.send_reply(self, msg, hackernews:send_hackernews_post(hn_code), true) end return hackernews diff --git a/otouto/plugins/hello.lua b/otouto/plugins/hello.lua new file mode 100644 index 0000000..bdc10b0 --- /dev/null +++ b/otouto/plugins/hello.lua @@ -0,0 +1,13 @@ +local hello = {} + +local utilities = require('otouto.utilities') + +hello.triggers = { + "^[Ss][Aa][Gg] [Hh][Aa][Ll][Ll][Oo] [Zz][Uu] (.*)$" +} + +function hello:action(msg, config, matches) + utilities.send_reply(self, msg, 'Hallo, '..matches[1]..'!') +end + +return hello diff --git a/otouto/plugins/instagram.lua b/otouto/plugins/instagram.lua new file mode 100644 index 0000000..97d905b --- /dev/null +++ b/otouto/plugins/instagram.lua @@ -0,0 +1,80 @@ +local instagram = {} + +local https = require('ssl.https') +local json = require('dkjson') +local URL = require('socket.url') +local utilities = require('otouto.utilities') + +function instagram:init(config) + if not cred_data.instagram_access_token then + print('Missing config value: instagram_access_token.') + print('instagram.lua will not be enabled.') + return + end + + instagram.triggers = { + "instagram.com/p/([A-Za-z0-9-_-]+)" + } +end + +local BASE_URL = 'https://api.instagram.com/v1' +local access_token = cred_data.instagram_access_token + +function instagram:get_insta_data(insta_code) + local url = BASE_URL..'/media/shortcode/'..insta_code..'?access_token='..access_token + local res,code = https.request(url) + if code ~= 200 then return nil end + local data = json.decode(res).data + return data +end + +function instagram:send_instagram_data(data) + -- Header + local username = data.user.username + local full_name = data.user.full_name + if username == full_name then + header = full_name..' hat ein' + else + header = full_name..' ('..username..') hat ein' + end + if data.type == 'video' then + header = header..' Video gepostet' + else + header = header..' Foto gepostet' + end + + -- Caption + if data.caption == nil then + caption = '' + else + caption = ':\n'..data.caption.text + end + + -- Footer + local comments = comma_value(data.comments.count) + local likes = comma_value(data.likes.count) + local footer = '\n'..likes..' Likes, '..comments..' Kommentare' + if data.type == 'video' then + footer = '\n'..data.videos.standard_resolution.url..footer + end + + -- Image + local image_url = data.images.standard_resolution.url + + return header..caption..footer, image_url +end + +function instagram:action(msg, config, matches) + local insta_code = matches[1] + local data = instagram:get_insta_data(insta_code) + if not data then utilities.send_reply(self, msg, config.errors.connection) return end + + local text, image_url = instagram:send_instagram_data(data) + if not image_url then utilities.send_reply(self, msg, config.errors.connection) return end + + utilities.send_typing(self, msg.chat.id, 'upload_photo') + local file = download_to_file(image_url) + utilities.send_photo(self, msg.chat.id, file, text, msg.message_id) +end + +return instagram diff --git a/otouto/plugins/ip_info.lua b/otouto/plugins/ip_info.lua new file mode 100644 index 0000000..df948e7 --- /dev/null +++ b/otouto/plugins/ip_info.lua @@ -0,0 +1,92 @@ +local ip_info = {} + +local http = require('socket.http') +local json = require('dkjson') +local URL = require('socket.url') +local utilities = require('otouto.utilities') + +function ip_info:init(config) + ip_info.triggers = { + "^/ip (.*)$", + "^/dns (.*)$" + } + + ip_info.doc = [[* +]]..config.cmd_pat..[[ip* __: Sendet Infos zu dieser IP]] +end + +ip_info.command = 'ip ' + +local BASE_URL = 'http://ip-api.com/json' + +function ip_info:get_host_data(host) + local url = BASE_URL..'/'..host..'?lang=de&fields=country,regionName,city,zip,lat,lon,isp,org,as,status,message,reverse,query' + local res,code = http.request(url) + if code ~= 200 then return "HTTP-FEHLER: "..code end + local data = json.decode(res) + if data.status == 'fail' then + return nil + end + + local isp = data.isp + + local url + if data.lat and data.lon then + lat = tostring(data.lat) + lon = tostring(data.lon) + url = "https://maps.googleapis.com/maps/api/staticmap?zoom=16&size=600x300&maptype=hybrid¢er="..lat..","..lon.."&markers=color:red%7Clabel:•%7C"..lat..","..lon + end + + if data.query == host then + query = '' + else + query = ' / '..data.query + end + + if data.reverse ~= "" and data.reverse ~= host then + host_addr = ' ('..data.reverse..')' + else + host_addr = '' + end + + -- Location + if data.zip ~= "" then + zipcode = data.zip..' ' + else + zipcode = '' + end + + local city = data.city + + if data.regionName ~= "" then + region = ', '..data.regionName + else + region = '' + end + + if data.country ~= "" then + country = ', '..data.country + else + country = '' + end + + local text = host..query..host_addr..' ist bei '..isp..':\n' + local location = zipcode..city..region..country + return text..location, url +end + +function ip_info:action(msg, config, matches) + local host = matches[1] + local text, image_url = ip_info:get_host_data(host) + if not text then utilities.send_reply(self, msg, config.errors.connection) return end + + if image_url then + utilities.send_typing(self, msg.chat.id, 'upload_photo') + local file = download_to_file(image_url) + utilities.send_photo(self, msg.chat.id, file, text, msg.message_id) + else + utilities.send_reply(self, msg, text) + end +end + +return ip_info