From 90428735d3de689e5a174c9e08900c4905e36a2a Mon Sep 17 00:00:00 2001 From: Akamaru Date: Sat, 9 May 2015 16:34:53 +0200 Subject: [PATCH] added new plugins date.lua get.lua invite.lua location.lua set.lua time.lua twitter.lua weather.lua youtube.lua --- .gitignore | 15 ++++++- plugins/date.lua | 11 +++++ plugins/get.lua | 80 +++++++++++++++++++++++++++++++++++ plugins/invite.lua | 42 +++++++++++++++++++ plugins/location.lua | 60 +++++++++++++++++++++++++++ plugins/set.lua | 30 ++++++++++++++ plugins/time.lua | 99 ++++++++++++++++++++++++++++++++++++++++++++ plugins/twitter.lua | 76 ++++++++++++++++++++++++++++++++++ plugins/weather.lua | 60 +++++++++++++++++++++++++++ plugins/youtube.lua | 44 ++++++++++++++++++++ 10 files changed, 516 insertions(+), 1 deletion(-) create mode 100644 plugins/date.lua create mode 100644 plugins/get.lua create mode 100644 plugins/invite.lua create mode 100644 plugins/location.lua create mode 100644 plugins/set.lua create mode 100644 plugins/time.lua create mode 100644 plugins/twitter.lua create mode 100644 plugins/weather.lua create mode 100644 plugins/youtube.lua diff --git a/.gitignore b/.gitignore index 1d4ff79..d76a86b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,17 @@ plugins/create_sticker.lua plugins/derpibooru_nsfw.lua plugins/derpibooru.lua plugins/rss.lua -plugins/meme.lua \ No newline at end of file +plugins/meme.lua +plugins/app_store.lua +plugins/bitly_create.lua +plugins/dailymotion.lua +plugins/dns.lua +plugins/gdrive.lua +plugins/instagram.lua +plugins/play_store.lua +plugins/reddit.lua +plugins/soundcloud.lua +plugins/spotify.lua +plugins/vimeo.lua +plugins/vine.lua +plugins/youtube_playlist.lua \ No newline at end of file diff --git a/plugins/date.lua b/plugins/date.lua new file mode 100644 index 0000000..539b374 --- /dev/null +++ b/plugins/date.lua @@ -0,0 +1,11 @@ + +function run(msg, matches) + return os.date("%d.%m.%Y") +end + +return { + description = "Zeigt das aktuelle Datum an", + usage = "/date", + patterns = {"^/date$"}, + run = run +} diff --git a/plugins/get.lua b/plugins/get.lua new file mode 100644 index 0000000..6510029 --- /dev/null +++ b/plugins/get.lua @@ -0,0 +1,80 @@ +local _file_values = './data/values.lua' + +_values = load_from_file(_file_values) + +local function fetch_value(chat, value_name) + -- Chat non exists + if _values[chat] == nil then + return nil + end + + if value_name == nil then + return nil + end + + local value = _values[chat][value_name] + return value +end + +local function get_value(chat, value_name) + + -- If chat values is empty + if (_values[chat] == nil) then + return "Hier sind keine Daten" + end + + -- If there is not value name, return all the values. + if (value_name == nil ) then + local text = "" + for key,value in pairs(_values[chat]) do + text = text..key.." = "..value.."\n" + end + return text + end + local value = _values[chat][value_name] + if ( value == nil) then + return "Konnte nicht finden "..value_name + end + return value_name.." = "..value +end + +local function run(msg, matches) + local chat_id = tostring(msg.to.id) + if matches[1] == "!get" then + return get_value(chat_id, nil) + end + return get_value(chat_id, matches[1]) +end + +local function lex(msg) + + if msg.text then + local text = msg.text + local chat_id = tostring(msg.to.id) + local s, e = text:find("%$%a+") + + if s then + local var = text:sub(s + 1, e) + local value = fetch_value(chat_id, var) + + if (value == nil) then + value = "(Unbekannter Wert " .. var .. ")" + end + + msg.text = text:sub(0, s - 1) .. value .. text:sub(e + 1) + end + end + + return msg +end + +return { + description = "Bekommt Variable, die mit !set gesetzt wurde", + usage = "/get (Variable)", + patterns = { + "^/get (%a+)$", + "^/get$"}, + run = run, + pre_process = lex +} + diff --git a/plugins/invite.lua b/plugins/invite.lua new file mode 100644 index 0000000..673f3c8 --- /dev/null +++ b/plugins/invite.lua @@ -0,0 +1,42 @@ +-- Invite other user to the chat group. +-- Use !invite name User_name or !invite id id_number +-- The User_name is the print_name (there are no spaces but _) + +do + +local function run(msg, matches) + -- User submitted a user name + if matches[1] == "name" then + user = matches[2] + user = string.gsub(user," ","_") + end + -- User submitted an id + if matches[1] == "id" then + user = matches[2] + user = 'user#id'..user + end + -- The message must come from a chat group + if msg.to.type == 'chat' then + chat = 'chat#id'..msg.to.id + else + return 'Dies ist keine Gruppe!!' + end + print ("Füge "..user.." zu "..chat.." hinzu") + status = chat_add_user (chat, user, ok_cb, false) + if not status then + return "Ein Fehler ist aufgetreten" + end + return "User "..user.." zu "..chat.." hinzugefügt!" +end + +return { + description = "Andere User zu einer Chat-Gruppe hinzufügen", + usage = "/invite name [user_name], !invite id [user_id]", + patterns = { + "^/invite (name) (.*)$", + "^/invite (id) (%d+)$" + }, + run = run +} + +end diff --git a/plugins/location.lua b/plugins/location.lua new file mode 100644 index 0000000..1d16676 --- /dev/null +++ b/plugins/location.lua @@ -0,0 +1,60 @@ +-- Implement a command !loc [area] which uses +-- the static map API to get a location image + +-- Not sure if this is the proper way +-- Intent: get_latlong is in time.lua, we need it here +-- loadfile "time.lua" + +-- Globals +-- If you have a google api key for the geocoding/timezone api +do + +local api_key = nil +local base_api = "https://maps.googleapis.com/maps/api" + +function get_staticmap(area) + local api = base_api .. "/staticmap?" + + -- Get a sense of scale + local lat,lng,acc,types = get_latlong(area) + + local scale = types[1] + if scale=="locality" then zoom=8 + elseif scale=="country" then zoom=4 + else zoom = 13 end + + local parameters = + "size=600x300" .. + "&zoom=" .. zoom .. + "¢er=" .. URL.escape(area) .. + "&markers=color:red"..URL.escape("|"..area) + + if api_key ~=nil and api_key ~= "" then + parameters = parameters .. "&key="..api_key + end + return lat, lng, api..parameters +end + + +function run(msg, matches) + local receiver = get_receiver(msg) + local lat,lng,url = get_staticmap(matches[1]) + + -- Send the actual location, is a google maps link + send_location(receiver, lat, lng, ok_cb, false) + + -- Send a picture of the map, which takes scale into account + send_photo_from_url(receiver, url) + + -- Return a link to the google maps stuff is now not needed anymore + return nil +end + +return { + description = "Zeigt Informationen über einen Ort.", + usage = "/loc (Ort)", + patterns = {"^/loc (.*)$"}, + run = run +} + +end diff --git a/plugins/set.lua b/plugins/set.lua new file mode 100644 index 0000000..b5610dc --- /dev/null +++ b/plugins/set.lua @@ -0,0 +1,30 @@ +local _file_values = './data/values.lua' + +local function save_value(chat, text ) + var_name, var_value = string.match(text, "!set (%a+) (.+)") + if (var_name == nil or var_value == nil) then + return "Benutzung: /set var_name value" + end + if _values[chat] == nil then + _values[chat] = {} + end + _values[chat][var_name] = var_value + + -- Save values to file + serialize_to_file(_values, _file_values) + + return "Gespeichert: "..var_name.." = "..var_value +end + +local function run(msg, matches) + local chat_id = tostring(msg.to.id) + local text = save_value(chat_id, msg.text) + return text +end + +return { + description = "Setze Variable", + usage = "/set [Variablenname] [Daten]", + patterns = {"^/set (%a+) (.+)$"}, + run = run +} diff --git a/plugins/time.lua b/plugins/time.lua new file mode 100644 index 0000000..9d62ec8 --- /dev/null +++ b/plugins/time.lua @@ -0,0 +1,99 @@ +-- Implement a command !time [area] which uses +-- 2 Google APIs to get the desired result: +-- 1. Geocoding to get from area to a lat/long pair +-- 2. Timezone to get the local time in that lat/long location + +-- Globals +-- If you have a google api key for the geocoding/timezone api +api_key = nil +base_api = "https://maps.googleapis.com/maps/api" +dateFormat = "%A, %d. %B - %H:%M:%S" + +-- Need the utc time for the google api +function utctime() + return os.time(os.date("!*t")) +end + +-- Use the geocoding api to get the lattitude and longitude with accuracy specifier +-- CHECKME: this seems to work without a key?? +function get_latlong(area) + local api = base_api .. "/geocode/json?" + local parameters = "address=".. (URL.escape(area) or "") + if api_key ~= nil then + parameters = parameters .. "&key="..api_key + end + + -- Do the request + local res, code = https.request(api..parameters) + if code ~=200 then return nil end + local data = json:decode(res) + + if (data.status == "ZERO_RESULTS") then + return nil + end + if (data.status == "OK") then + -- Get the data + lat = data.results[1].geometry.location.lat + lng = data.results[1].geometry.location.lng + acc = data.results[1].geometry.location_type + types= data.results[1].types + return lat,lng,acc,types + end +end + +-- Use timezone api to get the time in the lat, +-- Note: this needs an API key +function get_time(lat,lng) + local api = base_api .. "/timezone/json?" + + -- Get a timestamp (server time is relevant here) + local timestamp = utctime() + local parameters = "location=" .. + URL.escape(lat) .. "," .. + URL.escape(lng) .. + "×tamp="..URL.escape(timestamp) + if api_key ~=nil then + parameters = parameters .. "&key="..api_key + end + + local res,code = https.request(api..parameters) + if code ~= 200 then return nil end + local data = json:decode(res) + + if (data.status == "ZERO_RESULTS") then + return nil + end + if (data.status == "OK") then + -- Construct what we want + -- The local time in the location is: + -- timestamp + rawOffset + dstOffset + local localTime = timestamp + data.rawOffset + data.dstOffset + return localTime, data.timeZoneId + end + return localTime +end + +function getformattedLocalTime(area) + if area == nil then + return "Die Zeit nirgendswo ist nirgendswo..." + end + + lat,lng,acc = get_latlong(area) + if lat == nil and lng == nil then + return 'Sieht nicht so aus, als hätten sie in "'..area..'" eine Zeit.' + end + local localTime, timeZoneId = get_time(lat,lng) + + return "Die lokale Zeit in "..timeZoneId.." ist: ".. os.date(dateFormat,localTime) +end + +function run(msg, matches) + return getformattedLocalTime(matches[1]) +end + +return { + description = "Zeigt die lokale Zeit in einer Zeitzone an", + usage = "/zeit [Land/Ort]", + patterns = {"^/zeit (.*)$","^/Zeit (.*)$"}, + run = run +} diff --git a/plugins/twitter.lua b/plugins/twitter.lua new file mode 100644 index 0000000..72baaa2 --- /dev/null +++ b/plugins/twitter.lua @@ -0,0 +1,76 @@ +local OAuth = require "OAuth" + +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 run(msg, matches) + + if consumer_key:isempty() then + return "Twitter Consumer Key is empty, write it in plugins/twitter.lua" + end + if consumer_secret:isempty() then + return "Twitter Consumer Secret is empty, write it in plugins/twitter.lua" + end + if access_token:isempty() then + return "Twitter Access Token is empty, write it in plugins/twitter.lua" + end + if access_token_secret:isempty() then + return "Twitter Access Token Secret is empty, write it in plugins/twitter.lua" + end + + local twitter_url = "https://api.twitter.com/1.1/statuses/show/" .. matches[1] .. ".json" + local response_code, response_headers, response_status_line, response_body = client:PerformRequest("GET", twitter_url) + local response = json:decode(response_body) + + local header = "Tweet von " .. response.user.name .. " (@" .. response.user.screen_name .. ")\n" + local text = response.text + + -- replace short URLs + if response.entities.url 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 = {} + 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 + text = text:gsub(url, "") + table.insert(images, pic) + end + end + + -- send the parts + local receiver = get_receiver(msg) + send_msg(receiver, header .. "\n" .. text, ok_cb, false) + for k, v in pairs(images) do + local file = download_to_file(v) + send_photo(receiver, file, ok_cb, false) + delay_s(1) + end + + return nil +end + +return { + description = "When user sends twitter URL, send text and images to origin. Requieres OAuth Key.", + usage = "", + patterns = {"https://twitter.com/[^/]+/status/([0-9]+)"}, + run = run +} diff --git a/plugins/weather.lua b/plugins/weather.lua new file mode 100644 index 0000000..9c02b4e --- /dev/null +++ b/plugins/weather.lua @@ -0,0 +1,60 @@ +do + +local BASE_URL = "http://api.openweathermap.org/data/2.5/weather" + + +local function get_weather(location) + print("Finde Wetter in ", location) + local url = BASE_URL + url = url..'?q='..location + url = url..'&lang=de&units=metric' + + local b, c, h = http.request(url) + if c ~= 200 then return nil end + + local weather = json:decode(b) + local city = weather.name + local country = weather.sys.country + local dot_temperature = round(weather.main.temp, 2) + local temperature = string.gsub(dot_temperature, "%.", "%,") + local temp = 'Die Temperatur in '..city + ..' (' ..country..')' + ..' beträgt '..temperature..'°C' + local conditions = 'Die aktuelle Wetterlage ist: ' + .. weather.weather[1].description + + if weather.weather[1].main == 'Clear' then + conditions = conditions .. ' ☀' + elseif weather.weather[1].main == 'Clouds' then + conditions = conditions .. ' ☁☁' + elseif weather.weather[1].main == 'Rain' then + conditions = conditions .. ' ☔' + elseif weather.weather[1].main == 'Thunderstorm' then + conditions = conditions .. ' ☔☔☔☔' + end + return temp .. '\n' .. conditions +end + +local function run(msg, matches) + local city = 'Berlin' + + if matches[1] ~= '/wetter' then + city = matches[1] + end + local text = get_weather(city) + if not text then + text = 'Konnte das Wetter von dieser Stadt nicht bekommen.' + end + return text +end + +return { + description = "Wetter in dieser Stadt (Berlin ist Standard)", + usage = "/wetter (Stadt)", + patterns = { + "^/wetter$", + "^/wetter(.*)$"}, + run = run +} + +end diff --git a/plugins/youtube.lua b/plugins/youtube.lua new file mode 100644 index 0000000..f33c3c1 --- /dev/null +++ b/plugins/youtube.lua @@ -0,0 +1,44 @@ +do + +local BASE_URL = 'https://www.googleapis.com/youtube/v3' + +function get_yt_data (yt_code) + local apikey = cred_data.google_apikey + local url = BASE_URL..'/videos?part=snippet,statistics&key='..apikey..'&id='..yt_code..'&fields=items(snippet(channelTitle,localized(title,description)),statistics(viewCount,likeCount,dislikeCount,commentCount))' + local res,code = https.request(url) + if code ~= 200 then return "HTTP-FEHLER" end + local data = json:decode(res).items[1] + return data +end + +function send_youtube_data(data, receiver) + local title = data.snippet.localized.title + -- local description = data.items[1].snippet.localized.description + local uploader = data.snippet.channelTitle + local viewCount = data.statistics.viewCount + local likeCount = data.statistics.likeCount + local dislikeCount = data.statistics.dislikeCount + local commentCount = data.statistics.commentCount + + local text = title..'\n(Hochgeladen von: '..uploader..', '..viewCount..' mal angesehen, '..likeCount..' Likes und '..dislikeCount..' Dislikes, '..commentCount..' Kommentare)\n' + send_msg(receiver, text, ok_cb, false) +end + +function run(msg, matches) + local yt_code = matches[1] + local data = get_yt_data(yt_code) + local receiver = get_receiver(msg) + send_youtube_data(data, receiver) +end + +return { + description = "Sendet YouTube-Info.", + usage = "", + patterns = { + "youtu.be/([A-Za-z0-9-_-]+)", + "youtube.com/watch%?v=([A-Za-z0-9-_-]+)", + }, + run = run +} + +end