X-Git-Url: https://git.madduck.net/etc/awesome.git/blobdiff_plain/8c5b64675dfbf196871ee31cf22920627019bd84..010e60a8cd421ef6e0f15b5fda882e9e15939b71:/widgets/weather.lua

diff --git a/widgets/weather.lua b/widgets/weather.lua
index d8dfd3f..de3163c 100644
--- a/widgets/weather.lua
+++ b/widgets/weather.lua
@@ -7,13 +7,17 @@
 --]]
 
 local newtimer     = require("lain.helpers").newtimer
+local read_pipe    = require("lain.helpers").read_pipe
+
 local async        = require("lain.asyncshell")
 local json         = require("lain.util").dkjson
 local lain_icons   = require("lain.helpers").icons_dir
+
 local naughty      = require("naughty")
 local wibox        = require("wibox")
 
 local math         = { floor  = math.floor }
+local mouse        = mouse
 local string       = { format = string.format,
                        gsub   = string.gsub }
 
@@ -30,13 +34,18 @@ local function worker(args)
     local timeout_forecast      = args.timeout or 86400 -- 24 hrs
     local current_call          = "curl -s 'http://api.openweathermap.org/data/2.5/weather?id=%s&units=%s&lang=%s'"
     local forecast_call         = "curl -s 'http://api.openweathermap.org/data/2.5/forecast/daily?id=%s&units=%s&lang=%s&cnt=%s'"
-    local city_id               = args.city_id
+    local city_id               = args.city_id or 0 -- placeholder
     local units                 = args.units or "metric"
     local lang                  = args.lang or "en"
     local cnt                   = args.cnt or 7
     local date_cmd              = args.date_cmd or "date -u -d @%d +'%%a %%d'"
     local icons_path            = args.icons_path or lain_icons .. "openweathermap/"
-    local w_notification_preset = args.w_notification_preset or {}
+    local notification_preset   = args.notification_preset or {}
+    local notification_text_fun = args.notification_text_fun or
+                                  function (day, desc, tmin, tmax)
+                                      return string.format("<b>%s</b>: %s, %d - %d  ", day, desc, tmin, tmax)
+                                  end
+    local followmouse           = args.followmouse or false
     local settings              = args.settings or function() end
 
     weather.widget = wibox.widget.textbox('')
@@ -44,11 +53,16 @@ local function worker(args)
 
     function weather.show(t_out)
         weather.hide()
+
+        if followmouse then
+            notification_preset.screen = mouse.screen
+        end
+
         weather.notification = naughty.notify({
             text    = weather.notification_text,
             icon    = weather.icon_path,
             timeout = t_out,
-            preset  = w_notification_preset
+            preset  = notification_preset
         })
     end
 
@@ -71,28 +85,28 @@ local function worker(args)
     function weather.forecast_update()
         local cmd = string.format(forecast_call, city_id, units, lang, cnt)
         async.request(cmd, function(f)
-            j = f:read("*a")
-            f:close()
-            weather_now, pos, err = json.decode(j, 1, nil)
+            local pos, err
+            weather_now, pos, err = json.decode(f, 1, nil)
 
-            if tonumber(weather_now["cod"]) == 200 then
+            if not err and weather_now ~= nil and tonumber(weather_now["cod"]) == 200 then
                 weather.notification_text = ''
                 for i = 1, weather_now["cnt"] do
-                    local f = assert(io.popen(string.format(date_cmd, weather_now["list"][i]["dt"])))
-                    day = string.gsub(f:read("a"), "\n", "")
-                    f:close()
+                    local day = string.gsub(read_pipe(string.format(date_cmd, weather_now["list"][i]["dt"])), "\n", "")
 
-                    tmin = math.floor(weather_now["list"][i]["temp"]["min"])
-                    tmax = math.floor(weather_now["list"][i]["temp"]["max"])
-                    desc = weather_now["list"][i]["weather"][1]["description"]
+                    local tmin = math.floor(weather_now["list"][i]["temp"]["min"])
+                    local tmax = math.floor(weather_now["list"][i]["temp"]["max"])
+                    local desc = weather_now["list"][i]["weather"][1]["description"]
 
                     weather.notification_text = weather.notification_text ..
-                                                string.format("<b>%s</b>: %s, %d - %d  ", day, desc, tmin, tmax)
+                                                notification_text_fun(day, desc, tmin, tmax)
 
                     if i < weather_now["cnt"] then
                         weather.notification_text = weather.notification_text .. "\n"
                     end
                 end
+            else
+                weather.icon_path = icons_path .. "na.png"
+                weather.notification_text = "API/connection error or bad/not set city ID"
             end
         end)
     end
@@ -100,24 +114,25 @@ local function worker(args)
     function weather.update()
         local cmd = string.format(current_call, city_id, units, lang)
         async.request(cmd, function(f)
-            j = f:read("*a")
-            f:close()
-            weather_now, pos, err = json.decode(j, 1, nil)
+            local pos, err
+            weather_now, pos, err = json.decode(f, 1, nil)
 
-            if err then
-                weather.widget.set_text("N/A")
-                weather.icon:set_image(icons_path .. "na.png")
-            elseif tonumber(weather_now["cod"]) == 200 then
+            if not err and weather_now ~= nil and tonumber(weather_now["cod"]) == 200 then
                 weather.icon_path = icons_path .. weather_now["weather"][1]["icon"] .. ".png"
                 weather.icon:set_image(weather.icon_path)
                 widget = weather.widget
                 settings()
+            else
+                weather.widget._layout.text = " N/A " -- tries to avoid textbox bugs
+                weather.icon:set_image(icons_path .. "na.png")
             end
         end)
     end
 
-    newtimer("weather", timeout, weather.update)
-    newtimer("weather_forecast", timeout, weather.forecast_update)
+    weather.attach(weather.widget)
+
+    newtimer("weather-" .. city_id, timeout, weather.update)
+    newtimer("weather_forecast-" .. city_id, timeout, weather.forecast_update)
 
     return setmetatable(weather, { __index = weather.widget })
 end