From edfd51215e364b0460c17027ff4f8f951f03405a Mon Sep 17 00:00:00 2001 From: MArpogaus <38564291+MArpogaus@users.noreply.github.com> Date: Mon, 28 Sep 2020 10:41:40 +0200 Subject: [PATCH] [contrib.openweather] Support API ID and additional return values --- contrib/openweather_all.lua | 117 ++++++++++++++++++++---------------- docs/source/contrib.rst | 13 ++-- 2 files changed, 73 insertions(+), 57 deletions(-) diff --git a/contrib/openweather_all.lua b/contrib/openweather_all.lua index 23abe5e..20c5d87 100644 --- a/contrib/openweather_all.lua +++ b/contrib/openweather_all.lua @@ -1,6 +1,7 @@ -- contrib/openweather_all.lua -- Copyright (C) 2013 NormalRa -- Copyright (C) 2017 Jörg Thalheim +-- Copyright (C) 2020 Marcel Arpogaus -- -- This file is part of Vicious. -- @@ -16,69 +17,66 @@ -- -- You should have received a copy of the GNU General Public License -- along with Vicious. If not, see . - -- {{{ Grab environment local tonumber = tonumber -local io = { popen = io.popen } -local setmetatable = setmetatable -local string = { match = string.match } -local math = { - ceil = math.ceil, - floor = math.floor -} +local string = {match = string.match} +local math = {ceil = math.ceil, floor = math.floor} +local helpers = require "vicious.helpers" +local spawn = require "vicious.spawn" -- }}} - -- Openweather: provides weather information for a requested station -- vicious.widgets.openweather local openweather_all = {} - -- Initialize function tables -local _wdirs = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "N" } +local _wdirs = {"N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"} local _wdata = { - ["{city}"] = "N/A", - ["{wind deg}"] = "N/A", - ["{wind aim}"] = "N/A", - ["{wind mps}"] = "N/A", - ["{wind kmh}"] = "N/A", - ["{sky}"] = "N/A", - ["{weather}"] = "N/A", - ["{temp c}"] = "N/A", - ["{humid}"] = "N/A", - ["{press}"] = "N/A" + ["{city}"] = "N/A", + ["{wind deg}"] = "N/A", + ["{wind aim}"] = "N/A", + ["{wind mps}"] = "N/A", + ["{wind kmh}"] = "N/A", + ["{sky}"] = "N/A", + ["{weather}"] = "N/A", + ["{temp c}"] = "N/A", + ["{temp min c}"] = "N/A", + ["{temp max c}"] = "N/A", + ["{sunrise}"] = -1, + ["{sunset}"] = -1, + ["{humid}"] = "N/A", + ["{press}"] = "N/A" } -- {{{ Openweather widget type -local function worker(format, warg) - if not warg then return end - - -- Get weather forceast using the city ID code, from: - -- * OpenWeatherMap.org - local openweather = "http://api.openweathermap.org/data/2.5/weather?id="..warg.."&mode=json&units=metric" - local f = io.popen("curl --connect-timeout 1 -fsm 3 '"..openweather.."'") - local ws = f:read("*all") - f:close() - +local function parse(stdout, stderr, exitreason, exitcode) -- Check if there was a timeout or a problem with the station - if ws == nil then return _wdata end + if stdout == nil or exitcode ~= 0 then return _wdata end - _wdata["{city}"] = -- City name - string.match(ws, '"name":"([%a%s%-]+)"') or _wdata["{city}"] + _wdata["{city}"] = -- City name + string.match(stdout, '"name":"([%a%s%-]+)"') or _wdata["{city}"] _wdata["{wind deg}"] = -- Wind degrees - string.match(ws, '"deg":([%d]+)') or _wdata["{wind deg}"] - _wdata["{wind mps}"] = -- Wind speed in meters per second - string.match(ws, '"speed":([%d%.]+)') or _wdata["{wind mps}"] - _wdata["{sky}"] = -- Sky conditions - string.match(ws, '"main":"([%a]+)"') or _wdata["{sky}"] - _wdata["{weather}"] = -- Weather description - string.match(ws, '"description":"([%a%s]+)"') or _wdata["{weather}"] - _wdata["{temp c}"] = -- Temperature in celsius - string.match(ws, '"temp":([%-]?[%d%.]+)') or _wdata["{temp c}"] - _wdata["{humid}"] = -- Relative humidity in percent - string.match(ws, '"humidity":([%d]+)') or _wdata["{humid}"] - _wdata["{press}"] = -- Pressure in hPa - string.match(ws, '"pressure":([%d%.]+)') or _wdata["{press}"] + string.match(stdout, '"deg":([%d]+)') or _wdata["{wind deg}"] + _wdata["{wind mps}"] = -- Wind speed in meters per second + string.match(stdout, '"speed":([%d%.]+)') or _wdata["{wind mps}"] + _wdata["{sky}"] = -- Sky conditions + string.match(stdout, '"main":"([%a]+)"') or _wdata["{sky}"] + _wdata["{weather}"] = -- Weather description + string.match(stdout, '"description":"([%a%s]+)"') or _wdata["{weather}"] + _wdata["{temp c}"] = -- Temperature in celsius + string.match(stdout, '"temp":([%-]?[%d%.]+)') or _wdata["{temp c}"] + _wdata["{temp min c}"] = -- Minimal Temperature in celsius + string.match(stdout, '"temp_min":([%-]?[%d%.]+)') or _wdata["{temp min c}"] + _wdata["{temp max c}"] = -- Maximal Temperature in celsius + string.match(stdout, '"temp_max":([%-]?[%d%.]+)') or _wdata["{temp max c}"] + _wdata["{humid}"] = -- Relative humidity in percent + string.match(stdout, '"humidity":([%d]+)') or _wdata["{humid}"] + _wdata["{sunrise}"] = -- Sunrise + tonumber(string.match(stdout, '"sunrise":([%d]+)')) or _wdata["{sunrise}"] + _wdata["{sunset}"] = -- Sunset + tonumber(string.match(stdout, '"sunset":([%d]+)')) or _wdata["{sunset}"] + _wdata["{press}"] = -- Pressure in hPa + string.match(stdout, '"pressure":([%d%.]+)') or _wdata["{press}"] -- Wind speed in km/h if _wdata["{wind mps}"] ~= "N/A" then @@ -92,17 +90,32 @@ local function worker(format, warg) _wdata["{wind deg}"] = tonumber(_wdata["{wind deg}"]) -- Lua tables start at [1] - if (_wdata["{wind deg}"] / 45)%1 == 0 then + if (_wdata["{wind deg}"] / 45) % 1 == 0 then _wdata["{wind aim}"] = _wdirs[_wdata["{wind deg}"] / 45 + 1] else - _wdata["{wind aim}"] = - _wdirs[math.ceil(_wdata["{wind deg}"] / 45) + 1].. - _wdirs[math.floor(_wdata["{wind deg}"] / 45) + 1] + _wdata["{wind aim}"] = _wdirs[math.ceil(_wdata["{wind deg}"] / 45) + + 1] .. + _wdirs[math.floor( + _wdata["{wind deg}"] / 45) + 1] end end return _wdata end + +function openweather_all.async(format, warg, callback) + if not warg then return callback {} end + if type(warg) ~= "table" then return callback {} end + + -- Get weather forceast using the city ID code, from: + -- * OpenWeatherMap.org + local openweather = "http://api.openweathermap.org/data/2.5/weather?id=" .. + warg.city_id .. "&appid=" .. warg.app_id .. + "&mode=json&units=metric" + + spawn.easy_async("curl --connect-timeout 1 -fsm 3 '" .. openweather .. "'", + function(...) callback(parse(...)) end) +end -- }}} -return setmetatable(openweather_all, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(openweather_all) diff --git a/docs/source/contrib.rst b/docs/source/contrib.rst index 0826fdf..a1cfee0 100644 --- a/docs/source/contrib.rst +++ b/docs/source/contrib.rst @@ -133,12 +133,15 @@ vicious.contrib.net vicious.contrib.openweather ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Provides weather information for a requested city +Provides weather information for a requested city from OpenWeatherMap (OWM) -* Argument: OpenWeatherMap city ID, e.g. ``"1275339"`` -* Returns a table with string keys: ``${city}``, ``${wind deg}``, - ``${wind aim}``, ``${wind kmh}``, ``${wind mps}``, ``${sky}``, - ``${weather}``, ``${temp c}``, ``${humid}`` and ``${press}`` +* Argument: a table containing the fields ``city_id`` with the OWM city ID, e.g. + ``"2643743"`` and ``app_id`` with the the OWM app ID, e.g + ``"4c57f0c88d9844630327623633ce269cf826ab99"`` +* Returns a table with string keys: ``${city}``, ``${humid}``, ``${press}``, + ``${sky}``, ``${sunrise}``, ``${sunset}``, ``${temp c}``, ``${temp max c}``, + ``${temp min c}``, ``${weather}``, ``${wind aim}``, ``${wind deg}``, + ``${wind kmh}`` and ``${wind mps}``, vicious.contrib.nvinf ^^^^^^^^^^^^^^^^^^^^^