From e19c3adac44548401be41fe622be1c1eed52bb23 Mon Sep 17 00:00:00 2001 From: Marcel van der Boom Date: Sat, 22 Nov 2014 10:29:05 +0100 Subject: [PATCH] Inital version of !time command Syntax: !time [area] Uses the google geocoding api to turn an area specification into a lat/long coordinate pair, which is then used to get a timezone record to determine the local time. Usecase: when working in international groups it's convenient to know if your co-worker is likely to be awake or asleep. --- bot/bot.lua | 1 + plugins/time.lua | 103 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 plugins/time.lua diff --git a/bot/bot.lua b/bot/bot.lua index ab28153..1f92d77 100644 --- a/bot/bot.lua +++ b/bot/bot.lua @@ -1,4 +1,5 @@ http = require("socket.http") + https = require("ssl.https") URL = require("socket.url") json = (loadfile "./bot/JSON.lua")() -- lrexlib = require("rex_pcre") diff --git a/plugins/time.lua b/plugins/time.lua new file mode 100644 index 0000000..0699484 --- /dev/null +++ b/plugins/time.lua @@ -0,0 +1,103 @@ +-- 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, you can fill it in here +-- TODO: use bot config file +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 + return lat,lng,acc + 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 + end + return localTime +end + +function getformattedLocalTime(area) + if area == nil then + return "The time in nowhere is never" + end + + lat,lng,acc = get_latlong(area) + if lat == nil and lng==nil then + return "It seems that in '"..area.."' they do not have a concept of time." + end + local localTime = get_time(lat,lng) + + return "The local time in '"..area.. + "'\n(Loc: "..lat..", "..lng.." with '"..acc.."' accuracy is:\n" .. + os.date(dateFormat,localTime) +end + +function run(msg, matches) + return getformattedLocalTime(matches[1]) +end + +return { + description = "Displays the local time in an area", + usage = "!time [area]", + patterns = {"^!time (.*)$"}, + run = run +} + +