From 575ec300b8dda24d9bdf82a6a4853e0e48dc4824 Mon Sep 17 00:00:00 2001 From: Andreas Bielawski Date: Tue, 9 Aug 2016 02:13:13 +0200 Subject: [PATCH] =?UTF-8?q?-=20Weather=20unterst=C3=BCtzt=20jetzt=20Inline?= =?UTF-8?q?-Query!=20ACHTUNG:=20Falls=20noch=20Daten=20im=20Cache=20h?= =?UTF-8?q?=C3=A4ngen=20(unter=20telegram:cache:weather=20in=20Redis,=20ab?= =?UTF-8?q?er=20NUR=20die=20Koordinaten,=20nicht=20die=20St=C3=A4dtenamen!?= =?UTF-8?q?),=20diese=20bitte=20L=C3=96SCHEN,=20da=20jetzt=20Hashes=20benu?= =?UTF-8?q?tzt=20werden,=20um=20mehr=20Daten=20zu=20cachen=20(f=C3=BCr=20d?= =?UTF-8?q?en=20Inline-Mode),=20anstatt=20simple=20Keys=20-=20Fixe=20Cachi?= =?UTF-8?q?ng=20f=C3=BCr=20Hashes=20(am=20besten=20ohne=20TTL=20verwenden,?= =?UTF-8?q?=20TODO:=20fixen)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- otouto/plugins/weather.lua | 132 +++++++++++++++++++++++++++++-------- otouto/utilities.lua | 6 +- 2 files changed, 106 insertions(+), 32 deletions(-) diff --git a/otouto/plugins/weather.lua b/otouto/plugins/weather.lua index 828a08e..64dde87 100644 --- a/otouto/plugins/weather.lua +++ b/otouto/plugins/weather.lua @@ -17,6 +17,10 @@ function weather:init(config) "^/w$", "^/w (.*)$" } + weather.inline_triggers = { + "^w (.+)$", + "^w$" + } weather.doc = [[* ]]..config.cmd_pat..[[wetter*: Wetter für deinen Wohnort _(/location set [Ort])_ *]]..config.cmd_pat..[[wetter* __: Wetter für diesen Ort @@ -42,10 +46,43 @@ function get_city_name(lat, lng) return city end -function weather:get_weather(lat, lng) +function weather:get_city_coordinates(city, config) + local lat = redis:hget('telegram:cache:weather:'..string.lower(city), 'lat') + local lng = redis:hget('telegram:cache:weather:'..string.lower(city), 'lng') + if not lat and not lng then + print('Koordinaten nicht eingespeichert, frage Google...') + coords = utilities.get_coords(city, config) + lat = coords.lat + lng = coords.lon + end + + if not lat and not lng then + return nil + end + + redis:hset('telegram:cache:weather:'..string.lower(city), 'lat', lat) + redis:hset('telegram:cache:weather:'..string.lower(city), 'lng', lng) + return lat, lng +end + +function weather:get_weather(lat, lng, is_inline) print('Finde Wetter in '..lat..', '..lng) - local text = redis:get('telegram:cache:weather:'..lat..','..lng) - if text then print('...aus dem Cache') return text end + local hash = 'telegram:cache:weather:'..lat..','..lng + + local text = redis:hget(hash, 'text') + if text then + print('...aus dem Cache') + if is_inline then + local ttl = redis:ttl(hash) + local city = redis:hget(hash, 'city') + local temperature = redis:hget(hash, 'temperature') + local weather_icon = redis:hget(hash, 'weather_icon') + local condition = redis:hget(hash, 'condition') + return city, condition..' bei '..temperature..' °C', weather_icon, text, ttl + else + return text + end + end local url = BASE_URL..'/'..apikey..'/'..lat..','..lng..'?lang=de&units=si&exclude=minutely,hourly,daily,alerts,flags' @@ -58,7 +95,7 @@ function weather:get_weather(lat, lng) local ok, response_code, response_headers, response_status_line = https.request(request_constructor) if not ok then return nil end local data = json.decode(table.concat(response_body)) - local ttl = string.sub(response_headers["cache-control"], 9) + local ttl = tonumber(string.sub(response_headers["cache-control"], 9)) local weather = data.currently @@ -66,26 +103,28 @@ function weather:get_weather(lat, lng) local temperature = string.gsub(round(weather.temperature, 1), "%.", ",") local feelslike = string.gsub(round(weather.apparentTemperature, 1), "%.", ",") local temp = '*Wetter in '..city..':*\n'..temperature..' °C' - local conditions = ' | '..weather.summary - if weather.icon == 'clear-day' then + local weather_summary = weather.summary + local conditions = ' | '..weather_summary + local weather_icon = weather.icon + if weather_icon == 'clear-day' then conditions = conditions..' ☀️' - elseif weather.icon == 'clear-night' then + elseif weather_icon == 'clear-night' then conditions = conditions..' 🌙' - elseif weather.icon == 'rain' then + elseif weather_icon == 'rain' then conditions = conditions..' ☔️' - elseif weather.icon == 'snow' then + elseif weather_icon == 'snow' then conditions = conditions..' ❄️' - elseif weather.icon == 'sleet' then + elseif weather_icon == 'sleet' then conditions = conditions..' 🌨' - elseif weather.icon == 'wind' then + elseif weather_icon == 'wind' then conditions = conditions..' 💨' elseif weather.icon == 'fog' then conditions = conditions..' 🌫' - elseif weather.icon == 'cloudy' then + elseif weather_icon == 'cloudy' then conditions = conditions..' ☁️☁️' - elseif weather.icon == 'partly-cloudy-day' then + elseif weather_icon == 'partly-cloudy-day' then conditions = conditions..' 🌤' - elseif weather.icon == 'partly-cloudy-night' then + elseif weather_icon == 'partly-cloudy-night' then conditions = conditions..' 🌙☁️' else conditions = conditions..'' @@ -98,8 +137,54 @@ function weather:get_weather(lat, lng) text = text..'\n(gefühlt: '..feelslike..' °C)' end - cache_data('weather', lat..','..lng, text, tonumber(ttl), 'key') - return text + print('Caching data...') + redis:hset(hash, 'city', city) + redis:hset(hash, 'temperature', temperature) + redis:hset(hash, 'weather_icon', weather_icon) + redis:hset(hash, 'condition', weather_summary) + redis:hset(hash, 'text', text) + redis:expire(hash, ttl) + + if is_inline then + return city, weather_summary..' bei '..temperature..' °C', weather_icon, text, ttl + else + return text + end +end + +function weather:inline_callback(inline_query, config, matches) + local user_id = inline_query.from.id + if matches[1] ~= 'w' then + city = matches[1] + else + local set_location = get_location(user_id) + if not set_location then + city = 'Berlin, Deutschland' + else + city = set_location + end + end + local lat, lng = weather:get_city_coordinates(city, config) + if not lat and not lng then utilities.answer_inline_query(self, inline_query) return end + + local title, description, icon, text, ttl = weather:get_weather(lat, lng, true) + if not title and not description and not icon and not text and not ttl then utilities.answer_inline_query(self, inline_query) return end + + local text = text:gsub('\n', '\\n') + local thumb_url = 'https://anditest.perseus.uberspace.de/inlineQuerys/weather/' + if icon == 'clear-day' or icon == 'partly-cloudy-day' then + thumb_url = thumb_url..'day.jpg' + elseif icon == 'clear-night' or icon == 'partly-cloudy-night' then + thumb_url = thumb_url..'night.jpg' + elseif icon == 'rain' then + thumb_url = thumb_url..'rain.jpg' + elseif icon == 'snow' then + thumb_url = thumb_url..'snow.jpg' + else + thumb_url = thumb_url..'cloudy.jpg' + end + local results = '[{"type":"article","id":"19122006","title":"'..title..'","description":"'..description..'","thumb_url":"'..thumb_url..'","thumb_width":80,"thumb_height":80,"input_message_content":{"message_text":"'..text..'", "parse_mode":"Markdown"}}]' + utilities.answer_inline_query(self, inline_query, results, ttl) end function weather:action(msg, config, matches) @@ -116,22 +201,11 @@ function weather:action(msg, config, matches) end end - local lat = redis:hget('telegram:cache:weather:'..string.lower(city), 'lat') - local lng = redis:hget('telegram:cache:weather:'..string.lower(city), 'lng') + local lat, lng = weather:get_city_coordinates(city, config) if not lat and not lng then - print('Koordinaten nicht eingespeichert, frage Google...') - coords = utilities.get_coords(city, config) - lat = coords.lat - lng = coords.lon - end - - if not lat and not lng then - utilities.send_reply(self, msg, '*Diesen Ort gibt es nicht!*', true) + utilities.send_reply(self, msg, '*Diesen Ort gibt es nicht!*', true) return end - - redis:hset('telegram:cache:weather:'..string.lower(city), 'lat', lat) - redis:hset('telegram:cache:weather:'..string.lower(city), 'lng', lng) local text = weather:get_weather(lat, lng) if not text then diff --git a/otouto/utilities.lua b/otouto/utilities.lua index ed8f59f..f805eb0 100644 --- a/otouto/utilities.lua +++ b/otouto/utilities.lua @@ -794,8 +794,8 @@ function get_location(user_id) end end -function cache_data(plugin, query, data, timeout, typ) - -- How to: cache_data(pluginname, query_name, data_to_cache, expire_in_seconds) +function cache_data(plugin, query, data, timeout, typ, hash_field) + -- How to: cache_data(pluginname, query_name, data_to_cache, expire_in_seconds, type, hash_field (if hash)) local hash = 'telegram:cache:'..plugin..':'..query if timeout then print('Caching "'..query..'" from plugin '..plugin..' (expires in '..timeout..' seconds)') @@ -813,7 +813,7 @@ function cache_data(plugin, query, data, timeout, typ) redis:sadd(hash, str) end else - redis:hmset(hash, data) + redis:hset(hash, hash_field, data) end if timeout then redis:expire(hash, timeout)