All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
4 Licensed under GNU General Public License v2
5 * (c) 2013, Luke Bonham
9 local newtimer = require("lain.helpers").newtimer
10 local async = require("lain.asyncshell")
12 local naughty = require("naughty")
13 local wibox = require("wibox")
15 local debug = { getinfo = debug.getinfo }
16 local io = { lines = io.lines,
18 local os = { date = os.date,
20 local string = { find = string.find,
24 local tonumber = tonumber
26 local setmetatable = setmetatable
28 -- YAhoo! Weather Notification
32 icon = wibox.widget.imagebox(),
33 widget = wibox.widget.textbox('')
36 local project_path = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
37 local localizations_path = project_path .. 'localizations/'
38 local icon_path = project_path .. 'icons/'
39 local api_url = 'http://weather.yahooapis.com/forecastrss'
40 local units_set = '?u=c&w=' -- Default is Celsius
41 local language = string.match(os.getenv("LANG"), "(%S*$*)[.]") or "en_US" -- if LANG is not set
42 local weather_data = nil
43 local notification = nil
46 local settings = function() end
48 yawn_notification_preset = {}
50 local function fetch_weather()
51 local url = api_url .. units_set .. city_id
52 local cmd = "curl --connect-timeout 1 -fsm 3 '" .. url .. "'"
54 async.request(cmd, function(f)
55 local text = f:read("*a")
58 -- In case of no connection or invalid city ID
59 -- widgets won't display
60 if text == "" or text:match("City not found")
62 yawn.icon:set_image(icon_path .. "na.png")
64 weather_data = "Service not available at the moment."
65 yawn.widget:set_text(" N/A ")
67 weather_data = "City not found!\n" ..
68 "Are you sure " .. city_id ..
69 " is your Yahoo city ID?"
70 yawn.widget:set_text(" ? ")
75 -- Processing raw data
76 weather_data = text:gsub("<.->", "")
77 weather_data = weather_data:match("Current Conditions:.-Full") or ""
79 -- may still happens in case of bad connectivity
80 if weather_data == "" then
81 yawn.icon:set_image(icon_path .. "na.png")
82 yawn.widget:set_text(" ? ")
86 weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ")
87 weather_data = weather_data:gsub("Forecast:.-\n", "")
88 weather_data = weather_data:gsub("\nFull", "")
89 weather_data = weather_data:gsub("[\n]$", "")
90 weather_data = weather_data:gsub(" [-] " , ": ")
91 weather_data = weather_data:gsub("[.]", ",")
92 weather_data = weather_data:gsub("High: ", "")
93 weather_data = weather_data:gsub(" Low: ", " - ")
95 -- Getting info for text widget
96 local now = weather_data:sub(weather_data:find("Now:")+5,
97 weather_data:find("\n")-1)
98 forecast = now:sub(1, now:find(",")-1)
99 units = now:sub(now:find(",")+2, -2)
101 -- Day/Night icon change
102 local hour = tonumber(os.date("%H"))
105 if forecast == "Clear" or
106 forecast == "Fair" or
107 forecast == "Partly Cloudy" or
108 forecast == "Mostly Cloudy"
110 if hour >= 6 and hour <= 18
118 sky = sky .. forecast:gsub(" ", ""):gsub("/", "") .. ".png"
120 -- In case there's no defined icon for current forecast
121 if io.open(sky) == nil then
122 sky = icon_path .. "na.png"
126 local f = io.open(localizations_path .. language, "r")
127 if language:find("en_") == nil and f ~= nil
130 for line in io.lines(localizations_path .. language)
132 word = string.sub(line, 1, line:find("|")-1)
133 translation = string.sub(line, line:find("|")+1)
134 weather_data = string.gsub(weather_data, word, translation)
138 -- Finally setting infos
139 yawn.icon:set_image(sky)
142 _data = weather_data:match(": %S.-,") or weather_data
143 forecast = _data:gsub(": ", ""):gsub(",", "")
144 units = units:gsub(" ", "")
151 if notification ~= nil then
152 naughty.destroy(notification)
157 function yawn.show(t_out)
158 if yawn.widget._layout.text:match("?")
160 fetch_weather(settings)
165 notification = naughty.notify({
166 preset = yawn_notification_preset,
170 screen = client.focus and client.focus.screen or 1
174 function yawn.register(id, args)
175 local args = args or {}
176 local timeout = args.timeout or 600
177 settings = args.settings or function() end
179 if args.u == "f" then units_set = '?u=f&w=' end
183 newtimer("yawn", timeout, fetch_weather)
185 yawn.icon:connect_signal("mouse::enter", function()
188 yawn.icon:connect_signal("mouse::leave", function()
195 function yawn.attach(widget, id, args)
196 yawn.register(id, args)
198 widget:connect_signal("mouse::enter", function()
202 widget:connect_signal("mouse::leave", function()
207 return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end })