]> 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:

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