Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduce helpers.uri (curl replacement) & migrate widget/weather to it #549

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@

local spawn = require("awful.spawn")
local timer = require("gears.timer")
local gdebug = require("gears.debug")
local debug = require("debug")
local io = { lines = io.lines,
open = io.open }
local pairs = pairs
local rawget = rawget
local tsort = table.sort
local unpack = unpack or table.unpack -- lua 5.1 retro-compatibility
local lgi = require("lgi")

-- Lain helper functions for internal use
-- lain.helpers
Expand Down Expand Up @@ -132,6 +134,25 @@ end

-- }}}

-- {{{ Network functions

-- fetch a http uri using lgi.Soup
function helpers.uri(uri, callback, error_handler)
error_handler = error_handler or gdebug.print_error
local ss = lgi.Soup.Session()
local msg = lgi.Soup.Message.new('GET', uri)
ss:send_and_read_async(msg, lgi.GLib.PRIORITY_DEFAULT, nil, function(_, resp, _)
local buf, err = ss:send_and_read_finish(resp)
if err then
error_handler(err)
elseif buf then
callback(buf:get_data())
end
end)
end

-- }}}

-- {{{ A map utility

helpers.map_table = {}
Expand Down
58 changes: 30 additions & 28 deletions widget/weather.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ local type = type
local tonumber = tonumber

-- OpenWeatherMap
-- current weather and X-days forecast
-- current weather and 5d/3h forecast
-- lain.widget.weather

local function factory(args)
args = args or {}

local weather = { widget = args.widget or wibox.widget.textbox() }
-- weather.now will hold the 'current' and 'forecast' state
local weather = { widget = args.widget or wibox.widget.textbox(), now = {} }
local APPID = args.APPID -- mandatory api key
local timeout = args.timeout or 900 -- 15 min
local current_call = args.current_call or "curl -s 'https://api.openweathermap.org/data/2.5/weather?lat=%s&lon=%s&APPID=%s&units=%s&lang=%s'"
local forecast_call = args.forecast_call or "curl -s 'https://api.openweathermap.org/data/2.5/forecast?lat=%s&lon=%s&APPID=%s&cnt=%s&units=%s&lang=%s'"
local current_uri = args.current_uri or "https://api.openweathermap.org/data/2.5/weather?lat=%s&lon=%s&APPID=%s&units=%s&lang=%s"
local forecast_uri = args.forecast_uri or "https://api.openweathermap.org/data/2.5/forecast?lat=%s&lon=%s&APPID=%s&cnt=%s&units=%s&lang=%s"
local lat = args.lat or 0 -- placeholder
local lon = args.lon or 0 -- placeholder
local units = args.units or "metric"
Expand All @@ -37,15 +38,15 @@ local function factory(args)
local notification_preset = args.notification_preset or {}
local notification_text_fun = args.notification_text_fun or
function (wn)
local day = os.date("%a %d", wn["dt"])
local day = os.date("%a %d %H:%M", wn["dt"])
local temp = math.floor(wn["main"]["temp"])
local desc = wn["weather"][1]["description"]
return string.format("<b>%s</b>: %s, %d ", day, desc, temp)
return string.format("<b>%s</b>: %s, %d°", day, desc, temp)
end
local weather_na_markup = args.weather_na_markup or " N/A "
local followtag = args.followtag or false
local showpopup = args.showpopup or "on"
local settings = args.settings or function() end
local settings = args.settings or function(_, _) end

weather.widget:set_markup(weather_na_markup)
weather.icon_path = icons_path .. "na.png"
Expand Down Expand Up @@ -88,18 +89,17 @@ local function factory(args)
end

function weather.forecast_update()
local cmd = string.format(forecast_call, lat, lon, APPID, cnt, units, lang)
local uri = string.format(forecast_uri, lat, lon, APPID, cnt, units, lang)
helpers.uri(uri, function(f)
local forecast, _, err = json.decode(f, 1, nil)

helpers.async(cmd, function(f)
local err
weather_now, _, err = json.decode(f, 1, nil)

if not err and type(weather_now) == "table" and tonumber(weather_now["cod"]) == 200 then
if not err and type(weather.forecast) == "table" and tonumber(forecast["cod"]) == 200 then
weather.now.forecast = forecast
weather.notification_text = ""
for i = 1, weather_now["cnt"], math.floor(weather_now["cnt"] / cnt) do
for i = 1, forecast["cnt"], math.floor(forecast["cnt"] / cnt) do
weather.notification_text = weather.notification_text ..
notification_text_fun(weather_now["list"][i])
if i < weather_now["cnt"] then
notification_text_fun(forecast["list"][i])
if i < forecast["cnt"] then
weather.notification_text = weather.notification_text .. "\n"
end
end
Expand All @@ -108,17 +108,18 @@ local function factory(args)
end

function weather.update()
local cmd = string.format(current_call, lat, lon, APPID, units, lang)

helpers.async(cmd, function(f)
local err
weather_now, _, err = json.decode(f, 1, nil)

if not err and type(weather_now) == "table" and tonumber(weather_now["cod"]) == 200 then
local sunrise = tonumber(weather_now["sys"]["sunrise"])
local sunset = tonumber(weather_now["sys"]["sunset"])
local icon = weather_now["weather"][1]["icon"]
local uri = string.format(current_uri, lat, lon, APPID, units, lang)
helpers.uri(uri, function(f)
local current, _, err = json.decode(f, 1, nil)

if not err and type(current) == "table" and tonumber(current["cod"]) == 200 then
weather.now.current = current
local sunrise = tonumber(current["sys"]["sunrise"])
local sunset = tonumber(current["sys"]["sunset"])
local icon = current["weather"][1]["icon"]
local loc_now = os.time()
local city = current["name"]
local temp = current["main"]["temp"]

if sunrise <= loc_now and loc_now <= sunset then
icon = string.gsub(icon, "n", "d")
Expand All @@ -127,8 +128,8 @@ local function factory(args)
end

weather.icon_path = icons_path .. icon .. ".png"
widget = weather.widget
settings()
weather.widget:set_markup(string.format(" %s %d° ", city, temp))
settings(weather.widget, weather.now)
else
weather.icon_path = icons_path .. "na.png"
weather.widget:set_markup(weather_na_markup)
Expand All @@ -138,6 +139,7 @@ local function factory(args)
end)
end


if showpopup == "on" then weather.attach(weather.widget) end

weather.timer = helpers.newtimer("weather-" .. lat .. ":" .. lon, timeout, weather.update, false, true)
Expand Down