]> git.madduck.net Git - etc/awesome.git/blob - widgets/yawn/init.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

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.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

issue #9 fix
[etc/awesome.git] / widgets / yawn / init.lua
1
2 --[[
3                                                   
4      Licensed under GNU General Public License v2 
5       * (c) 2013, Luke Bonham                     
6                                                   
7 --]]
8
9 local newtimer     = require("lain.helpers").newtimer
10
11 local naughty      = require("naughty")
12 local wibox        = require("wibox")
13
14 local debug        = { getinfo = debug.getinfo }
15 local io           = io
16 local os           = { date    = os.date,
17                        getenv  = os.getenv }
18 local string       = { find    = string.find,
19                        match   = string.match,
20                        gsub    = string.gsub,
21                        sub     = string.sub }
22 local tonumber     = tonumber
23
24 local setmetatable = setmetatable
25
26 -- YAhoo! Weather Notification
27 -- lain.widgets.yawn
28 local yawn =
29 {
30     icon   = wibox.widget.imagebox(),
31     widget = wibox.widget.textbox('')
32 }
33
34 local project_path        = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
35 local localizations_path  = project_path .. 'localizations/'
36 local icon_path           = project_path .. 'icons/'
37 local api_url             = 'http://weather.yahooapis.com/forecastrss'
38 local units_set           = '?u=c&w=' -- Default is Celsius
39 local language            = string.match(os.getenv("LANG"), "(%S*$*)[.]")
40 local weather_data        = nil
41 local notification        = nil
42 local city_id             = nil
43 local sky                 = nil
44 local settings            = function() end
45
46 yawn_notification_preset = {}
47
48 local function fetch_weather()
49     local url = api_url .. units_set .. city_id
50     local f = io.popen("curl --connect-timeout 1 -fsm 1 '"
51                        .. url .. "'" )
52     local text = f:read("*all")
53     f:close()
54
55     -- In case of no connection or invalid city ID
56     -- widgets won't display
57     if text == "" or text:match("City not found")
58     then
59         yawn.icon:set_image(icon_path .. "na.png")
60         if text == "" then
61             weather_data = "Service not available at the moment."
62             yawn.widget:set_text("N/A")
63         else
64             weather_data = "City not found!\n" ..
65                            "Are you sure " .. city_id ..
66                            " is your Yahoo city ID?"
67             yawn.widget:set_text("?")
68         end
69         return
70     end
71
72     -- Processing raw data
73     weather_data = text:gsub("<.->", "")
74     weather_data = weather_data:match("Current Conditions:.-Full") or ""
75
76     -- may still happens in case of bad connectivity
77     if weather_data == "" then
78         yawn.icon:set_image(icon_path .. "na.png")
79         yawn.widget:set_text("?")
80         return
81     end
82
83     weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ")
84     weather_data = weather_data:gsub("Forecast:.-\n", "")
85     weather_data = weather_data:gsub("\nFull", "")
86     weather_data = weather_data:gsub("[\n]$", "")
87     weather_data = weather_data:gsub(" [-] " , ": ")
88     weather_data = weather_data:gsub("[.]", ",")
89     weather_data = weather_data:gsub("High: ", "")
90     weather_data = weather_data:gsub(" Low: ", " - ")
91
92     -- Getting info for text widget
93     local now      = weather_data:sub(weather_data:find("Now:")+5,
94                      weather_data:find("\n")-1)
95     forecast       = now:sub(1, now:find(",")-1)
96     units          = now:sub(now:find(",")+2, -2)
97
98     -- Day/Night icon change
99     local hour = tonumber(os.date("%H"))
100     sky = icon_path
101
102     if forecast == "Clear"         or
103        forecast == "Fair"          or
104        forecast == "Partly Cloudy" or
105        forecast == "Mostly Cloudy"
106        then
107            if hour >= 6 and hour <= 18
108            then
109                sky = sky .. "Day"
110            else
111                sky = sky .. "Night"
112            end
113     end
114
115     sky = sky  .. forecast:gsub(" ", ""):gsub("/", "") .. ".png"
116
117     -- In case there's no defined icon for current forecast
118     f = io.popen(sky)
119     if f == nil then
120         sky = icon_path .. "na.png"
121     else
122         io.close(f)
123     end
124
125     -- Localization
126     local f = io.open(localizations_path .. language, "r")
127     if language:find("en_") == nil and f ~= nil
128     then
129         f:close()
130         for line in io.lines(localizations_path .. language)
131         do
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)
135         end
136     end
137
138     -- Finally setting infos
139     yawn.icon:set_image(sky)
140     widget = yawn.widget
141
142     forecast = weather_data:match(": %S.-,"):gsub(": ", ""):gsub(",", "")
143     units = units:gsub(" ", "")
144
145     settings()
146 end
147
148 function yawn.hide()
149     if notification ~= nil then
150         naughty.destroy(notification)
151         notification = nil
152     end
153 end
154
155 function yawn.show(t_out)
156     if yawn.widget._layout.text == "?"
157     then
158         fetch_weather(settings)
159     end
160
161     yawn.hide()
162
163     notification = naughty.notify({
164         preset = yawn_notification_preset,
165         text = weather_data,
166         icon = sky,
167         timeout = t_out
168     })
169 end
170
171 function yawn.register(id, args)
172     local args     = args or {}
173     local timeout  = args.timeout or 600
174     settings       = args.settings or function() end
175
176     if args.u == "f" then units_set = '?u=f&w=' end
177
178     city_id = id
179
180     newtimer("yawn", timeout, fetch_weather)
181
182     yawn.icon:connect_signal("mouse::enter", function()
183         yawn.show(0)
184     end)
185     yawn.icon:connect_signal("mouse::leave", function()
186         yawn.hide()
187     end)
188
189     return yawn
190 end
191
192 function yawn.attach(widget, id, args)
193     yawn.register(id, args)
194
195     widget:connect_signal("mouse::enter", function()
196         yawn.show(0)
197     end)
198
199     widget:connect_signal("mouse::leave", function()
200         yawn.hide()
201     end)
202 end
203
204 return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end })